66Puppet ::Type . type ( :package ) . provide :openbsd , :parent => Puppet ::Provider ::Package do
77 desc "OpenBSD's form of `pkg_add` support.
88
9+ OpenBSD has the concept of package branches, providing multiple versions of the
10+ same package, i.e. `stable` vs. `snapshot`. To select a specific branch,
11+ suffix the package name with % sign follwed by the branch name, i.e. `gimp%stable`.
12+
913 This provider supports the `install_options` and `uninstall_options`
1014 attributes, which allow command-line flags to be passed to pkg_add and pkg_delete.
1115 These options should be specified as an array where each element is either a
1822 defaultfor 'os.name' => :openbsd
1923 confine 'os.name' => :openbsd
2024
21- has_feature :versionable
2225 has_feature :install_options
2326 has_feature :uninstall_options
24- has_feature :upgradeable
2527 has_feature :supports_flavors
2628
27- mk_resource_methods
28-
2929 def self . instances
30- packages = [ ]
31-
30+ final = [ ]
3231 begin
33- execpipe ( listcmd ) do |process |
34- # our regex for matching pkg_info output
35- regex = /^(.*)-(\d [^-]*)-?([\w -]*)(.*)$/
36- fields = [ :name , :ensure , :flavor ]
37- hash = { }
38-
39- # now turn each returned line into a package object
40- process . each_line { |line |
41- match = regex . match ( line . split [ 0 ] )
42- next unless match
43-
44- fields . zip ( match . captures ) { |field , value |
45- hash [ field ] = value
46- }
32+ packages = listcmd
33+ packages . each { |package , value |
34+ if !package . empty? ( )
35+ value [ :provider ] = self . name
36+ final << new ( value )
37+ end
38+ }
39+ return final
4740
48- hash [ :provider ] = name
49-
50- packages << new ( hash )
51- hash = { }
52- }
53- end
54-
55- packages
5641 rescue Puppet ::ExecutionFailure
5742 nil
5843 end
5944 end
6045
6146 def self . listcmd
62- [ command ( :pkginfo ) , "-a" ]
63- end
64-
65- def latest
66- if @resource [ :flavor ]
67- query = "#{ @resource [ :name ] } --#{ @resource [ :flavor ] } "
68- else
69- query = @resource [ :name ] + "--"
70- end
71-
72- output = Puppet ::Util . withenv ( { } ) { pkginfo "-Q" , query }
73-
74- if output . nil? or output . size == 0 or output =~ /Error from /
75- debug "Failed to query for #{ resource [ :name ] } "
76- return properties [ :ensure ]
77- else
78- # Remove all fuzzy matches first.
79- output = output . split . select { |p | p =~ /^#{ resource [ :name ] } -(\d [^-]*)-?(\w *)/ } . join
80- debug "pkg_info -Q for #{ resource [ :name ] } : #{ output } "
81- end
82-
83- if output =~ /^#{ resource [ :name ] } -(\d [^-]*)-?(\w *) \( installed\) $/
84- debug "Package is already the latest available"
85- properties [ :ensure ]
86- else
87- match = /^(.*)-(\d [^-]*)-?(\w *)$/ . match ( output )
88- debug "Latest available for #{ resource [ :name ] } : #{ match [ 2 ] } "
89-
90- if properties [ :ensure ] . to_sym == :absent
91- return match [ 2 ]
92- end
93-
94- vcmp = properties [ :ensure ] . split ( '.' ) . map { |s | s . to_i } <=> match [ 2 ] . split ( '.' ) . map { |s | s . to_i }
95- if vcmp > 0
96- # The locally installed package may actually be newer than what a mirror
97- # has. Log it at debug, but ignore it otherwise.
98- debug "Package #{ resource [ :name ] } #{ properties [ :ensure ] } newer then available #{ match [ 2 ] } "
99- properties [ :ensure ]
100- else
101- match [ 2 ]
102- end
47+ regex_fuzzy = /^(.*)--([\w -]+)?(%[^w]+)?$/
48+ f = [ ]
49+ f = pkginfo ( "-a" , "-z" ) . split ( "\n " )
50+ packages = { }
51+ f . each do |line |
52+ match = regex_fuzzy . match ( line . split [ 0 ] )
53+ name = match . captures [ 0 ]
54+ flavor = match . captures [ 1 ]
55+ branch = match . captures [ 2 ]
56+ if branch . nil?
57+ pname = name
58+ else
59+ pname = name + branch
60+ end
61+ packages [ pname ] = { :name => pname , :flavor => flavor , :branch => branch , :ensure => "present" }
10362 end
63+ packages
10464 end
10565
106- def update
107- install ( true )
108- end
109-
110- def install ( latest = false )
66+ def install
11167 cmd = [ ]
11268
69+ full_name = get_full_name ( action = "install" )
70+
11371 cmd << '-r'
11472 cmd << install_options
115- cmd << get_full_name ( latest )
116-
117- if latest
118- cmd . unshift ( '-z' )
119- end
73+ cmd << full_name
12074
12175 # pkg_add(1) doesn't set the return value upon failure so we have to peek
12276 # at it's output to see if something went wrong.
12377 output = Puppet ::Util . withenv ( { } ) { pkgadd cmd . flatten . compact }
124- pp output
12578 if output =~ /Can't find /
12679 self . fail "pkg_add returned: #{ output . chomp } "
12780 end
12881 end
12982
130- def get_full_name ( latest = false )
83+ def get_full_name ( action = "install" )
13184 # In case of a real update (i.e., the package already exists) then
13285 # pkg_add(8) can handle the flavors. However, if we're actually
13386 # installing with 'latest', we do need to handle the flavors. This is
13487 # done so we can feed pkg_add(8) the full package name to install to
13588 # prevent ambiguity.
136- if resource [ :flavor ]
137- # If :ensure contains a version, use that instead of looking it up.
138- # This allows for installing packages with the same stem, but multiple
139- # version such as postfix-VERSION-flavor.
140- if @resource [ :ensure ] . to_s =~ /(\d [^-]*)$/
141- use_version = @resource [ :ensure ]
142- else
143- use_version = ''
144- end
145- "#{ resource [ :name ] } -#{ use_version } -#{ resource [ :flavor ] } "
146- elsif resource [ :name ] . to_s . match ( /[a-z0-9]%[0-9a-z]/i )
147- resource [ :name ] . to_s
148- elsif !latest
149- "#{ resource [ :name ] } --"
150- else
151- # If :ensure contains a version, use that instead of looking it up.
152- # This allows for installing packages with the same stem, but multiple
153- # version such as openldap-server.
154- if @resource [ :ensure ] . to_s =~ /(\d [^-]*)$/
155- use_version = @resource [ :ensure ]
156- else
157- use_version = get_version
158- end
159-
160- if resource [ :flavor ]
161- [ @resource [ :name ] , use_version , @resource [ :flavor ] ] . join ( '-' ) . gsub ( /-+$/ , '' )
162- else
163- [ @resource [ :name ] , use_version ]
164- end
165- end
166- end
16789
168- def get_version
169- pkg_search_name = @resource [ :name ]
170- unless pkg_search_name . match ( /[a-z0-9]%[0-9a-z]/i ) and !@resource [ :flavor ]
171- # we are only called when no flavor is specified
172- # so append '--' to the :name to avoid patch versions on flavors
173- pkg_search_name << "--"
90+ name_branch_regex = /^(\S *)(%\w *)$/
91+ match = name_branch_regex . match ( @resource [ :name ] )
92+ if match
93+ use_name = match . captures [ 0 ]
94+ use_branch = match . captures [ 1 ]
95+ else
96+ use_name = @resource [ :name ]
97+ use_branch = ''
17498 end
175- # our regex for matching pkg_info output
176- regex = /^(.*)-(\d [^-]*)[-]?(\w *)(.*)$/
177- master_version = 0
178- version = -1
179-
180- # pkg_info -I might return multiple lines, i.e. flavors
181- matching_pkgs = pkginfo ( "-I" , "pkg_search_name" )
182- matching_pkgs . each_line do |line |
183- next unless ( match = regex . match ( line . split [ 0 ] ) )
18499
185- # now we return the first version, unless ensure is latest
186- version = match . captures [ 1 ]
187- return version unless @resource [ :ensure ] == "latest"
188-
189- master_version = version unless master_version > version
100+ if @resource [ :flavor ]
101+ return "#{ use_name } --#{ @resource [ :flavor ] } #{ use_branch } "
102+ else
103+ return "#{ use_name } --#{ use_branch } "
190104 end
191105
192- return master_version unless master_version == 0
193-
194- return '' if version == -1
195-
196- raise Puppet ::Error , _ ( "%{version} is not available for this package" ) % { version : version }
197- rescue Puppet ::ExecutionFailure
198- nil
199106 end
200107
201108 def query
202- # Search for the version info
203- if pkginfo ( @resource [ :name ] ) =~ /Information for (inst:)?#{ @resource [ :name ] } -(\S +)/
204- { :ensure => Regexp . last_match ( 2 ) }
205- else
206- nil
109+ pkg = self . class . instances . find do |package |
110+ @resource [ :name ] == package . name
207111 end
112+ pkg ? pkg . properties : nil
208113 end
209114
210115 def install_options
@@ -215,12 +120,16 @@ def uninstall_options
215120 [ join_options ( resource [ :uninstall_options ] ) ]
216121 end
217122
218- def uninstall
219- pkgdelete uninstall_options . flatten . compact , @resource [ :name ]
123+ def uninstall ( purge = false )
124+ if purge
125+ pkgdelete "-c" , "-qq" , uninstall_options . flatten . compact , get_full_name ( action = "uninstall" )
126+ else
127+ pkgdelete uninstall_options . flatten . compact , get_full_name ( action = "uninstall" )
128+ end
220129 end
221130
222131 def purge
223- pkgdelete "-c" , "-q" , @resource [ :name ]
132+ uninstall ( purge = true )
224133 end
225134
226135 def flavor
@@ -229,7 +138,6 @@ def flavor
229138
230139 def flavor = ( value )
231140 if flavor != @resource . should ( :flavor )
232- uninstall
233141 install
234142 end
235143 end
0 commit comments