Skip to content

Commit

Permalink
Merge pull request #461 from yast/s390_finish_client
Browse files Browse the repository at this point in the history
Copy udev rules before calling bootloader finish client
  • Loading branch information
teclator authored Mar 14, 2023
2 parents 4ca7abc + 8f54f12 commit fc1a850
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 1 deletion.
47 changes: 47 additions & 0 deletions service/lib/dinstaller/storage/finisher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
require "dinstaller/helpers"
require "abstract_method"

Yast.import "Arch"

module DInstaller
module Storage
# Auxiliary class to handle the last storage-related steps of the installation
Expand All @@ -36,6 +38,9 @@ class Finisher
include Helpers

# Constructor
# @param logger [Logger]
# @param config [Config]
# @param security [Security]
def initialize(logger, config, security)
@logger = logger
@config = config
Expand Down Expand Up @@ -69,6 +74,7 @@ def run
def possible_steps
[
SecurityStep.new(logger, security),
CopyFilesStep.new(logger),
BootloaderStep.new(logger),
TpmStep.new(logger, config),
IguanaStep.new(logger),
Expand Down Expand Up @@ -121,6 +127,41 @@ def staging_graph
end
end

# Step to copy files from the inst-sys to the target system
class CopyFilesStep < Step
UDEV_RULES_DIR = "/etc/udev/rules.d"
ROOT_PATH = "/"
FILES = [
{ dir: "/etc/udev/rules.d", file: "40-*" },
{ dir: "/etc/udev/rules.d", file: "41-*" },
{ dir: "/etc/udev/rules.d", file: "70-persistent-net.rules" }
].freeze

def label
"Copying important installation files to the target system"
end

def run?
glob_files.any?
end

def run
target = File.join(Yast::Installation.destdir, UDEV_RULES_DIR)
FileUtils.mkdir_p(target)
FileUtils.cp(glob_files, target)
end

private

def root_dir
ROOT_PATH
end

def glob_files
Dir.glob(FILES.map { |f| File.join(root_dir, f[:dir], f[:file]) })
end
end

# Step to write the security settings
class SecurityStep < Step
# Constructor
Expand All @@ -145,8 +186,14 @@ def label
end

def run
cio_ignore_finish if Yast::Arch.s390
::Bootloader::FinishClient.new.write
end

def cio_ignore_finish
require "installation/cio_ignore"
wfm_write("cio_ignore_finish")
end
end

# Step to configure the file-system snapshots
Expand Down
140 changes: 140 additions & 0 deletions service/test/dinstaller/storage/finisher_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# frozen_string_literal: true

# Copyright (c) [2023] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require_relative "../../test_helper"
require_relative "storage_helpers"
require "dinstaller/helpers"
require "dinstaller/config"
require "dinstaller/security"
require "dinstaller/storage/finisher"

describe DInstaller::Storage::Finisher do
include DInstaller::RSpec::StorageHelpers

subject(:storage) { described_class.new(logger, config, security) }

let(:logger) { Logger.new($stdout, level: :warn) }
let(:config_path) do
File.join(FIXTURES_PATH, "root_dir", "etc", "d-installer.yaml")
end

let(:destdir) { File.join(FIXTURES_PATH, "target_dir") }
let(:config) { DInstaller::Config.from_file(config_path) }
let(:security) { instance_double(DInstaller::Security, probe: nil, write: nil) }
let(:copy_files) { DInstaller::Storage::Finisher::CopyFilesStep.new(logger) }
let(:progress) { instance_double(DInstaller::Progress, step: nil) }

describe "#run" do
before do
allow_any_instance_of(described_class::Step).to receive(:run?).and_return(false)
allow(described_class::Step).to receive(:run?).and_return(false)
allow(copy_files.class).to receive(:new).and_return(copy_files)
allow(copy_files).to receive(:run?).and_return(true)
allow(subject).to receive(:progress).and_return(progress)
end

it "runs the possible steps that must be run" do
expect(subject).to receive(:start_progress).with(1)
expect(subject.progress).to receive(:step) do |label, &block|
expect(label).to eql(copy_files.label)
expect(copy_files).to receive(:run)
block.call
end

subject.run
end
end

describe described_class::Step do
subject { described_class.new(logger) }

describe "#run?" do
it "returns whether the step must be executed or not (default: true)" do
expect(subject.run?).to eql(true)
end
end
end

describe described_class::CopyFilesStep do
subject { copy_files }
before do
allow(Yast::Installation).to receive(:destdir).and_return(destdir)
allow(subject).to receive(:root_dir).and_return(File.join(FIXTURES_PATH, "root_dir"))
end

around do |block|
FileUtils.mkdir_p(destdir)
block.call
FileUtils.rm_rf(destdir)
end

describe "#run" do
let(:rules) do
[
"41-cio-ignore.rules", "41-dasd-eckd-0.0.0160.rules",
"41-qeth-0.0.0800.rules", "70-persistent-net.rules"
]
end

it "copies some specific udev rules to the target system when exist" do
subject.run
rules.each do |rule|
expect(File.exist?(File.join(destdir, "/etc/udev/rules.d/#{rule}"))).to eql(true)
end
end
end
end

describe described_class::BootloaderStep do
subject { described_class.new(logger) }
let(:on_s390) { false }

before do
allow(Yast::Arch).to receive(:s390).and_return(on_s390)
allow_any_instance_of(::Bootloader::FinishClient).to receive(:write)
end

context "when running on s390x" do
let(:on_s390) { true }

describe "#run" do
it "runs the cio_ignore_finish client" do
expect(subject).to receive(:wfm_write).with("cio_ignore_finish")
subject.run
end
end
end

context "when not running on s390x" do
describe "#run" do
it "does not run the cio_ignore_finish client" do
expect(subject).to_not receive(:wfm_write).with("cio_ignore_finish")
subject.run
end
end
end

it "runs the Bootloader Finish Client" do
expect_any_instance_of(::Bootloader::FinishClient).to receive(:write)
subject.run
end
end
end
7 changes: 6 additions & 1 deletion service/test/dinstaller/storage/manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,18 @@
before do
mock_storage(devicegraph: devicegraph)
allow(File).to receive(:directory?).with("/iguana").and_return iguana
allow(copy_files_class).to receive(:new).and_return(copy_files)
end
let(:copy_files_class) { DInstaller::Storage::Finisher::CopyFilesStep }
let(:copy_files) { instance_double(copy_files_class, run?: true, run: true, label: "Copy") }

let(:iguana) { false }
let(:devicegraph) { "staging-plain-partitions.yaml" }

it "installs the bootloader, sets up the snapshots, copy logs, and umounts the file systems" do
it "copy needed files, installs the bootloader, sets up the snapshots, " \
"copy logs, and umounts the file systems" do
expect(security).to receive(:write)
expect(copy_files).to receive(:run)
expect(bootloader_finish).to receive(:write)
expect(Yast::WFM).to receive(:CallFunction).with("snapshots_finish", ["Write"])
expect(Yast::WFM).to receive(:CallFunction).with("copy_logs_finish", ["Write"])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Generated by chzdev
ACTION=="add", SUBSYSTEM=="subsystem", KERNEL=="ccw", RUN{program}+="/bin/sh -c 'echo free 0160,0800-0802 > /proc/cio_ignore'"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Generated by chzdev
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="0.0.0160", DRIVER=="dasd-eckd", GOTO="cfg_dasd_eckd_0.0.0160"
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="dasd-eckd", TEST=="[ccw/0.0.0160]", GOTO="cfg_dasd_eckd_0.0.0160"
GOTO="end_dasd_eckd_0.0.0160"

LABEL="cfg_dasd_eckd_0.0.0160"
ATTR{[ccw/0.0.0160]use_diag}="0"
ATTR{[ccw/0.0.0160]online}="1"

LABEL="end_dasd_eckd_0.0.0160"
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by chzdev
ACTION=="add", SUBSYSTEM=="drivers", KERNEL=="qeth", GOTO="group_qeth_0.0.0800"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="0.0.0800", DRIVER=="qeth", GOTO="group_qeth_0.0.0800"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="0.0.0801", DRIVER=="qeth", GOTO="group_qeth_0.0.0800"
ACTION=="add", SUBSYSTEM=="ccw", KERNEL=="0.0.0802", DRIVER=="qeth", GOTO="group_qeth_0.0.0800"
ACTION=="add", SUBSYSTEM=="ccwgroup", KERNEL=="0.0.0800", DRIVER=="qeth", GOTO="cfg_qeth_0.0.0800"
GOTO="end_qeth_0.0.0800"

LABEL="group_qeth_0.0.0800"
TEST=="[ccwgroup/0.0.0800]", GOTO="end_qeth_0.0.0800"
TEST!="[ccw/0.0.0800]", GOTO="end_qeth_0.0.0800"
TEST!="[ccw/0.0.0801]", GOTO="end_qeth_0.0.0800"
TEST!="[ccw/0.0.0802]", GOTO="end_qeth_0.0.0800"
ATTR{[drivers/ccwgroup:qeth]group}="0.0.0800,0.0.0801,0.0.0802"
GOTO="end_qeth_0.0.0800"

LABEL="cfg_qeth_0.0.0800"
ATTR{[ccwgroup/0.0.0800]portno}="0"
ATTR{[ccwgroup/0.0.0800]layer2}="1"
ATTR{[ccwgroup/0.0.0800]online}="1"

LABEL="end_qeth_0.0.0800"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# This file was automatically generated by the /usr/lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# S/390 qeth device at 0.0.0800
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="qeth", ATTR{dev_id}=="0x0", KERNELS=="0.0.0800", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0

0 comments on commit fc1a850

Please sign in to comment.