=46rom=206405eb5e2b81191e7858084647d276d64bfe9bfd=20Mon=20Sep=2017=20=
00:00:00=202001=0AFrom:=20Udo=20Waechter=20=
<udo.waechter@uni-osnabrueck.de>=0ADate:=20Fri,=2024=20Jul=202009=20=
13:38:40=20+0200=0ASubject:=20[PATCH=201/2]=20added=20uninstall=20=
capabilities=0A=0ASigned-off-by:=20Udo=20Waechter=20=
<udo.waechter@uni-osnabrueck.de>=0A---=0A=20=
lib/puppet/provider/package/appdmg.rb=20|=20=20188=20=
+++++++++++++++++++--------------=0A=201=20files=20changed,=20110=20=
insertions(+),=2078=20deletions(-)=0A=0Adiff=20--git=20=
a/lib/puppet/provider/package/appdmg.rb=20=
b/lib/puppet/provider/package/appdmg.rb=0Aindex=20352f873..d334edc=20=
100644=0A---=20a/lib/puppet/provider/package/appdmg.rb=0A+++=20=
b/lib/puppet/provider/package/appdmg.rb=0A@@=20-13,102=20+13,134=20@@=0A=20=
#=20in=20/var/db/.puppet_appdmg_installed_<name>=0A=20=0A=20require=20=
'puppet/provider/package'=0A+require=20'yaml'=0A+require=20"FileUtils"=0A=
+=0A=20Puppet::Type.type(:package).provide(:appdmg,=20:parent=20=3D>=20=
Puppet::Provider::Package)=20do=0A-=20=20=20=20desc=20"Package=20=
management=20which=20copies=20application=20bundles=20to=20a=20target."=0A=
+=20=20desc=20"Package=20management=20which=20copies=20application=20=
bundles=20to=20a=20target."=0A+=20=20$appdmg_target=20=3D=20=
"/Applications"=0A+=20=20confine=20:operatingsystem=20=3D>=20:darwin=0A=20=
=0A-=20=20=20=20confine=20:operatingsystem=20=3D>=20:darwin=0A-=20=20=20=20=
=0A-=20=20=20=20commands=20:hdiutil=20=3D>=20"/usr/bin/hdiutil"=0A-=20=20=
=20=20commands=20:curl=20=3D>=20"/usr/bin/curl"=0A-=20=20=20=20commands=20=
:ditto=20=3D>=20"/usr/bin/ditto"=0A+=20=20commands=20:hdiutil=20=3D>=20=
"/usr/bin/hdiutil"=0A+=20=20commands=20:curl=20=3D>=20"/usr/bin/curl"=0A=
+=20=20commands=20:ditto=20=3D>=20"/usr/bin/ditto"=0A+=20=20#=20JJM=20We=20=
store=20a=20cookie=20for=20each=20installed=20.app.dmg=20in=20/var/db=0A=
+=20=20def=20self.instances_by_name=0A+=20=20=20=20=
Dir.entries("/var/db").find_all=20{=20|f|=0A+=20=20=20=20=20=20f=20=3D~=20=
/^\.puppet_appdmg_installed_/=0A+=20=20=20=20}.collect=20do=20|f|=0A+=20=20=
=20=20=20=20name=20=3D=20f.sub(/^\.puppet_appdmg_installed_/,=20'')=0A+=20=
=20=20=20=20=20yield=20name=20if=20block_given?=0A+=20=20=20=20=20=20=
name=0A+=20=20=20=20end=0A+=20=20end=0A=20=0A-=20=20=20=20#=20JJM=20We=20=
store=20a=20cookie=20for=20each=20installed=20.app.dmg=20in=20/var/db=0A=
-=20=20=20=20def=20self.instances_by_name=0A-=20=20=20=20=20=20=20=20=
Dir.entries("/var/db").find_all=20{=20|f|=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20f=20=3D~=20/^\.puppet_appdmg_installed_/=0A-=20=20=20=20=20=20=20=20=
}.collect=20do=20|f|=0A-=20=20=20=20=20=20=20=20=20=20=20=20name=20=3D=20=
f.sub(/^\.puppet_appdmg_installed_/,=20'')=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20yield=20name=20if=20block_given?=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20name=0A-=20=20=20=20=20=20=20=20end=0A+=20=20def=20self.instances=0A=
+=20=20=20=20instances_by_name.collect=20do=20|name|=0A+=20=20=20=20=20=20=
new(:name=20=3D>=20name,=20:provider=20=3D>=20:appdmg,=20:ensure=20=3D>=20=
:installed)=0A=20=20=20=20=20end=0A+=20=20end=0A=20=0A-=20=20=20=20def=20=
self.instances=0A-=20=20=20=20=20=20=20=20instances_by_name.collect=20do=20=
|name|=0A-=20=20=20=20=20=20=20=20=20=20=20=20new(:name=20=3D>=20name,=20=
:provider=20=3D>=20:appdmg,=20:ensure=20=3D>=20:installed)=0A-=20=20=20=20=
=20=20=20=20end=0A+=20=20def=20self.installapp(source,=20name,=20=
orig_source)=0A+=20=20=20=20appname=20=3D=20File.basename(source);=0A+=20=
=20=20=20ditto=20"--rsrc",=20source,=20"#{$appdmg_target}/#{appname}"=0A=
+=20=20=20=20dbfile=20=3D=20"/var/db/.puppet_appdmg_installed_#{name}"=0A=
+=20=20=20=20receipthash=20=3D=20{}=0A+=20=20=20=20receipthash["files"]=20=
=3D=20[]=0A+=20=20=20=20if=20File.exist?(dbfile)=0A+=20=20=20=20=20=20=
receipthash=20=3D=20YAML::load_file(dbfile)=0A=20=20=20=20=20end=0A+=20=20=
=20=20receipthash["name"]=20=3D=20name=0A+=20=20=20=20=
receipthash["source"]=20=3D=20orig_source=0A+=20=20=20=20=
receipthash["files"].include?(appname)=20or=20=
receipthash["files"].push(appname)=0A+=20=20=20=20f=20=3D=20=
File.open(dbfile,"w")=0A+=20=20=20=20f.print=20receipthash.to_yaml=0A+=20=
=20=20=20f.close=0A+=20=20end=0A=20=0A-=20=20=20=20def=20=
self.installapp(source,=20name,=20orig_source)=0A-=20=20=20=20=20=20=
appname=20=3D=20File.basename(source);=0A-=20=20=20=20=20=20ditto=20=
"--rsrc",=20source,=20"/Applications/#{appname}"=0A-=20=20=20=20=20=20=
File.open("/var/db/.puppet_appdmg_installed_#{name}",=20"w")=20do=20|t|=0A=
-=20=20=20=20=20=20=20=20=20=20t.print=20"name:=20'#{name}'\n"=0A-=20=20=20=
=20=20=20=20=20=20=20t.print=20"source:=20'#{orig_source}'\n"=0A+=20=20=
def=20self.uninstallappdmg(name)=0A+=20=20=20=20dbfile=20=3D=20=
"/var/db/.puppet_appdmg_installed_#{name}"=0A+=20=20=20=20unless=20=
File.exist?(dbfile)=0A+=20=20=20=20=20=20raise=20Puppet::Error.new("App=20=
DMG=20Package=20#{name}=20not=20installed.")=0A+=20=20=20=20end=0A+=20=20=
=20=20receipthash=20=3D=20YAML::load_file(dbfile)=0A+=20=20=20=20=
receipthash["files"].each=20do=20|appname|=0A+=20=20=20=20=20=20=
FileUtils.remove_entry_secure("#{$appdmg_target}/#{appname}")=0A+=20=20=20=
=20=20=20unless=20$?=20=3D=3D=200=0A+=20=20=20=20=20=20=20=20raise=20=
Puppet::Error.new("App=20DMG=20could=20not=20remove=20=
\"#{$appdmg_target}/#{appname}\"")=0A=20=20=20=20=20=20=20end=0A=20=20=20=
=20=20end=0A+=20=20=20=20File.unlink(dbfile)=0A+=20=20end=0A=20=0A-=20=20=
=20=20def=20self.installpkgdmg(source,=20name)=0A-=20=20=20=20=20=20=20=20=
unless=20source=20=3D~=20/\.dmg$/i=0A-=20=20=20=20=20=20=20=20=20=20=20=20=
self.fail=20"Mac=20OS=20X=20PKG=20DMG's=20must=20specificy=20a=20source=20=
string=20ending=20in=20.dmg"=0A-=20=20=20=20=20=20=20=20end=0A-=20=20=20=20=
=20=20=20=20require=20'open-uri'=0A-=20=20=20=20=20=20=20=20require=20=
'facter/util/plist'=0A+=20=20def=20self.installappdmg(source,=20name)=0A=
+=20=20=20=20unless=20source=20=3D~=20/\.dmg$/i=0A+=20=20=20=20=20=20=
raise=20Puppet::Error.new("Mac=20OS=20X=20app=20DMG's=20must=20specificy=20=
a=20source=20string=20ending=20in=20.dmg")=0A+=20=20=20=20end=0A+=20=20=20=
=20require=20'open-uri'=0A+=20=20=20=20require=20'facter/util/plist'=0A+=20=
=20=20=20cached_source=20=3D=20source=0A+=20=20=20=20if=20=
%r{\A[A-Za-z][A-Za-z0-9+\-\.]*://}=20=3D~=20cached_source=0A+=20=20=20=20=
=20=20cached_source=20=3D=20"/tmp/#{name}"=0A+=20=20=20=20=20=20begin=0A=
+=20=20=20=20=20=20=20=20curl=20"-o",=20cached_source,=20"-C",=20"-",=20=
"-k",=20"-s",=20"--url",=20source=0A+=20=20=20=20=20=20=20=20=
Puppet.debug=20"Success:=20curl=20transfered=20[#{name}]"=0A+=20=20=20=20=
=20=20rescue=20Puppet::ExecutionFailure=0A+=20=20=20=20=20=20=20=20=
Puppet.debug=20"curl=20did=20not=20transfer=20[#{name}].=20=20Falling=20=
back=20to=20slower=20open-uri=20transfer=20methods."=0A=20=20=20=20=20=20=
=20=20=20cached_source=20=3D=20source=0A-=20=20=20=20=20=20=20=20if=20=
%r{\A[A-Za-z][A-Za-z0-9+\-\.]*://}=20=3D~=20cached_source=0A-=20=20=20=20=
=20=20=20=20=20=20=20=20cached_source=20=3D=20"/tmp/#{name}"=0A-=20=20=20=
=20=20=20=20=20=20=20=20=20begin=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20curl=20"-o",=20cached_source,=20"-C",=20"-",=20"-k",=20"-s",=20=
"--url",=20source=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
Puppet.debug=20"Success:=20curl=20transfered=20[#{name}]"=0A-=20=20=20=20=
=20=20=20=20=20=20=20=20rescue=20Puppet::ExecutionFailure=0A-=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20Puppet.debug=20"curl=20did=20not=20=
transfer=20[#{name}].=20=20Falling=20back=20to=20slower=20open-uri=20=
transfer=20methods."=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
cached_source=20=3D=20source=0A-=20=20=20=20=20=20=20=20=20=20=20=20end=0A=
-=20=20=20=20=20=20=20=20end=0A+=20=20=20=20=20=20end=0A+=20=20=20=20end=0A=
=20=0A+=20=20=20=20begin=0A+=20=20=20=20=20=20open(cached_source)=20do=20=
|dmg|=0A+=20=20=20=20=20=20=20=20xml_str=20=3D=20hdiutil=20"mount",=20=
"-plist",=20"-nobrowse",=20"-readonly",=20"-mountrandom",=20"/tmp",=20=
dmg.path=0A+=20=20=20=20=20=20=20=20ptable=20=3D=20Plist::parse_xml=20=
xml_str=0A+=20=20=20=20=20=20=20=20#=20JJM=20Filter=20out=20all=20=
mount-paths=20into=20a=20single=20array,=20discard=20the=20rest.=0A+=20=20=
=20=20=20=20=20=20mounts=20=3D=20ptable['system-entities'].collect=20{=20=
|entity|=0A+=20=20=20=20=20=20=20=20=20=20entity['mount-point']=0A+=20=20=
=20=20=20=20=20=20}.select=20{=20|mountloc|;=20mountloc=20}=0A=20=20=20=20=
=20=20=20=20=20begin=0A-=20=20=20=20=20=20=20=20=20=20=20=20=
open(cached_source)=20do=20|dmg|=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20xml_str=20=3D=20hdiutil=20"mount",=20"-plist",=20"-nobrowse",=20=
"-readonly",=20"-mountrandom",=20"/tmp",=20dmg.path=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20ptable=20=3D=20=
Plist::parse_xml=20xml_str=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20#=20JJM=20Filter=20out=20all=20mount-paths=20into=20a=20=
single=20array,=20discard=20the=20rest.=0A-=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20mounts=20=3D=20=
ptable['system-entities'].collect=20{=20|entity|=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20entity['mount-point']=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20}.select=20=
{=20|mountloc|;=20mountloc=20}=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20begin=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20mounts.each=20do=20|fspath|=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
Dir.entries(fspath).select=20{=20|f|=0A-=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20f=20=3D~=20=
/\.app$/i=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20}.each=20do=20|pkg|=0A-=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
installapp("#{fspath}/#{pkg}",=20name,=20source)=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20end=0A-=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20end=20=
#=20mounts.each=20do=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20ensure=0A-=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20hdiutil=20"eject",=20mounts[0]=0A-=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20end=20#=20begin=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20end=20#=20open()=20do=0A+=20=20=20=20=20=20=20=20=20=
=20mounts.each=20do=20|fspath|=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
Dir.entries(fspath).select=20{=20|f|=0A+=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20f=20=3D~=20/\.app$/i=0A+=20=20=20=20=20=20=20=20=20=20=20=20=
}.each=20do=20|app|=0A+=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
installapp("#{fspath}/#{app}",=20name,=20source)=0A+=20=20=20=20=20=20=20=
=20=20=20=20=20end=0A+=20=20=20=20=20=20=20=20=20=20end=20#=20=
mounts.each=20do=0A=20=20=20=20=20=20=20=20=20ensure=0A-=20=20=20=20=20=20=
=20=20=20=20=20=20#=20JJM=20Remove=20the=20file=20if=20open-uri=20didn't=20=
already=20do=20so.=0A-=20=20=20=20=20=20=20=20=20=20=20=20=
File.unlink(cached_source)=20if=20File.exist?(cached_source)=0A+=20=20=20=
=20=20=20=20=20=20=20hdiutil=20"eject",=20mounts[0]=0A=20=20=20=20=20=20=20=
=20=20end=20#=20begin=0A-=20=20=20=20end=20#=20def=20self.installpkgdmg=0A=
+=20=20=20=20=20=20end=20#=20open()=20do=0A+=20=20=20=20ensure=0A+=20=20=20=
=20=20=20#=20JJM=20Remove=20the=20file=20if=20open-uri=20didn't=20=
already=20do=20so.=0A+=20=20=20=20=20=20File.unlink(cached_source)=20if=20=
File.exist?(cached_source)=0A+=20=20=20=20end=20#=20begin=0A+=20=20end=20=
#=20def=20self.installappdmg=0A=20=0A-=20=20=20=20def=20query=0A-=20=20=20=
=20=20=20=20=20if=20=
FileTest.exists?("/var/db/.puppet_appdmg_installed_#{@resource[:name]}")=0A=
-=20=20=20=20=20=20=20=20=20=20=20=20return=20{:name=20=3D>=20=
@resource[:name],=20:ensure=20=3D>=20:present}=0A-=20=20=20=20=20=20=20=20=
else=0A-=20=20=20=20=20=20=20=20=20=20=20=20return=20nil=0A-=20=20=20=20=20=
=20=20=20end=0A+=20=20def=20query=0A+=20=20=20=20if=20=
FileTest.exists?("/var/db/.puppet_appdmg_installed_#{@resource[:name]}")=0A=
+=20=20=20=20=20=20return=20{:name=20=3D>=20@resource[:name],=20:ensure=20=
=3D>=20:present}=0A+=20=20=20=20else=0A+=20=20=20=20=20=20return=20nil=0A=
+=20=20=20=20end=0A+=20=20end=0A+=0A+=20=20def=20install=0A+=20=20=20=20=
source=20=3D=20nil=0A+=20=20=20=20unless=20source=20=3D=20=
@resource[:source]=0A+=20=20=20=20=20=20raise=20Puppet::Error.new("Mac=20=
OS=20X=20app=20DMG's=20must=20specify=20a=20package=20source.")=0A+=20=20=
=20=20end=0A+=20=20=20=20unless=20name=20=3D=20@resource[:name]=0A+=20=20=
=20=20=20=20raise=20Puppet::Error.new("Mac=20OS=20X=20app=20DMG's=20must=20=
specify=20a=20package=20name.")=0A=20=20=20=20=20end=0A+=20=20=20=20=
self.class.installappdmg(source,name)=0A+=20=20end=0A=20=0A-=20=20=20=20=
def=20install=0A-=20=20=20=20=20=20=20=20source=20=3D=20nil=0A-=20=20=20=20=
=20=20=20=20unless=20source=20=3D=20@resource[:source]=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20self.fail=20"Mac=20OS=20X=20PKG=20DMG's=20must=20=
specify=20a=20package=20source."=0A-=20=20=20=20=20=20=20=20end=0A-=20=20=
=20=20=20=20=20=20unless=20name=20=3D=20@resource[:name]=0A-=20=20=20=20=20=
=20=20=20=20=20=20=20self.fail=20"Mac=20OS=20X=20PKG=20DMG's=20must=20=
specify=20a=20package=20name."=0A-=20=20=20=20=20=20=20=20end=0A-=20=20=20=
=20=20=20=20=20self.class.installpkgdmg(source,name)=0A+=20=20def=20=
uninstall=0A+=20=20=20=20unless=20name=20=3D=20@resource[:name]=0A+=20=20=
=20=20=20=20raise=20Puppet::Error.new("Mac=20OS=20X=20app=20DMG's=20must=20=
specify=20a=20package=20name.")=0A=20=20=20=20=20end=0A+=20=20=20=20=
self.class.uninstallappdmg(name)=0A+=20=20end=0A=20end=0A=20=0A--=20=0A=
1.6.3.3=0A=0A=
