On 4/10/24 07:10, Sebastian Reitenbach wrote:
Hi, On Tuesday, April 09, 2024 22:43 CEST, Giovanni Bechis <giova...@paclan.it> wrote:On Tue, Apr 09, 2024 at 10:17:30PM +0200, Sebastian Reitenbach wrote:Since we now have a recent Puppet in ports, I started looking at how packages are handled with Puppet. My current trouble is that it wasn't really possible to install banches properly: i.e. can't properly install gimp, or auto* based on branch. Or esp, when want to install multiple of them, it was just not possible. For ports where branches conflict, i.e. postfix, this was working, but had to specify exact version, and on every upgrade bump the version .... _very_ annoying. Currently Puppet allows to install packages of a given version (ensure => "X.Y.Z"), or to follow updates (ensure => "latest").[...]This is just for Puppet 8. Anyone still on Puppet 7? It should be easily ported to Puppet 7 as well.I am on Puppet 7 and I do not have time to upgrade to Puppet 8 soon; IMy upgrade from Puppet 7 to 8 took quite a long time. They removed a lot of backward compat shim, and if you have many old and partially hand made or patched modules like I do, it took quite a while to update all of them....
upgrading is on my queue and I have lot of hand made modules, other then that, can a Puppet 7 client connect to a Puppet 8 server ?
Attached an untested version of the same changes for the Puppet 7 port.am also using "ensure => latest" syntax but I can change my code to get rid of it OpenBSD will no more support it.What's your use-case to using "ensure => latest"? If there's really a "good one", I can look into re-adding the feature. My use-case up to now for sparingly using "latest" was to force using "snapshot" branch of some packages.
my OpenBSD Puppet server manages Linux and Windows servers as well, on those OS I want to update automatically only some trusted packages, not all the packages the distro wants to update. Anyway I can change that part of my code without big issues. Cheers Giovanni
Cheers Giovannicheers, Sebastian Index: Makefile =================================================================== RCS file: /cvs/ports/sysutils/ruby-puppet/8/Makefile,v diff -u -r1.2 Makefile --- Makefile 20 Mar 2024 21:21:14 -0000 1.2 +++ Makefile 9 Apr 2024 19:51:40 -0000 @@ -1,6 +1,7 @@ PORTROACH= limit:^7VERSION= 8.5.1+REVISION= 0RUN_DEPENDS+= converters/ruby-multi_json,${MODRUBY_FLAVOR}>=1.13,<2 \devel/ruby-concurrent-ruby,${MODRUBY_FLAVOR}>=1,<2 \ Index: patches/patch-lib_puppet_provider_package_openbsd_rb =================================================================== RCS file: /cvs/ports/sysutils/ruby-puppet/8/patches/patch-lib_puppet_provider_package_openbsd_rb,v diff -u -r1.2 patch-lib_puppet_provider_package_openbsd_rb --- patches/patch-lib_puppet_provider_package_openbsd_rb 20 Mar 2024 21:21:14 -0000 1.2 +++ patches/patch-lib_puppet_provider_package_openbsd_rb 9 Apr 2024 19:51:40 -0000 @@ -1,42 +1,89 @@ -- Handle errors from pkg_add -- Handle uninstall_options being 'nil' by default -- If no flavor speficied, force the empty flavor with '--' - but skipping the % un-ambiguity pkg names -- Bail out on shortform PKG_PATH (i.e. 'ftp.openbsd.org') -- pkg.conf is gone -- properly handle packages with multiple versions and flavors, - i.e. postfix-XXX-flavor - +- get rid of versionable (no ensure => "version X.X.X") +- get rid of upgradeable (ensure => latest) +- properly support branchesIndex: lib/puppet/provider/package/openbsd.rb--- lib/puppet/provider/package/openbsd.rb.orig +++ lib/puppet/provider/package/openbsd.rb -@@ -24,6 +24,8 @@ Puppet::Type.type(:package).provide :openbsd, :parent - has_feature :upgradeable +@@ -6,10 +6,14 @@ require_relative '../../../puppet/provider/package' + Puppet::Type.type(:package).provide :openbsd, :parent => Puppet::Provider::Package do + desc "OpenBSD's form of `pkg_add` support. + ++ OpenBSD has the concept of package branches, providing multiple versions of the ++ same package, i.e. `stable` vs. `snapshot`. To select a specific branch, ++ suffix the package name with % sign follwed by the branch name, i.e. `gimp%stable`. ++ + This provider supports the `install_options` and `uninstall_options` + attributes, which allow command-line flags to be passed to pkg_add and pkg_delete. + These options should be specified as an array where each element is either a +- string or a hash." ++ string or a hash." + + commands :pkginfo => "pkg_info", + :pkgadd => "pkg_add", +@@ -18,220 +22,94 @@ Puppet::Type.type(:package).provide :openbsd, :parent + defaultfor 'os.name' => :openbsd + confine 'os.name' => :openbsd + +- has_feature :versionable + has_feature :install_options + has_feature :uninstall_options +- has_feature :upgradeable has_feature :supports_flavors-+ mk_resource_methods-+ def self.instances - packages = [] - -@@ -46,12 +48,6 @@ Puppet::Type.type(:package).provide :openbsd, :parent - - packages << new(hash) - hash = {} +- packages = [] +- ++ final = [] + begin +- execpipe(listcmd) do |process| +- # our regex for matching pkg_info output +- regex = /^(.*)-(\d[^-]*)[-]?([\w-]*)(.*)$/ +- fields = [:name, :ensure, :flavor] +- hash = {} ++ packages = listcmd ++ packages.each { |package, value| ++ if !package.empty?() ++ value[:provider] = self.name ++ final << new(value) ++ end ++ } ++ return final + +- # now turn each returned line into a package object +- process.each_line { |line| +- match = regex.match(line.split[0]) +- if match +- fields.zip(match.captures) { |field, value| +- hash[field] = value +- } +- +- hash[:provider] = self.name +- +- packages << new(hash) +- hash = {} - else - unless line =~ /Updating the pkgdb/ - # Print a warning on lines we can't match, but move - # on, since it should be non-fatal - warning(_("Failed to match line %{line}") % { line: line }) - end - end - } - end -@@ -67,26 +63,17 @@ Puppet::Type.type(:package).provide :openbsd, :parent +- end +- } +- end +- +- return packages + rescue Puppet::ExecutionFailure +- return nil ++ nil + end end- def latest+ def self.listcmd +- [command(:pkginfo), "-a"] +- end +- +- def latest - parse_pkgconf - - if @resource[:source][-1, 1] == ::File::SEPARATOR @@ -45,55 +92,51 @@ - e_vars = {} - end - - if @resource[:flavor] - query = "#{@resource[:name]}--#{@resource[:flavor]}" - else +- if @resource[:flavor] +- query = "#{@resource[:name]}--#{@resource[:flavor]}" +- else - query = @resource[:name] -+ query = @resource[:name] + "--" - end - +- end +- - output = Puppet::Util.withenv(e_vars) { pkginfo "-Q", query } - version = properties[:ensure] -+ output = Puppet::Util.withenv({}) {pkginfo "-Q", query} - - if output.nil? or output.size == 0 or output =~ /Error from / - debug "Failed to query for #{resource[:name]}" +- +- if output.nil? or output.size == 0 or output =~ /Error from / +- debug "Failed to query for #{resource[:name]}" - return version -+ return properties[:ensure] - else - # Remove all fuzzy matches first. - output = output.split.select { |p| p =~ /^#{resource[:name]}-(\d[^-]*)[-]?(\w*)/ }.join -@@ -95,21 +82,22 @@ Puppet::Type.type(:package).provide :openbsd, :parent - - if output =~ /^#{resource[:name]}-(\d[^-]*)[-]?(\w*) \(installed\)$/ - debug "Package is already the latest available" +- else +- # Remove all fuzzy matches first. +- output = output.split.select { |p| p =~ /^#{resource[:name]}-(\d[^-]*)[-]?(\w*)/ }.join +- debug "pkg_info -Q for #{resource[:name]}: #{output}" +- end +- +- if output =~ /^#{resource[:name]}-(\d[^-]*)[-]?(\w*) \(installed\)$/ +- debug "Package is already the latest available" - return version -+ return properties[:ensure] - else - match = /^(.*)-(\d[^-]*)[-]?(\w*)$/.match(output) - debug "Latest available for #{resource[:name]}: #{match[2]}" - +- else +- match = /^(.*)-(\d[^-]*)[-]?(\w*)$/.match(output) +- debug "Latest available for #{resource[:name]}: #{match[2]}" +- - if version.to_sym == :absent || version.to_sym == :purged -+ if properties[:ensure].to_sym == :absent - return match[2] - end - - vcmp = version.split('.').map { |s| s.to_i } <=> match[2].split('.').map { |s| s.to_i } -+ vcmp = properties[:ensure].split('.').map{|s|s.to_i} <=> match[2].split('.').map{|s|s.to_i} - if vcmp > 0 - # The locally installed package may actually be newer than what a mirror - # has. Log it at debug, but ignore it otherwise. +- return match[2] +- end +- +- vcmp = version.split('.').map { |s| s.to_i } <=> match[2].split('.').map { |s| s.to_i } +- if vcmp > 0 +- # The locally installed package may actually be newer than what a mirror +- # has. Log it at debug, but ignore it otherwise. - debug "Package #{resource[:name]} #{version} newer then available #{match[2]}" - return version -+ debug "Package #{resource[:name]} #{properties[:ensure]} newer then available #{match[2]}" -+ return properties[:ensure] - else - return match[2] - end -@@ -120,57 +108,25 @@ Puppet::Type.type(:package).provide :openbsd, :parent - self.install(true) - end - +- else +- return match[2] +- end +- end +- end +- +- def update +- self.install(true) +- end +- - def parse_pkgconf - unless @resource[:source] - if Puppet::FileSystem.exist?("/etc/pkg.conf") @@ -111,7 +154,20 @@ - end - end - end -- end ++ regex_fuzzy = /^(.*)--([\w-]+)?(%[^w]+)?$/ ++ f = [] ++ f = pkginfo("-a", "-z").split("\n") ++ packages = {} ++ f.each do |line| ++ match = regex_fuzzy.match(line.split[0]) ++ name = match.captures[0] ++ flavor = match.captures[1] ++ branch = match.captures[2] ++ if branch.nil? ++ pname = name ++ else ++ pname = name + branch + end - - unless @resource[:source] - raise Puppet::Error, @@ -121,14 +177,18 @@ - raise Puppet::Error, - _("You must specify a package source or configure an installpath in /etc/pkg.conf") - end -- end -- end -- - def install(latest = false) ++ packages[pname] = { :name => pname, :flavor => flavor, :branch => branch, :ensure => "present" } + end ++ packages + end + +- def install(latest = false) ++ def install cmd = []- parse_pkgconf-- ++ full_name = get_full_name(action="install") + - if @resource[:source][-1, 1] == ::File::SEPARATOR - e_vars = { 'PKG_PATH' => @resource[:source] } - full_name = get_full_name(latest) @@ -139,27 +199,24 @@ - + cmd << '-r' cmd << install_options -- cmd << full_name -+ cmd << get_full_name(latest) + cmd << full_name- if latest+- if latest - cmd.unshift('-rz') -+ cmd.unshift('-z') - end - -- Puppet::Util.withenv(e_vars) { pkgadd cmd.flatten.compact } + # pkg_add(1) doesn't set the return value upon failure so we have to peek + # at it's output to see if something went wrong. + output = Puppet::Util.withenv({}) { pkgadd cmd.flatten.compact } -+ require 'pp' -+ pp output + if output =~ /Can't find / + self.fail "pkg_add returned: #{output.chomp}" -+ end + end +- +- Puppet::Util.withenv(e_vars) { pkgadd cmd.flatten.compact } end- def get_full_name(latest = false)-@@ -179,11 +135,20 @@ Puppet::Type.type(:package).provide :openbsd, :parent +- def get_full_name(latest = false) ++ def get_full_name(action="install") + # In case of a real update (i.e., the package already exists) then + # pkg_add(8) can handle the flavors. However, if we're actually # installing with 'latest', we do need to handle the flavors. This is # done so we can feed pkg_add(8) the full package name to install to # prevent ambiguity. @@ -168,53 +225,35 @@ - elsif latest - # Don't depend on get_version for updates. - @resource[:name] -+ if resource[:flavor] -+ # If :ensure contains a version, use that instead of looking it up. -+ # This allows for installing packages with the same stem, but multiple -+ # version such as postfix-VERSION-flavor. -+ if @resource[:ensure].to_s =~ /(\d[^-]*)$/ -+ use_version = @resource[:ensure] -+ else -+ use_version = '' -+ end -+ "#{resource[:name]}-#{use_version}-#{resource[:flavor]}" -+ elsif resource[:name].to_s.match(/[a-z0-9]%[0-9a-z]/i) -+ "#{resource[:name]}" -+ elsif not latest -+ "#{resource[:name]}--" - else - # If :ensure contains a version, use that instead of looking it up. - # This allows for installing packages with the same stem, but multiple -@@ -194,33 +159,41 @@ Puppet::Type.type(:package).provide :openbsd, :parent - use_version = get_version - end +- else +- # If :ensure contains a version, use that instead of looking it up. +- # This allows for installing packages with the same stem, but multiple +- # version such as openldap-server. +- if @resource[:ensure].to_s =~ /(\d[^-]*)$/ +- use_version = @resource[:ensure] +- else +- use_version = get_version +- end- [@resource[:name], use_version, @resource[:flavor]].join('-').gsub(/-+$/, '')-+ if resource[:flavor] -+ [ @resource[:name], use_version, @resource[:flavor]].join('-').gsub(/-+$/, '') -+ else -+ [ @resource[:name], use_version ] -+ end ++ name_branch_regex = /^(\S*)(%\w*)$/ ++ match = name_branch_regex.match(@resource[:name]) ++ if match ++ use_name = match.captures[0] ++ use_branch = match.captures[1] ++ else ++ use_name = @resource[:name] ++ use_branch = '' end - end +- end- def get_version+- def get_version - execpipe([command(:pkginfo), "-I", @resource[:name]]) do |process| - # our regex for matching pkg_info output - regex = /^(.*)-(\d[^-]*)[-]?(\w*)(.*)$/ - master_version = 0 - version = -1 -+ pkg_search_name = @resource[:name] -+ unless pkg_search_name.match(/[a-z0-9]%[0-9a-z]/i) and not @resource[:flavor] -+ # we are only called when no flavor is specified -+ # so append '--' to the :name to avoid patch versions on flavors -+ pkg_search_name << "--" -+ end -+ # our regex for matching pkg_info output -+ regex = /^(.*)-(\d[^-]*)[-]?(\w*)(.*)$/ -+ master_version = 0 -+ version = -1 - +- - process.each_line do |line| - match = regex.match(line.split[0]) - if match @@ -224,29 +263,36 @@ - - master_version = version unless master_version > version - end -+ # pkg_info -I might return multiple lines, i.e. flavors -+ matching_pkgs = pkginfo("-I", "pkg_search_name") -+ matching_pkgs.each_line do |line| -+ if match = regex.match(line.split[0]) -+ # now we return the first version, unless ensure is latest -+ version = match.captures[1] -+ return version unless @resource[:ensure] == "latest" -+ master_version = version unless master_version > version - end -+ end - +- end +- - return master_version unless master_version == 0 - return '' if version == -1 -+ return master_version unless master_version == 0 -+ return '' if version == -1 -+ raise Puppet::Error, _("%{version} is not available for this package") % { version: version } - +- - raise Puppet::Error, _("%{version} is not available for this package") % { version: version } -- end - rescue Puppet::ExecutionFailure - return nil ++ if @resource[:flavor] ++ return "#{use_name}--#{@resource[:flavor]}#{use_branch}" ++ else ++ return "#{use_name}--#{use_branch}" + end +- rescue Puppet::ExecutionFailure +- return nil ++ end -@@ -239,7 +212,7 @@ Puppet::Type.type(:package).provide :openbsd, :parent + + def query +- # Search for the version info +- if pkginfo(@resource[:name]) =~ /Information for (inst:)?#{@resource[:name]}-(\S+)/ +- return { :ensure => $2 } +- else +- return nil ++ pkg = self.class.instances.find do |package| ++ @resource[:name] == package.name + end ++ pkg ? pkg.properties : nil + end + + def install_options +@@ -239,15 +117,19 @@ Puppet::Type.type(:package).provide :openbsd, :parent enddef uninstall_options@@ -254,4 +300,27 @@ + [join_options(resource[:uninstall_options])] end- def uninstall+- def uninstall +- pkgdelete uninstall_options.flatten.compact, @resource[:name] ++ def uninstall(purge = false) ++ if purge ++ pkgdelete "-c", "-qq", uninstall_options.flatten.compact, get_full_name(action="uninstall") ++ else ++ pkgdelete uninstall_options.flatten.compact, get_full_name(action="uninstall") ++ end + end + + def purge +- pkgdelete "-c", "-q", @resource[:name] ++ uninstall(purge=true) + end + + def flavor +@@ -256,7 +138,6 @@ Puppet::Type.type(:package).provide :openbsd, :parent + + def flavor=(value) + if flavor != @resource.should(:flavor) +- uninstall + install + end + end
OpenPGP_signature.asc
Description: OpenPGP digital signature