6
6
Puppet ::Type . type ( :package ) . provide :openbsd , :parent => Puppet ::Provider ::Package do
7
7
desc "OpenBSD's form of `pkg_add` support.
8
8
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
+
9
13
This provider supports the `install_options` and `uninstall_options`
10
14
attributes, which allow command-line flags to be passed to pkg_add and pkg_delete.
11
15
These options should be specified as an array where each element is either a
12
16
string or a hash."
13
17
14
- commands :pkginfo => "pkg_info " ,
15
- :pkgadd => "pkg_add " ,
18
+ commands :pkgadd => "pkg_add " ,
19
+ :pkginfo => "pkg_info " ,
16
20
:pkgdelete => "pkg_delete"
17
21
18
22
defaultfor 'os.name' => :openbsd
19
23
confine 'os.name' => :openbsd
20
24
21
- has_feature :versionable
22
25
has_feature :install_options
23
26
has_feature :uninstall_options
24
- has_feature :upgradeable
25
27
has_feature :supports_flavors
26
28
27
- mk_resource_methods
28
-
29
29
def self . instances
30
30
packages = [ ]
31
31
32
32
begin
33
33
execpipe ( listcmd ) do |process |
34
34
# our regex for matching pkg_info output
35
- regex = /^(.*)-( \d [^-]*)-?([ \w -]*)(.*) $/
36
- fields = [ :name , :ensure , :flavor ]
35
+ regex = /^(.*)--([ \w -]+)?(%[^w]+)? $/
36
+ fields = [ :name , :flavor , :branch ]
37
37
hash = { }
38
38
39
39
# now turn each returned line into a package object
40
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
- }
47
-
48
- hash [ :provider ] = name
49
-
50
- packages << new ( hash )
51
- hash = { }
41
+ match = regex . match ( line . split ( "\n " ) [ 0 ] )
42
+ if match
43
+ fields . zip ( match . captures ) { |field , value |
44
+ hash [ field ] = value
45
+ }
46
+
47
+ hash [ :name ] = "#{ hash [ :name ] } #{ hash [ :branch ] } " if hash [ :branch ]
48
+
49
+ hash [ :provider ] = name
50
+ packages << new ( hash )
51
+ hash = { }
52
+ else
53
+ unless line =~ /Updating the pkgdb/
54
+ # Print a warning on lines we can't match, but move
55
+ # on, since it should be non-fatal
56
+ warning ( _ ( "Failed to match line %{line}" ) % { line : line } )
57
+ end
58
+ end
52
59
}
53
60
end
54
61
@@ -59,168 +66,71 @@ def self.instances
59
66
end
60
67
61
68
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
103
- end
69
+ [ command ( :pkginfo ) , "-a" , "-z" ]
104
70
end
105
71
106
- def update
107
- install ( true )
108
- end
109
-
110
- def install ( latest = false )
72
+ def install
111
73
cmd = [ ]
112
74
75
+ full_name = get_full_name
76
+
113
77
cmd << '-r'
114
78
cmd << install_options
115
- cmd << get_full_name ( latest )
116
-
117
- if latest
118
- cmd . unshift ( '-z' )
119
- end
79
+ cmd << full_name
120
80
121
81
# pkg_add(1) doesn't set the return value upon failure so we have to peek
122
82
# at it's output to see if something went wrong.
123
83
output = Puppet ::Util . withenv ( { } ) { pkgadd cmd . flatten . compact }
124
- pp output
125
84
if output =~ /Can't find /
126
85
self . fail "pkg_add returned: #{ output . chomp } "
127
86
end
128
87
end
129
88
130
- def get_full_name ( latest = false )
89
+ def get_full_name
131
90
# In case of a real update (i.e., the package already exists) then
132
91
# pkg_add(8) can handle the flavors. However, if we're actually
133
92
# installing with 'latest', we do need to handle the flavors. This is
134
93
# done so we can feed pkg_add(8) the full package name to install to
135
94
# 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
167
95
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 << "--"
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 = ''
174
104
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 ] ) )
184
-
185
- # now we return the first version, unless ensure is latest
186
- version = match . captures [ 1 ]
187
- return version unless @resource [ :ensure ] == "latest"
188
105
189
- master_version = version unless master_version > version
106
+ if @resource [ :flavor ]
107
+ "#{ use_name } --#{ @resource [ :flavor ] } #{ use_branch } "
108
+ else
109
+ "#{ use_name } --#{ use_branch } "
190
110
end
191
-
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
199
111
end
200
112
201
113
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
114
+ pkg = self . class . instances . find do |package |
115
+ @resource [ :name ] == package . name
207
116
end
117
+ pkg ? pkg . properties : nil
208
118
end
209
119
210
120
def install_options
211
121
join_options ( resource [ :install_options ] )
212
122
end
213
123
214
124
def uninstall_options
215
- [ join_options ( resource [ :uninstall_options ] ) ]
125
+ join_options ( resource [ :uninstall_options ] ) || [ ]
216
126
end
217
127
218
128
def uninstall
219
- pkgdelete uninstall_options . flatten . compact , @resource [ :name ]
129
+ pkgdelete uninstall_options . flatten . compact , get_full_name
220
130
end
221
131
222
132
def purge
223
- pkgdelete "-c" , "-q " , @resource [ :name ]
133
+ pkgdelete "-c" , "-qq " , uninstall_options . flatten . compact , get_full_name
224
134
end
225
135
226
136
def flavor
@@ -229,7 +139,6 @@ def flavor
229
139
230
140
def flavor = ( value )
231
141
if flavor != @resource . should ( :flavor )
232
- uninstall
233
142
install
234
143
end
235
144
end
0 commit comments