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.
- checksums.yaml +7 -0
- data/LICENSE +13 -0
- data/README.md +175 -0
- data/bin/build +33 -0
- data/bin/devkit +22 -0
- data/bin/repo +26 -0
- data/bin/ship +15 -0
- data/lib/vanagon.rb +8 -0
- data/lib/vanagon/common.rb +2 -0
- data/lib/vanagon/common/pathname.rb +87 -0
- data/lib/vanagon/common/user.rb +25 -0
- data/lib/vanagon/component.rb +157 -0
- data/lib/vanagon/component/dsl.rb +307 -0
- data/lib/vanagon/component/source.rb +66 -0
- data/lib/vanagon/component/source/git.rb +60 -0
- data/lib/vanagon/component/source/http.rb +158 -0
- data/lib/vanagon/driver.rb +112 -0
- data/lib/vanagon/engine/base.rb +82 -0
- data/lib/vanagon/engine/docker.rb +40 -0
- data/lib/vanagon/engine/local.rb +40 -0
- data/lib/vanagon/engine/pooler.rb +85 -0
- data/lib/vanagon/errors.rb +28 -0
- data/lib/vanagon/extensions/string.rb +11 -0
- data/lib/vanagon/optparse.rb +62 -0
- data/lib/vanagon/platform.rb +245 -0
- data/lib/vanagon/platform/deb.rb +71 -0
- data/lib/vanagon/platform/dsl.rb +293 -0
- data/lib/vanagon/platform/osx.rb +100 -0
- data/lib/vanagon/platform/rpm.rb +76 -0
- data/lib/vanagon/platform/rpm/wrl.rb +39 -0
- data/lib/vanagon/platform/solaris_10.rb +182 -0
- data/lib/vanagon/platform/solaris_11.rb +138 -0
- data/lib/vanagon/platform/swix.rb +35 -0
- data/lib/vanagon/project.rb +251 -0
- data/lib/vanagon/project/dsl.rb +218 -0
- data/lib/vanagon/utilities.rb +299 -0
- data/spec/fixures/component/invalid-test-fixture.json +3 -0
- data/spec/fixures/component/mcollective.service +1 -0
- data/spec/fixures/component/test-fixture.json +4 -0
- data/spec/lib/vanagon/common/pathname_spec.rb +103 -0
- data/spec/lib/vanagon/common/user_spec.rb +36 -0
- data/spec/lib/vanagon/component/dsl_spec.rb +443 -0
- data/spec/lib/vanagon/component/source/git_spec.rb +19 -0
- data/spec/lib/vanagon/component/source/http_spec.rb +43 -0
- data/spec/lib/vanagon/component/source_spec.rb +99 -0
- data/spec/lib/vanagon/component_spec.rb +22 -0
- data/spec/lib/vanagon/engine/base_spec.rb +40 -0
- data/spec/lib/vanagon/engine/docker_spec.rb +40 -0
- data/spec/lib/vanagon/engine/pooler_spec.rb +54 -0
- data/spec/lib/vanagon/platform/deb_spec.rb +60 -0
- data/spec/lib/vanagon/platform/dsl_spec.rb +128 -0
- data/spec/lib/vanagon/platform/rpm_spec.rb +41 -0
- data/spec/lib/vanagon/platform/solaris_11_spec.rb +44 -0
- data/spec/lib/vanagon/platform_spec.rb +53 -0
- data/spec/lib/vanagon/project/dsl_spec.rb +203 -0
- data/spec/lib/vanagon/project_spec.rb +44 -0
- data/spec/lib/vanagon/utilities_spec.rb +140 -0
- data/templates/Makefile.erb +116 -0
- data/templates/deb/changelog.erb +5 -0
- data/templates/deb/conffiles.erb +3 -0
- data/templates/deb/control.erb +21 -0
- data/templates/deb/dirs.erb +3 -0
- data/templates/deb/docs.erb +1 -0
- data/templates/deb/install.erb +3 -0
- data/templates/deb/postinst.erb +46 -0
- data/templates/deb/postrm.erb +15 -0
- data/templates/deb/prerm.erb +17 -0
- data/templates/deb/rules.erb +25 -0
- data/templates/osx/postinstall.erb +24 -0
- data/templates/osx/preinstall.erb +19 -0
- data/templates/osx/project-installer.xml.erb +19 -0
- data/templates/rpm/project.spec.erb +217 -0
- data/templates/solaris/10/depend.erb +3 -0
- data/templates/solaris/10/pkginfo.erb +13 -0
- data/templates/solaris/10/postinstall.erb +37 -0
- data/templates/solaris/10/preinstall.erb +7 -0
- data/templates/solaris/10/preremove.erb +6 -0
- data/templates/solaris/10/proto.erb +5 -0
- data/templates/solaris/11/p5m.erb +73 -0
- 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
|
+
|