Skip to content

Commit

Permalink
Add package mapping capability
Browse files Browse the repository at this point in the history
If a given package/pattern in the source machine had been
renamed/splitted/removed in the target machine, we need a way to map
those packages/patterns into the new packages/patterns. This functionality
is expecially helpful for cross-OS migration (i.e. CentOS to openSUSE).
  • Loading branch information
guangyee committed Mar 2, 2021
1 parent e41b642 commit f3f2af6
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 30 deletions.
37 changes: 37 additions & 0 deletions export_helpers/salt_package_map.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# One-to-one package map. Source package version match is optional. If
# specified, the version must match the source package version for the mapping
# to take effect. If source package version is absent, that means it will
# match any version. Likewise, target package version is optional.
# When specified, it will map to a specific target package version. Otherwise,
# it will map to the latest version.
<source package name>:
version: <source package version match>
packages:
- name: <target package name>
version: <target package version>

# Map a source pattern package.
<source pattern package name>
version: <source pattern package version match>
pattern: yes
packages:
- name: <target pattern package name>
version: <target pattern package version>
pattern: yes

# One-to-many map. A source package can map to multiple packages and/or
# patterns.
<source package name>:
version: <source package version match>
packages:
- name: <target pattern package name>
version: <target pattern package version>
pattern: yes
- name: <target package name>
version: <target pacakge version>

# A package without mapping means there are no target packages to map there.
# Therefore, it will be excluded from migration.
<source package name>:
version: <source package version match>

101 changes: 71 additions & 30 deletions lib/salt_states.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,14 @@ def initialize(system_description, options)
@system_description = system_description
@options = options
@group_id_to_name_mapping = {}
@package_map = nil

@system_description.assert_scopes(
"packages",
"os"
)
check_existance_of_extracted_files
load_package_map
end

def write(output_location)
Expand Down Expand Up @@ -95,6 +97,15 @@ def check_existance_of_extracted_files
end
end

def load_package_map
package_map_file = File.join(
Machinery::ROOT, "export_helpers/#{@name}_package_map"
)
if File.file?(package_map_file)
@package_map = YAML.load_file(package_map_file)
end
end

def add_group(name, gid)
@group_id_to_name_mapping[gid] = name
salt_group = <<~SALT
Expand Down Expand Up @@ -382,52 +393,82 @@ def managed_file_states(output_location)
managed_files_sls
end

def add_package(package)
def add_package(name, version, pattern)
package_or_pattern = pattern ? "patern" : "package"
salt_package = <<~SALT
install-package-#{package.name}:
install-#{package_or_pattern}-#{name}:
pkg.installed:
- name: #{package.name}
- name: #{name}
SALT

if @options["skip-package-version"]
if pattern
salt_package += " - includes: [pattern]\n"
end

if @options["skip-package-version"] or version.nil?
salt_package + "\n"
else
salt_package + " - version: '#{package.version}'\n\n"
salt_package + " - version: '#{version}'\n\n"
end
end

def add_pattern(pattern)
<<~SALT
install-pattern-#{pattern.name}:
pkg.installed:
- name: pattern:#{pattern.name}
- version: '#{pattern.version}'
- includes: [pattern]
def package_pattern_match?(package_mapping, pattern)
pattern == package_mapping.fetch('pattern', false)
end

SALT
def package_version_match?(package_mapping, version)
!package_mapping.include?("version") or (
package_mapping["version"] == version)
end

def package_has_mapping?(name, version, pattern)
if @package_map&.include?(name)
if @package_map[name]&.is_a?(Hash)
(package_pattern_match?(@package_map[name], pattern) &&
package_version_match?(@package_map[name], version))
else
!pattern
end
else
false
end
end

def map_package(name, version, pattern)
if package_has_mapping?(name, version, pattern)
if @package_map[name].is_a?(Hash) &&
@package_map[name].include?("packages")
packages = []
@package_map[name]["packages"].each do |package|
packages.append([package["name"], package.fetch("version", nil),
package.fetch("pattern", false)])
end
packages
else
# package maps to nothing. This means the package will not be
# migrated.
[]
end
else
[[name, version, pattern]]
end
end

def package_states
uniq_packages = []
packages_sls = ""
packages = []
@system_description&.packages&.each do |package|
# FIXME(gyee): seem like a bug in inspection that it has duplicate
# entries for packages in manifest.json.
next if uniq_packages.include? package.name

uniq_packages.push(package.name)
packages_sls += add_package(package)
packages += map_package(package.name, package.version, false)
end
@system_description&.patterns&.each do |package|
packages += map_package(package.name, package.version, true)
end
uniq_patterns = []
@system_description&.patterns&.each do |pattern|
# FIXME(gyee): seem like a bug in inspection that it has duplicate
# entries for packages in manifest.json.
next if uniq_patterns.include? pattern.name

uniq_patterns.push(pattern.name)
packages_sls += add_pattern(pattern)

packages = packages.uniq
salt_package_states = ""
packages.each do |package|
salt_package_states += add_package(package[0], package[1], package[2])
end
packages_sls
salt_package_states
end

def add_repo(repo)
Expand Down

0 comments on commit f3f2af6

Please sign in to comment.