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
2729 def self . instances
@@ -30,8 +32,8 @@ def self.instances
3032 begin
3133 execpipe ( listcmd ) do |process |
3234 # our regex for matching pkg_info output
33- regex = /^(.*)-( \d [^-]*)-?([ \w -]*)(.*) $/
34- fields = [ :name , :ensure , :flavor ]
35+ regex = /^(.*)--([ \w -]+)?(%[^w]+)? $/
36+ fields = [ :name , :flavor , :branch ]
3537 hash = { }
3638
3739 # now turn each returned line into a package object
@@ -42,8 +44,9 @@ def self.instances
4244 hash [ field ] = value
4345 }
4446
45- hash [ :provider ] = name
47+ hash [ :name ] = " #{ hash [ : name] } #{ hash [ :branch ] } " if hash [ :branch ]
4648
49+ hash [ :provider ] = name
4750 packages << new ( hash )
4851 hash = { }
4952 else
@@ -63,191 +66,71 @@ def self.instances
6366 end
6467
6568 def self . listcmd
66- [ command ( :pkginfo ) , "-a" ]
67- end
68-
69- def latest
70- parse_pkgconf
71-
72- if @resource [ :source ] [ -1 , 1 ] == ::File ::SEPARATOR
73- e_vars = { 'PKG_PATH' => @resource [ :source ] }
74- else
75- e_vars = { }
76- end
77-
78- if @resource [ :flavor ]
79- query = "#{ @resource [ :name ] } --#{ @resource [ :flavor ] } "
80- else
81- query = @resource [ :name ]
82- end
83-
84- output = Puppet ::Util . withenv ( e_vars ) { pkginfo "-Q" , query }
85- version = properties [ :ensure ]
86-
87- if output . nil? or output . size == 0 or output =~ /Error from /
88- debug "Failed to query for #{ resource [ :name ] } "
89- return version
90- else
91- # Remove all fuzzy matches first.
92- output = output . split . select { |p | p =~ /^#{ resource [ :name ] } -(\d [^-]*)-?(\w *)/ } . join
93- debug "pkg_info -Q for #{ resource [ :name ] } : #{ output } "
94- end
95-
96- if output =~ /^#{ resource [ :name ] } -(\d [^-]*)-?(\w *) \( installed\) $/
97- debug "Package is already the latest available"
98- version
99- else
100- match = /^(.*)-(\d [^-]*)-?(\w *)$/ . match ( output )
101- debug "Latest available for #{ resource [ :name ] } : #{ match [ 2 ] } "
102-
103- if version . to_sym == :absent || version . to_sym == :purged
104- return match [ 2 ]
105- end
106-
107- vcmp = version . split ( '.' ) . map ( &:to_i ) <=> match [ 2 ] . split ( '.' ) . map ( &:to_i )
108- if vcmp > 0
109- # The locally installed package may actually be newer than what a mirror
110- # has. Log it at debug, but ignore it otherwise.
111- debug "Package #{ resource [ :name ] } #{ version } newer then available #{ match [ 2 ] } "
112- version
113- else
114- match [ 2 ]
115- end
116- end
69+ [ command ( :pkginfo ) , "-a" , "-z" ]
11770 end
11871
119- def update
120- install ( true )
121- end
122-
123- def parse_pkgconf
124- unless @resource [ :source ]
125- if Puppet ::FileSystem . exist? ( "/etc/pkg.conf" )
126- File . open ( "/etc/pkg.conf" , "rb" ) . readlines . each do |line |
127- matchdata = line . match ( /^installpath\s *=\s *(.+)\s *$/i )
128- if matchdata
129- @resource [ :source ] = matchdata [ 1 ]
130- else
131- matchdata = line . match ( /^installpath\s *\+ =\s *(.+)\s *$/i )
132- if matchdata
133- if @resource [ :source ] . nil?
134- @resource [ :source ] = matchdata [ 1 ]
135- else
136- @resource [ :source ] += ":" + matchdata [ 1 ]
137- end
138- end
139- end
140- end
141-
142- unless @resource [ :source ]
143- raise Puppet ::Error ,
144- _ ( "No valid installpath found in /etc/pkg.conf and no source was set" )
145- end
146- else
147- raise Puppet ::Error ,
148- _ ( "You must specify a package source or configure an installpath in /etc/pkg.conf" )
149- end
150- end
151- end
152-
153- def install ( latest = false )
72+ def install
15473 cmd = [ ]
15574
156- parse_pkgconf
157-
158- if @resource [ :source ] [ -1 , 1 ] == ::File ::SEPARATOR
159- e_vars = { 'PKG_PATH' => @resource [ :source ] }
160- full_name = get_full_name ( latest )
161- else
162- e_vars = { }
163- full_name = @resource [ :source ]
164- end
75+ full_name = get_full_name
16576
77+ cmd << '-r'
16678 cmd << install_options
16779 cmd << full_name
16880
169- if latest
170- cmd . unshift ( '-rz' )
81+ # pkg_add(1) doesn't set the return value upon failure so we have to peek
82+ # at it's output to see if something went wrong.
83+ output = Puppet ::Util . withenv ( { } ) { pkgadd cmd . flatten . compact }
84+ if output =~ /Can't find /
85+ self . fail "pkg_add returned: #{ output . chomp } "
17186 end
172-
173- Puppet ::Util . withenv ( e_vars ) { pkgadd cmd . flatten . compact }
17487 end
17588
176- def get_full_name ( latest = false )
89+ def get_full_name
17790 # In case of a real update (i.e., the package already exists) then
178- # pkg_add(8 ) can handle the flavors. However, if we're actually
91+ # pkg_add(1 ) can handle the flavors. However, if we're actually
17992 # installing with 'latest', we do need to handle the flavors. This is
180- # done so we can feed pkg_add(8 ) the full package name to install to
93+ # done so we can feed pkg_add(1 ) the full package name to install to
18194 # prevent ambiguity.
182- if latest && resource [ :flavor ]
183- "#{ resource [ :name ] } --#{ resource [ :flavor ] } "
184- elsif latest
185- # Don't depend on get_version for updates.
186- @resource [ :name ]
187- else
188- # If :ensure contains a version, use that instead of looking it up.
189- # This allows for installing packages with the same stem, but multiple
190- # version such as openldap-server.
191- if @resource [ :ensure ] . to_s =~ /(\d [^-]*)$/
192- use_version = @resource [ :ensure ]
193- else
194- use_version = get_version
195- end
19695
197- [ @resource [ :name ] , use_version , @resource [ :flavor ] ] . join ( '-' ) . gsub ( /-+$/ , '' )
96+ name_branch_regex = /^(\S *)(%\w *)$/
97+ match = name_branch_regex . match ( @resource [ :name ] )
98+ if match
99+ use_name = match . captures [ 0 ]
100+ use_branch = match . captures [ 1 ]
101+ else
102+ use_name = @resource [ :name ]
103+ use_branch = ''
198104 end
199- end
200-
201- def get_version
202- execpipe ( [ command ( :pkginfo ) , "-I" , @resource [ :name ] ] ) do |process |
203- # our regex for matching pkg_info output
204- regex = /^(.*)-(\d [^-]*)-?(\w *)(.*)$/
205- master_version = 0
206- version = -1
207-
208- process . each_line do |line |
209- match = regex . match ( line . split [ 0 ] )
210- next unless match
211-
212- # now we return the first version, unless ensure is latest
213- version = match . captures [ 1 ]
214- return version unless @resource [ :ensure ] == "latest"
215-
216- master_version = version unless master_version > version
217- end
218-
219- return master_version unless master_version == 0
220- return '' if version == -1
221105
222- raise Puppet ::Error , _ ( "%{version} is not available for this package" ) % { version : version }
106+ if @resource [ :flavor ]
107+ "#{ use_name } --#{ @resource [ :flavor ] } #{ use_branch } "
108+ else
109+ "#{ use_name } --#{ use_branch } "
223110 end
224- rescue Puppet ::ExecutionFailure
225- nil
226111 end
227112
228113 def query
229- # Search for the version info
230- if pkginfo ( @resource [ :name ] ) =~ /Information for (inst:)?#{ @resource [ :name ] } -(\S +)/
231- { :ensure => Regexp . last_match ( 2 ) }
232- else
233- nil
114+ pkg = self . class . instances . find do |package |
115+ @resource [ :name ] == package . name
234116 end
117+ pkg ? pkg . properties : nil
235118 end
236119
237120 def install_options
238121 join_options ( resource [ :install_options ] )
239122 end
240123
241124 def uninstall_options
242- join_options ( resource [ :uninstall_options ] )
125+ join_options ( resource [ :uninstall_options ] ) || [ ]
243126 end
244127
245128 def uninstall
246- pkgdelete uninstall_options . flatten . compact , @resource [ :name ]
129+ pkgdelete uninstall_options . flatten . compact , get_full_name
247130 end
248131
249132 def purge
250- pkgdelete "-c" , "-q " , @resource [ :name ]
133+ pkgdelete "-c" , "-qq " , uninstall_options . flatten . compact , get_full_name
251134 end
252135
253136 def flavor
@@ -256,7 +139,6 @@ def flavor
256139
257140 def flavor = ( value )
258141 if flavor != @resource . should ( :flavor )
259- uninstall
260142 install
261143 end
262144 end
0 commit comments