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 
1216     string or a hash." 
1317
14-   commands  :pkginfo   =>  "pkg_info " , 
15-            :pkgadd   =>  "pkg_add " , 
18+   commands  :pkgadd   =>  "pkg_add " , 
19+            :pkginfo   =>  "pkg_info " , 
1620           :pkgdelete  =>  "pkg_delete" 
1721
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 
3030    packages  =  [ ] 
3131
3232    begin 
3333      execpipe ( listcmd )  do  |process |
3434        # 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  ] 
3737        hash  =  { } 
3838
3939        # now turn each returned line into a package object 
4040        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 
5259        } 
5360      end 
5461
@@ -59,168 +66,71 @@ def self.instances
5966  end 
6067
6168  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" ] 
10470  end 
10571
106-   def  update 
107-     install ( true ) 
108-   end 
109- 
110-   def  install ( latest  =  false ) 
72+   def  install 
11173    cmd  =  [ ] 
11274
75+     full_name  =  get_full_name 
76+ 
11377    cmd  << '-r' 
11478    cmd  << install_options 
115-     cmd  << get_full_name ( latest ) 
116- 
117-     if  latest 
118-       cmd . unshift ( '-z' ) 
119-     end 
79+     cmd  << full_name 
12080
12181    # pkg_add(1) doesn't set the return value upon failure so we have to peek 
12282    # at it's output to see if something went wrong. 
12383    output  =  Puppet ::Util . withenv ( { } )  {  pkgadd  cmd . flatten . compact  } 
124-     pp  output 
12584    if  output  =~ /Can't find / 
12685      self . fail  "pkg_add returned: #{ output . chomp }  " 
12786    end 
12887  end 
12988
130-   def  get_full_name ( latest   =   false ) 
89+   def  get_full_name 
13190    # In case of a real update (i.e., the package already exists) then 
13291    # pkg_add(8) can handle the flavors. However, if we're actually 
13392    # installing with 'latest', we do need to handle the flavors. This is 
13493    # done so we can feed pkg_add(8) the full package name to install to 
13594    # 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 
16795
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  =  '' 
174104    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" 
188105
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 }  " 
190110    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 
199111  end 
200112
201113  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 
207116    end 
117+     pkg  ? pkg . properties  : nil 
208118  end 
209119
210120  def  install_options 
211121    join_options ( resource [ :install_options ] ) 
212122  end 
213123
214124  def  uninstall_options 
215-     [ join_options ( resource [ :uninstall_options ] ) ] 
125+     join_options ( resource [ :uninstall_options ] )  ||  [ ] 
216126  end 
217127
218128  def  uninstall 
219-     pkgdelete  uninstall_options . flatten . compact ,  @resource [ :name ] 
129+     pkgdelete  uninstall_options . flatten . compact ,  get_full_name 
220130  end 
221131
222132  def  purge 
223-     pkgdelete  "-c" ,  "-q " ,  @resource [ :name ] 
133+     pkgdelete  "-c" ,  "-qq " ,  uninstall_options . flatten . compact ,   get_full_name 
224134  end 
225135
226136  def  flavor 
@@ -229,7 +139,6 @@ def flavor
229139
230140  def  flavor = ( value ) 
231141    if  flavor  != @resource . should ( :flavor ) 
232-       uninstall 
233142      install 
234143    end 
235144  end 
0 commit comments