vanagon 0.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +13 -0
  3. data/README.md +175 -0
  4. data/bin/build +33 -0
  5. data/bin/devkit +22 -0
  6. data/bin/repo +26 -0
  7. data/bin/ship +15 -0
  8. data/lib/vanagon.rb +8 -0
  9. data/lib/vanagon/common.rb +2 -0
  10. data/lib/vanagon/common/pathname.rb +87 -0
  11. data/lib/vanagon/common/user.rb +25 -0
  12. data/lib/vanagon/component.rb +157 -0
  13. data/lib/vanagon/component/dsl.rb +307 -0
  14. data/lib/vanagon/component/source.rb +66 -0
  15. data/lib/vanagon/component/source/git.rb +60 -0
  16. data/lib/vanagon/component/source/http.rb +158 -0
  17. data/lib/vanagon/driver.rb +112 -0
  18. data/lib/vanagon/engine/base.rb +82 -0
  19. data/lib/vanagon/engine/docker.rb +40 -0
  20. data/lib/vanagon/engine/local.rb +40 -0
  21. data/lib/vanagon/engine/pooler.rb +85 -0
  22. data/lib/vanagon/errors.rb +28 -0
  23. data/lib/vanagon/extensions/string.rb +11 -0
  24. data/lib/vanagon/optparse.rb +62 -0
  25. data/lib/vanagon/platform.rb +245 -0
  26. data/lib/vanagon/platform/deb.rb +71 -0
  27. data/lib/vanagon/platform/dsl.rb +293 -0
  28. data/lib/vanagon/platform/osx.rb +100 -0
  29. data/lib/vanagon/platform/rpm.rb +76 -0
  30. data/lib/vanagon/platform/rpm/wrl.rb +39 -0
  31. data/lib/vanagon/platform/solaris_10.rb +182 -0
  32. data/lib/vanagon/platform/solaris_11.rb +138 -0
  33. data/lib/vanagon/platform/swix.rb +35 -0
  34. data/lib/vanagon/project.rb +251 -0
  35. data/lib/vanagon/project/dsl.rb +218 -0
  36. data/lib/vanagon/utilities.rb +299 -0
  37. data/spec/fixures/component/invalid-test-fixture.json +3 -0
  38. data/spec/fixures/component/mcollective.service +1 -0
  39. data/spec/fixures/component/test-fixture.json +4 -0
  40. data/spec/lib/vanagon/common/pathname_spec.rb +103 -0
  41. data/spec/lib/vanagon/common/user_spec.rb +36 -0
  42. data/spec/lib/vanagon/component/dsl_spec.rb +443 -0
  43. data/spec/lib/vanagon/component/source/git_spec.rb +19 -0
  44. data/spec/lib/vanagon/component/source/http_spec.rb +43 -0
  45. data/spec/lib/vanagon/component/source_spec.rb +99 -0
  46. data/spec/lib/vanagon/component_spec.rb +22 -0
  47. data/spec/lib/vanagon/engine/base_spec.rb +40 -0
  48. data/spec/lib/vanagon/engine/docker_spec.rb +40 -0
  49. data/spec/lib/vanagon/engine/pooler_spec.rb +54 -0
  50. data/spec/lib/vanagon/platform/deb_spec.rb +60 -0
  51. data/spec/lib/vanagon/platform/dsl_spec.rb +128 -0
  52. data/spec/lib/vanagon/platform/rpm_spec.rb +41 -0
  53. data/spec/lib/vanagon/platform/solaris_11_spec.rb +44 -0
  54. data/spec/lib/vanagon/platform_spec.rb +53 -0
  55. data/spec/lib/vanagon/project/dsl_spec.rb +203 -0
  56. data/spec/lib/vanagon/project_spec.rb +44 -0
  57. data/spec/lib/vanagon/utilities_spec.rb +140 -0
  58. data/templates/Makefile.erb +116 -0
  59. data/templates/deb/changelog.erb +5 -0
  60. data/templates/deb/conffiles.erb +3 -0
  61. data/templates/deb/control.erb +21 -0
  62. data/templates/deb/dirs.erb +3 -0
  63. data/templates/deb/docs.erb +1 -0
  64. data/templates/deb/install.erb +3 -0
  65. data/templates/deb/postinst.erb +46 -0
  66. data/templates/deb/postrm.erb +15 -0
  67. data/templates/deb/prerm.erb +17 -0
  68. data/templates/deb/rules.erb +25 -0
  69. data/templates/osx/postinstall.erb +24 -0
  70. data/templates/osx/preinstall.erb +19 -0
  71. data/templates/osx/project-installer.xml.erb +19 -0
  72. data/templates/rpm/project.spec.erb +217 -0
  73. data/templates/solaris/10/depend.erb +3 -0
  74. data/templates/solaris/10/pkginfo.erb +13 -0
  75. data/templates/solaris/10/postinstall.erb +37 -0
  76. data/templates/solaris/10/preinstall.erb +7 -0
  77. data/templates/solaris/10/preremove.erb +6 -0
  78. data/templates/solaris/10/proto.erb +5 -0
  79. data/templates/solaris/11/p5m.erb +73 -0
  80. metadata +172 -0
@@ -0,0 +1,100 @@
1
+ class Vanagon
2
+ class Platform
3
+ class OSX < Vanagon::Platform
4
+ # The specific bits used to generate a osx package for a given project
5
+ #
6
+ # @param project [Vanagon::Project] project to build a osx package of
7
+ # @return [Array] list of commands required to build a osx package for the given project from a tarball
8
+ def generate_package(project)
9
+ target_dir = project.repo ? output_dir(project.repo) : output_dir
10
+ # Setup build directories
11
+ ["bash -c 'mkdir -p $(tempdir)/osx/build/{dmg,pkg,scripts,resources,root,payload,plugins}'",
12
+ "mkdir -p $(tempdir)/osx/build/root/#{project.name}-#{project.version}",
13
+ # Grab distribution xml, scripts and other external resources
14
+ "cp #{project.name}-installer.xml $(tempdir)/osx/build/",
15
+ "cp scripts/* $(tempdir)/osx/build/scripts/",
16
+ "if [ -d resources/osx/productbuild ] ; then cp -r resources/osx/productbuild/* $(tempdir)/osx/build/; fi",
17
+ # Unpack the project
18
+ "gunzip -c #{project.name}-#{project.version}.tar.gz | '#{@tar}' -C '$(tempdir)/osx/build/root/#{project.name}-#{project.version}' --strip-components 1 -xf -",
19
+
20
+ # Move bill-of-materials into a docdir
21
+ "mkdir -p $(tempdir)/osx/build/root/#{project.name}-#{project.version}/usr/local/share/doc/#{project.name}",
22
+ "mv $(tempdir)/osx/build/root/#{project.name}-#{project.version}/bill-of-materials $(tempdir)/osx/build/root/#{project.name}-#{project.version}/usr/local/share/doc/#{project.name}/bill-of-materials",
23
+
24
+ # Package the project
25
+ "(cd $(tempdir)/osx/build/; #{@pkgbuild} --root root/#{project.name}-#{project.version} \
26
+ --scripts $(tempdir)/osx/build/scripts \
27
+ --identifier #{project.identifier}.#{project.name} \
28
+ --version #{project.version} \
29
+ --install-location / \
30
+ payload/#{project.name}-#{project.version}-#{project.release}.pkg)",
31
+ # Create a custom installer using the pkg above
32
+ "(cd $(tempdir)/osx/build/; #{@productbuild} --distribution #{project.name}-installer.xml \
33
+ --identifier #{project.identifier}.#{project.name}-installer \
34
+ --package-path payload/ \
35
+ --resources $(tempdir)/osx/build/resources \
36
+ --plugins $(tempdir)/osx/build/plugins \
37
+ pkg/#{project.name}-#{project.version}-#{project.release}-installer.pkg)",
38
+ # Create a dmg and ship it to the output dir
39
+ "(cd $(tempdir)/osx/build/; #{@hdiutil} create -volname #{project.name}-#{project.version} \
40
+ -srcfolder pkg/ dmg/#{project.package_name})",
41
+ "mkdir -p output/#{target_dir}",
42
+ "cp $(tempdir)/osx/build/dmg/#{project.package_name} ./output/#{target_dir}"]
43
+ end
44
+
45
+ # Method to generate the files required to build a osx package for the project
46
+ #
47
+ # @param workdir [String] working directory to stage the evaluated templates in
48
+ # @param name [String] name of the project
49
+ # @param binding [Binding] binding to use in evaluating the packaging templates
50
+ def generate_packaging_artifacts(workdir, name, binding)
51
+ resources_dir = File.join(workdir, "resources", "osx")
52
+ FileUtils.mkdir_p(resources_dir)
53
+ script_dir = File.join(workdir, "scripts")
54
+ FileUtils.mkdir_p(script_dir)
55
+
56
+ erb_file(File.join(VANAGON_ROOT, "templates/osx/project-installer.xml.erb"), File.join(workdir, "#{name}-installer.xml"), false, { :binding => binding })
57
+
58
+ ["postinstall", "preinstall"].each do |script_file|
59
+ erb_file(File.join(VANAGON_ROOT, "templates/osx/#{script_file}.erb"), File.join(script_dir, script_file), false, { :binding => binding })
60
+ FileUtils.chmod 0755, File.join(script_dir, script_file)
61
+ end
62
+
63
+ # Probably a better way to do this, but OSX tends to need some extra stuff
64
+ FileUtils.cp_r("resources/osx/.", resources_dir) if File.exist?("resources/osx/")
65
+ end
66
+
67
+ # Method to derive the package name for the project
68
+ #
69
+ # @param project [Vanagon::Project] project to name
70
+ # @return [String] name of the osx package for this project
71
+ def package_name(project)
72
+ "#{project.name}-#{project.version}-#{project.release}.#{@os_name}#{@os_version}.dmg"
73
+ end
74
+
75
+ # Get the expected output dir for the osx packages. This allows us to
76
+ # use some standard tools to ship internally.
77
+ #
78
+ # @return [String] relative path to where osx packages should be staged
79
+ def output_dir(target_repo = "")
80
+ File.join("apple", @os_version, target_repo, @architecture)
81
+ end
82
+
83
+ # Constructor. Sets up some defaults for the osx platform and calls the parent constructor
84
+ #
85
+ # @param name [String] name of the platform
86
+ # @return [Vanagon::Platform::OSX] the osx derived platform with the given name
87
+ def initialize(name)
88
+ @name = name
89
+ @make = "/usr/bin/make"
90
+ @tar = "tar"
91
+ @pkgbuild = "/usr/bin/pkgbuild"
92
+ @productbuild = "/usr/bin/productbuild"
93
+ @hdiutil = "/usr/bin/hdiutil"
94
+ @patch = "/usr/bin/patch"
95
+ @num_cores = "/usr/sbin/sysctl -n hw.physicalcpu"
96
+ super(name)
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,76 @@
1
+ require 'vanagon/utilities'
2
+ include Vanagon::Utilities
3
+
4
+ class Vanagon
5
+ class Platform
6
+ class RPM < Vanagon::Platform
7
+ # The specific bits used to generate an rpm package for a given project
8
+ #
9
+ # @param project [Vanagon::Project] project to build an rpm package of
10
+ # @return [Array] list of commands required to build an rpm package for the given project from a tarball
11
+ def generate_package(project)
12
+ target_dir = project.repo ? output_dir(project.repo) : output_dir
13
+ ["bash -c 'mkdir -p $(tempdir)/rpmbuild/{SOURCES,SPECS,BUILD,RPMS,SRPMS}'",
14
+ "cp #{project.name}-#{project.version}.tar.gz $(tempdir)/rpmbuild/SOURCES",
15
+ "cp file-list-for-rpm $(tempdir)/rpmbuild/SOURCES",
16
+ "cp #{project.name}.spec $(tempdir)/rpmbuild/SPECS",
17
+ "PATH=/opt/freeware/bin:$$PATH #{@rpmbuild} -bb --target #{@architecture} #{rpm_defines} $(tempdir)/rpmbuild/SPECS/#{project.name}.spec",
18
+ "mkdir -p output/#{target_dir}",
19
+ "cp $(tempdir)/rpmbuild/*RPMS/**/*.rpm ./output/#{target_dir}"]
20
+ end
21
+
22
+ # Method to generate the files required to build an rpm package for the project
23
+ #
24
+ # @param workdir [String] working directory to stage the evaluated templates in
25
+ # @param name [String] name of the project
26
+ # @param binding [Binding] binding to use in evaluating the packaging templates
27
+ def generate_packaging_artifacts(workdir, name, binding)
28
+ erb_file(File.join(VANAGON_ROOT, "templates/rpm/project.spec.erb"), File.join(workdir, "#{name}.spec"), false, { :binding => binding })
29
+ end
30
+
31
+ # Method to derive the package name for the project
32
+ #
33
+ # @param project [Vanagon::Project] project to name
34
+ # @return [String] name of the rpm package for this project
35
+ def package_name(project)
36
+ "#{project.name}-#{project.version}-#{project.release}.#{project.noarch ? 'noarch' : @architecture}.rpm"
37
+ end
38
+
39
+ # Get the expected output dir for the rpm packages. This allows us to
40
+ # use some standard tools to ship internally.
41
+ #
42
+ # @return [String] relative path to where rpm packages should be staged
43
+ def output_dir(target_repo = "products")
44
+ File.join(@os_name, @os_version, target_repo, @architecture)
45
+ end
46
+
47
+ def rpm_defines
48
+ defines = %(--define '_topdir $(tempdir)/rpmbuild' )
49
+ # RPM doesn't allow dashes in the os_name. This was added to
50
+ # convert cisco-wrlinux to cisco_wrlinux
51
+ unless is_aix?
52
+ defines << %(--define 'dist .#{@os_name.gsub('-', '_')}#{@os_version}' )
53
+ end
54
+ defines
55
+ end
56
+
57
+ # Constructor. Sets up some defaults for the rpm platform and calls the parent constructor
58
+ #
59
+ # @param name [String] name of the platform
60
+ # @return [Vanagon::Platform::RPM] the rpm derived platform with the given name
61
+ def initialize(name)
62
+ @name = name
63
+ @make = "/usr/bin/make"
64
+ @tar = "tar"
65
+ @patch = "/usr/bin/patch"
66
+ @num_cores = "/bin/grep -c 'processor' /proc/cpuinfo"
67
+ if is_aix?
68
+ @num_cores = "lsdev -Cc processor |wc -l"
69
+ @install = "/opt/freeware/bin/install"
70
+ end
71
+ @rpmbuild = "/usr/bin/rpmbuild"
72
+ super(name)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,39 @@
1
+ # This platform definition was created to account for oddities with
2
+ # the RPM available on WindRiver Linux based systems. WRL uses RPMv5
3
+ # and some of the WRL-based OS platforms we support (e.g, HuaweiOS)
4
+ # do not have package repo systems or support for installing remote
5
+ # RPMs via urls
6
+ class Vanagon
7
+ class Platform
8
+ class RPM
9
+ class WRL < Vanagon::Platform::RPM
10
+ # Some WRL RPM platforms (e.g, HuaweiOS) don't allow you to
11
+ # install remote packages via url, so we'll do a dance to
12
+ # download them via curl and then perform the installs locally.
13
+ # This method generates a shell script to be executed on the
14
+ # system to do this.
15
+ #
16
+ # @param build_dependencies [Array] list of all build dependencies to install
17
+ # @return [String] a command to install all of the build dependencies
18
+ def install_build_dependencies(build_dependencies)
19
+ commands = []
20
+ unless build_dependencies.empty?
21
+ commands << "tmpdir=$(mktemp -p /var/tmp -d)"
22
+ commands << "cd ${tmpdir}"
23
+ build_dependencies.each do |build_dependency|
24
+ if build_dependency.match(/^http.*\.rpm$/)
25
+ # We're downloading each package individually so
26
+ # failures are easier to troubleshoot
27
+ commands << %(curl --remote-name --location --fail --silent #{build_dependency} && echo "Successfully downloaded #{build_dependency}")
28
+ end
29
+ end
30
+ # Install the downloaded packages
31
+ commands << "rpm -Uvh --nodeps --replacepkgs ${tmpdir}/*.rpm"
32
+ end
33
+
34
+ commands.join(' && ')
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,182 @@
1
+ class Vanagon
2
+ class Platform
3
+ class Solaris10 < Vanagon::Platform
4
+ # The specific bits used to generate a solaris package for a given project
5
+ #
6
+ # @param project [Vanagon::Project] project to build a solaris package of
7
+ # @return [Array] list of commands required to build a solaris package for the given project from a tarball
8
+ def generate_package(project)
9
+ target_dir = project.repo ? output_dir(project.repo) : output_dir
10
+ name_and_version = "#{project.name}-#{project.version}"
11
+ pkg_name = package_name(project)
12
+
13
+ [
14
+ # Set up our needed directories
15
+ "mkdir -p $(tempdir)/#{name_and_version}",
16
+ "mkdir -p $(tempdir)/pkg",
17
+ "mkdir -p output/#{target_dir}",
18
+
19
+ # Unpack the project and stage the packaging artifacts
20
+ "gunzip -c #{name_and_version}.tar.gz | '#{@tar}' -C '$(tempdir)' -xf -",
21
+
22
+ # Move bill-of-materials into a docdir
23
+ "mkdir -p $(tempdir)/#{name_and_version}/usr/share/doc/#{project.name}",
24
+ "mv $(tempdir)/#{name_and_version}/bill-of-materials $(tempdir)/#{name_and_version}/usr/share/doc/#{project.name}/bill-of-materials",
25
+
26
+ "rm #{name_and_version}.tar.gz",
27
+ "cp -r packaging $(tempdir)/",
28
+
29
+ # Here we are tweaking file/dir ownership and perms in the following ways
30
+ # - All directories default to 0755 and root:sys
31
+ # - All files default to root:sys
32
+ # - The bin directory and all bin files are owned by root:bin instead of root:sys
33
+ # - All files under lib are owned by root:bin instead of root:sys
34
+ # - All .so files are owned by root:bin instead of root:sys
35
+ %((cd $(tempdir)/#{name_and_version}; pkgproto . | sort | awk ' \
36
+ $$1 ~ /^d$$/ {print "d",$$2,$$3,"0755 root sys";} \
37
+ $$1 ~ /^s$$/ {print;} \
38
+ $$1 ~ /^f$$/ {print "f",$$2,$$3,$$4,"root sys";} \
39
+ $$1 !~ /^[dfs]$$/ {print;} ' | /opt/csw/bin/gsed \
40
+ -e '/^[fd] [^ ]\\+ .*[/]s\\?bin/ {s/root sys$$/root bin/}' \
41
+ -e '/^[fd] [^ ]\\+ .*[/]lib[/][^/ ]\\+ / {s/root sys$$/root bin/}' \
42
+ -e '/^[fd] [^ ]\\+ .*[/][^ ]\\+[.]so / {s/root sys$$/root bin/}' >> ../packaging/proto) ),
43
+ %((cd $(tempdir); #{project.get_directories.map { |dir| "/opt/csw/bin/ggrep -q 'd none #{dir.path.sub(/^\//, '')}' packaging/proto || echo 'd none #{dir.path.sub(/^\//, '')} #{dir.mode || '0755'} #{dir.owner || 'root'} #{dir.group || 'sys'}' >> packaging/proto" }.join('; ')})),
44
+
45
+ # Actually build the package
46
+ "pkgmk -f $(tempdir)/packaging/proto -b $(tempdir)/#{name_and_version} -o -d $(tempdir)/pkg/",
47
+ "pkgtrans -s $(tempdir)/pkg/ $(tempdir)/pkg/#{pkg_name.gsub(/\.gz$/, '')} #{project.name}",
48
+ "gzip -c $(tempdir)/pkg/#{pkg_name.gsub(/\.gz$/, '')} > output/#{target_dir}/#{pkg_name}",
49
+ ]
50
+ end
51
+
52
+ # Method to generate the files required to build a solaris package for the project
53
+ #
54
+ # @param workdir [String] working directory to stage the evaluated templates in
55
+ # @param name [String] name of the project
56
+ # @param binding [Binding] binding to use in evaluating the packaging templates
57
+ def generate_packaging_artifacts(workdir, name, binding)
58
+ ["pkginfo", "depend", "preinstall", "preremove", "postinstall", "proto"].each do |template|
59
+ target_dir = File.join(workdir, 'packaging')
60
+ FileUtils.mkdir_p(target_dir)
61
+ erb_file(File.join(VANAGON_ROOT, "templates/solaris/10/#{template}.erb"), File.join(target_dir, template), false, { :binding => binding })
62
+ end
63
+ end
64
+
65
+ # Generate the scripts required to add a group to the package generated.
66
+ # This will also update the group if it has changed.
67
+ #
68
+ # @param user [Vanagon::Common::User] the user to reference for the group
69
+ # @return [String] the commands required to add a group to the system
70
+ def add_group(user)
71
+ # NB: system users aren't supported on solaris 10
72
+ return <<-HERE.undent
73
+ if ! getent group '#{user.group}' > /dev/null 2>&1; then
74
+ /usr/sbin/groupadd '#{user.group}'
75
+ fi
76
+ HERE
77
+ end
78
+
79
+ # Generate the scripts required to add a user to the package generated.
80
+ # This will also update the user if it has changed.
81
+ #
82
+ # @param user [Vanagon::Common::User] the user to create
83
+ # @return [String] the commands required to add a user to the system
84
+ def add_user(user)
85
+ # NB: system users aren't supported on solaris 10
86
+ # Solaris 10 also doesn't support long flags
87
+ cmd_args = ["'#{user.name}'"]
88
+ cmd_args.unshift "-g '#{user.group}'" if user.group
89
+ cmd_args.unshift "-d '#{user.homedir}'" if user.homedir
90
+ if user.shell
91
+ cmd_args.unshift "-s '#{user.shell}'"
92
+ elsif user.is_system
93
+ # Even though system users aren't a thing, we can still disable the shell
94
+ cmd_args.unshift "-s '/usr/bin/false'"
95
+ end
96
+
97
+ user_args = cmd_args.join("\s")
98
+
99
+ return <<-HERE.undent
100
+ if getent passwd '#{user.name}' > /dev/null 2>&1; then
101
+ /usr/sbin/usermod #{user_args}
102
+ else
103
+ /usr/sbin/useradd #{user_args}
104
+ fi
105
+ HERE
106
+ end
107
+
108
+ # Method to derive the package name for the project
109
+ #
110
+ # @param project [Vanagon::Project] project to name
111
+ # @return [String] name of the solaris package for this project
112
+ def package_name(project)
113
+ "#{project.name}-#{project.version}-#{project.release}.#{@architecture}.pkg.gz"
114
+ end
115
+
116
+ # Get the expected output dir for the solaris 10 packages. This allows us to
117
+ # use some standard tools to ship internally.
118
+ #
119
+ # @return [String] relative path to where solaris 10 packages should be staged
120
+ def output_dir(target_repo = "")
121
+ File.join("solaris", @os_version, target_repo)
122
+ end
123
+
124
+ # Because solaris has multiple terrible ways to install packages, we have
125
+ # this method which generates a shell script to be executed on the system
126
+ # which will install all of the build dependencies
127
+ #
128
+ # @param build_dependencies [Array] list of all build dependencies to install
129
+ # @return [String] a command to install all of the build dependencies
130
+ def install_build_dependencies(build_dependencies)
131
+ http = []
132
+ pkgutil = []
133
+ noasks = ["instance=overwrite", "partial=nocheck", "runlevel=nocheck", "idepend=nocheck", "rdepend=nocheck", "space=nocheck", "setuid=nocheck", "conflict=nocheck", "action=nocheck", "basedir=default"]
134
+ noask_command = noasks.map { |noask| "echo '#{noask}' >> /var/tmp/noask" }.join('; ')
135
+
136
+ build_dependencies.each do |build_dependency|
137
+ if build_dependency.match(/^http.*\.gz/)
138
+ # Fetch, unpack, install...this assumes curl is present.
139
+ package = build_dependency.sub(/^http.*\//, '')
140
+ http << "tmpdir=$(mktemp -p /var/tmp -d); (cd ${tmpdir} && curl -O #{build_dependency} && gunzip -c #{package} | pkgadd -d /dev/stdin -a /var/tmp/noask all)"
141
+ else
142
+ # Opencsw dependencies. At this point we assume that pkgutil is installed.
143
+ pkgutil << build_dependency
144
+ end
145
+ end
146
+
147
+ command = ''
148
+ unless pkgutil.empty?
149
+ command << "/opt/csw/bin/pkgutil -y -i #{pkgutil.join("\s")}; "
150
+ end
151
+
152
+ unless http.empty?
153
+ command << "echo -n > /var/tmp/noask; #{noask_command}; "
154
+ command << http.join('; ')
155
+ end
156
+
157
+ command
158
+ end
159
+
160
+ # Constructor. Sets up some defaults for the solaris 10 platform and calls the parent constructor
161
+ #
162
+ # @param name [String] name of the platform
163
+ # @return [Vanagon::Platform::Solaris] the solaris 10 derived platform with the given name
164
+ def initialize(name)
165
+ @name = name
166
+ @make = "/opt/csw/bin/gmake"
167
+ @tar = "/usr/sfw/bin/gtar"
168
+ @patch = "/usr/bin/gpatch"
169
+ # solaris 10
170
+ @num_cores = "/usr/bin/kstat cpu_info | awk '{print $$1}' | grep '^core_id$$' | wc -l"
171
+ super(name)
172
+ if @architecture == "sparc"
173
+ @platform_triple = "sparc-sun-solaris2.#{@os_version}"
174
+ elsif @architecture == "i386"
175
+ @platform_triple = "i386-pc-solaris2.#{@os_version}"
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+
@@ -0,0 +1,138 @@
1
+ class Vanagon
2
+ class Platform
3
+ class Solaris11 < Vanagon::Platform
4
+ # The specific bits used to generate a solaris package for a given project
5
+ #
6
+ # @param project [Vanagon::Project] project to build a solaris package of
7
+ # @return [Array] list of commands required to build a solaris package for the given project from a tarball
8
+ def generate_package(project)
9
+ target_dir = project.repo ? output_dir(project.repo) : output_dir
10
+ name_and_version = "#{project.name}-#{project.version}"
11
+ pkg_name = package_name(project)
12
+
13
+ [
14
+ # Set up our needed directories
15
+ "mkdir -p $(tempdir)/#{name_and_version}",
16
+ "mkdir -p $(tempdir)/pkg",
17
+ "mkdir -p output/#{target_dir}",
18
+
19
+ # Unpack the project and stage the packaging artifacts
20
+ "gunzip -c #{name_and_version}.tar.gz | '#{@tar}' -C '$(tempdir)' -xf -",
21
+ "cp -r packaging $(tempdir)/",
22
+ "pkgrepo create $(tempdir)/repo",
23
+ "pkgrepo set -s $(tempdir)/repo publisher/prefix=#{project.identifier}",
24
+
25
+ "(cd $(tempdir); pkgsend generate #{name_and_version} | pkgfmt >> packaging/#{project.name}.p5m.1)",
26
+
27
+ # Actually build the package
28
+ "(cd $(tempdir)/packaging; pkgmogrify -DARCH=`uname -p` #{project.name}.p5m.1 #{project.name}.p5m | pkgfmt > #{project.name}.p5m.2)",
29
+ "pkglint $(tempdir)/packaging/#{project.name}.p5m.2",
30
+ "pkgsend -s 'file://$(tempdir)/repo' publish -d '$(tempdir)/#{name_and_version}' --fmri-in-manifest '$(tempdir)/packaging/#{project.name}.p5m.2'",
31
+ "pkgrecv -s 'file://$(tempdir)/repo' -a -d 'output/#{target_dir}/#{pkg_name}' '#{project.name}@#{ips_version(project.version, project.release)}'",
32
+
33
+ # Now make sure the package we built isn't totally broken (but not when cross-compiling)
34
+ %(if [ "#{@architecture}" = `uname -p` ]; then pkg install -nv -g 'output/#{target_dir}/#{pkg_name}' '#{project.name}@#{ips_version(project.version, project.release)}'; fi),
35
+ ]
36
+ end
37
+
38
+ # Method to generate the files required to build a solaris package for the project
39
+ #
40
+ # @param workdir [String] working directory to stage the evaluated templates in
41
+ # @param name [String] name of the project
42
+ # @param binding [Binding] binding to use in evaluating the packaging templates
43
+ def generate_packaging_artifacts(workdir, name, binding)
44
+ target_dir = File.join(workdir, 'packaging')
45
+ FileUtils.mkdir_p(target_dir)
46
+ erb_file(File.join(VANAGON_ROOT, "templates/solaris/11/p5m.erb"), File.join(target_dir, "#{name}.p5m"), false, { :binding => binding })
47
+ end
48
+
49
+ # Generate the scripts required to add a group to the package generated.
50
+ # This will also update the group if it has changed.
51
+ #
52
+ # @param user [Vanagon::Common::User] the user to reference for the group
53
+ # @return [String] the commands required to add a group to the system
54
+ def add_group(user)
55
+ "group groupname=#{user.group}"
56
+ end
57
+
58
+ # Helper to setup an IPS build repo on a target system
59
+ # http://docs.oracle.com/cd/E36784_01/html/E36802/gkkek.html
60
+ #
61
+ # @param uri [String] uri of the repository to add
62
+ # @param origin [String] origin of the repository
63
+ # @return [String] the command required to add an ips build repository
64
+ def add_repository(uri, origin)
65
+ "pkg set-publisher -G '*' -g #{uri} #{origin}"
66
+ end
67
+
68
+ # Generate the scripts required to add a user to the package generated.
69
+ # This will also update the user if it has changed.
70
+ #
71
+ # @param user [Vanagon::Common::User] the user to create
72
+ # @return [String] the commands required to add a user to the system
73
+ def add_user(user)
74
+ command = "user username=#{user.name}"
75
+ command << " group=#{user.group}" if user.group
76
+ command << " home-dir=#{user.homedir}" if user.homedir
77
+ if user.shell
78
+ command << " login-shell=#{user.shell}"
79
+ elsif user.is_system
80
+ command << " login-shell=/usr/bin/false"
81
+ end
82
+
83
+ command
84
+ end
85
+
86
+ # Method to derive the package name for the project
87
+ #
88
+ # @param project [Vanagon::Project] project to name
89
+ # @return [String] name of the solaris package for this project
90
+ def package_name(project)
91
+ "#{project.name}@#{ips_version(project.version, project.release)}.#{@architecture}.p5p"
92
+ end
93
+
94
+ # Method to transform a standard version into the format expected by IPS
95
+ # packages
96
+ #
97
+ # @param version [String] Standard package version
98
+ # @param release [String] Standard package release
99
+ # @return [String] version in IPS format
100
+ def ips_version(version, release)
101
+ version.gsub!(/[a-zA-Z]/, '')
102
+ version.gsub!(/(^-)|(-$)/, '')
103
+
104
+ # Here we strip leading 0 from version components but leave singular 0 on their own.
105
+ version = version.split('.').map(&:to_i).join('.')
106
+ "#{version},5.11-#{release}"
107
+ end
108
+
109
+ # Get the expected output dir for the solaris 11 packages. This allows us to
110
+ # use some standard tools to ship internally.
111
+ #
112
+ # @return [String] relative path to where solaris 11 packages should be staged
113
+ def output_dir(target_repo = "")
114
+ File.join("solaris", @os_version, target_repo)
115
+ end
116
+
117
+ # Constructor. Sets up some defaults for the solaris 11 platform and calls the parent constructor
118
+ #
119
+ # @param name [String] name of the platform
120
+ # @return [Vanagon::Platform::Solaris] the solaris 11 derived platform with the given name
121
+ def initialize(name)
122
+ @name = name
123
+ @make = "/usr/bin/gmake"
124
+ @tar = "/usr/bin/gtar"
125
+ @patch = "/usr/bin/gpatch"
126
+ @num_cores = "/usr/bin/kstat cpu_info | /usr/bin/ggrep -E '[[:space:]]+core_id[[:space:]]' | wc -l"
127
+ super(name)
128
+ if @architecture == "sparc"
129
+ @platform_triple = "sparc-sun-solaris2.#{@os_version}"
130
+ elsif @architecture == "i386"
131
+ @platform_triple = "i386-pc-solaris2.#{@os_version}"
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+