Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Automatically select the driver packages (bsc#953522)
- 4.1.27
- Loading branch information
Showing
7 changed files
with
348 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# ------------------------------------------------------------------------------ | ||
# Copyright (c) 2019 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. | ||
# ------------------------------------------------------------------------------ | ||
|
||
require "yaml" | ||
require "yast" | ||
|
||
module Y2Packager | ||
# Track the known repositories from which the system packages (drivers) | ||
# have been installed (or suggested to the user). | ||
# @see https://github.com/yast/yast-packager/wiki/Selecting-the-Driver-Packages | ||
class KnownRepositories | ||
include Yast::Logger | ||
|
||
STATUS_FILE = "/var/lib/YaST2/system_packages_repos.yaml".freeze | ||
|
||
# Constructor | ||
def initialize | ||
Yast.import "Pkg" | ||
Yast.import "Installation" | ||
end | ||
|
||
def repositories | ||
@repositories ||= read_repositories | ||
end | ||
|
||
def write | ||
log.info("Writing known repositories #{repositories.inspect} to #{status_file}") | ||
|
||
# accessible only for the root user, the repository URLs should not contain | ||
# any passwords but rather be safe than sorry | ||
File.open(status_file, "w", 0o600) do |f| | ||
f.write(repositories.to_yaml) | ||
end | ||
end | ||
|
||
def update | ||
# add the current repositories | ||
repositories.concat(current_repositories) | ||
# remove duplicates and sort them | ||
repositories.uniq! | ||
repositories.sort! | ||
end | ||
|
||
# | ||
# Return new (unknown) repositories | ||
# | ||
# @return [Array<String>] List of new repositories (URLs) | ||
# | ||
def new_repositories | ||
log.info "current repositories: #{current_repositories.inspect}" | ||
log.info "known repositories: #{repositories.inspect}" | ||
|
||
new_repos = current_repositories - repositories | ||
log.info "New repositories: #{new_repos.inspect}" | ||
new_repos | ||
end | ||
|
||
private | ||
|
||
def read_repositories | ||
if !File.exist?(status_file) | ||
log.info("Status file #{status_file} not found") | ||
return [] | ||
end | ||
|
||
status = YAML.load_file(status_file) | ||
# unify the file in case it was manually modified | ||
status.uniq! | ||
status.sort! | ||
|
||
log.info("Read known repositories from #{status_file}: #{status}") | ||
status | ||
end | ||
|
||
def current_repositories | ||
# only the enabled repositories | ||
repo_ids = Yast::Pkg.SourceGetCurrent(true) | ||
|
||
urls = repo_ids.map { |r| Yast::Pkg.SourceGeneralData(r)["url"] } | ||
urls.uniq! | ||
urls.sort | ||
end | ||
|
||
def status_file | ||
# add the current target prefix | ||
File.join(Yast::Installation.destdir, STATUS_FILE) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# ------------------------------------------------------------------------------ | ||
# Copyright (c) 2019 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. | ||
# ------------------------------------------------------------------------------ | ||
|
||
require "yast" | ||
|
||
module Y2Packager | ||
# Preselect the system packages (drivers) from the specified repositories. | ||
# @see https://github.com/yast/yast-packager/wiki/Selecting-the-Driver-Packages | ||
class SystemPackages | ||
include Yast::Logger | ||
|
||
# @return [Array<String>] Repositories from which the driver packages should be selected | ||
attr_reader :repositories | ||
|
||
# | ||
# Constructor | ||
# | ||
# @param repository_urls [Array<String>] Repositories from which the driver | ||
# packages should be selected | ||
# | ||
def initialize(repository_urls) | ||
log.info "System packages repositories: #{repository_urls.inspect}" | ||
@repositories = repository_urls | ||
end | ||
|
||
def packages | ||
@packages ||= find_packages | ||
end | ||
|
||
def select | ||
return if packages.empty? | ||
log.info "Preselecting system packages: #{packages.inspect}" | ||
packages.each { |p| Yast::Pkg.PkgInstall(p) } | ||
end | ||
|
||
private | ||
|
||
# | ||
# Create repository ID to URL mapping | ||
# | ||
# @return [Array<Integer>] List of repository IDs | ||
# | ||
def repo_ids(urls) | ||
repo_ids = Yast::Pkg.SourceGetCurrent(true) | ||
repo_ids.each_with_object([]) do |i, list| | ||
list << i if urls.include?(Yast::Pkg.SourceGeneralData(i)["url"]) | ||
end | ||
end | ||
|
||
def find_packages | ||
if repositories.empty? | ||
log.info "No new repository found, not searching system packages" | ||
return [] | ||
end | ||
|
||
original_solver_flags = Yast::Pkg.GetSolverFlags | ||
|
||
# solver flags for selecting minimal recommended packages (e.g. drivers) | ||
Yast::Pkg.SetSolverFlags( | ||
"ignoreAlreadyRecommended" => false, | ||
"onlyRequires" => true | ||
) | ||
# select the packages | ||
Yast::Pkg.PkgSolve(true) | ||
|
||
ids = repo_ids(repositories) | ||
|
||
pkgs = Yast::Pkg.ResolvableProperties("", :package, "") | ||
pkgs = pkgs.select do |p| | ||
# the packages from the specified repositories selected by the solver | ||
p["status"] == :selected && ids.include?(p["source"]) && p["transact_by"] == :solver | ||
end | ||
|
||
# set back the original solver flags | ||
Yast::Pkg.SetSolverFlags(original_solver_flags) | ||
|
||
pkgs.map! { |p| p["name"] } | ||
log.info "Found system packages: #{pkgs}" | ||
|
||
pkgs | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#!/usr/bin/env rspec | ||
|
||
require_relative "test_helper" | ||
require "y2packager/known_repositories" | ||
|
||
describe Y2Packager::KnownRepositories do | ||
Yast.import "Pkg" | ||
|
||
let(:repo_url) { "http://example.com/repo" } | ||
let(:repos) { [repo_url] } | ||
let(:source_id) { 42 } | ||
|
||
before do | ||
allow(Yast::WFM).to receive(:scr_root).and_return("/") | ||
end | ||
|
||
describe "#repositories" do | ||
it "returns empty list if the file does not exist" do | ||
expect(File).to receive(:exist?).with(Y2Packager::KnownRepositories::STATUS_FILE) | ||
.and_return(false) | ||
expect(subject.repositories).to eq([]) | ||
end | ||
|
||
it "reads the repository list from file" do | ||
expect(File).to receive(:exist?).with(Y2Packager::KnownRepositories::STATUS_FILE) | ||
.and_return(true) | ||
expect(YAML).to receive(:load_file).with(Y2Packager::KnownRepositories::STATUS_FILE) | ||
.and_return(repos) | ||
|
||
expect(subject.repositories).to eq(repos) | ||
end | ||
end | ||
|
||
describe "#write" do | ||
it "writes the known repositories to the file" do | ||
allow(subject).to receive(:repositories).and_return(repos) | ||
|
||
file = double("file") | ||
expect(File).to receive(:open).with(Y2Packager::KnownRepositories::STATUS_FILE, "w", 0o600) | ||
.and_yield(file) | ||
expect(file).to receive(:write).with(repos.to_yaml) | ||
|
||
subject.write | ||
end | ||
end | ||
|
||
describe "#new_repositories" do | ||
it "return the unknown repositories" do | ||
allow(subject).to receive(:repositories).and_return(repos) | ||
|
||
allow(Yast::Pkg).to receive(:SourceGetCurrent).with(true).and_return([source_id]) | ||
allow(Yast::Pkg).to receive(:SourceGeneralData).with(source_id) | ||
.and_return("url" => "http://new.example.com") | ||
|
||
expect(subject.new_repositories).to eq(["http://new.example.com"]) | ||
end | ||
end | ||
|
||
describe "#update" do | ||
it "add the current repositories to the known repositories" do | ||
allow(subject).to receive(:repositories).and_return(repos) | ||
|
||
allow(Yast::Pkg).to receive(:SourceGetCurrent).with(true).and_return([source_id]) | ||
allow(Yast::Pkg).to receive(:SourceGeneralData).with(source_id) | ||
.and_return("url" => "http://new.example.com") | ||
|
||
subject.update | ||
expect(repos).to eq(["http://example.com/repo", "http://new.example.com"]) | ||
end | ||
end | ||
|
||
end |
Oops, something went wrong.