vanagon 0.3.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0273c4745ecf7c50f369b6ea518caf46b92c8e07
|
4
|
+
data.tar.gz: 06437a1d3f2838cfd97d673fe2f82981ca917df0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2664084d24f35b26e7b30b4ab20c0ee910281af1722ac82363696de47af77962eb1f9cd3980f3d6af8a3aa10a0472f890f27eae66557c0c5a0aadeca96007852
|
7
|
+
data.tar.gz: f27159049e709a19879702636296d27ab31d2c40455f0c11675616a75a3c96411a017f9fefc1fec0ee460dbd4c0443a64e5f6549dbe3a48fc009f28f4d0cc551
|
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2014-2015 Puppet Labs
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
![Build Status](https://magnum.travis-ci.com/puppetlabs/vanagon.svg?token=A9NWBM3ogJqUCfos2gVF&branch=master)
|
2
|
+
The Vanagon Project
|
3
|
+
===
|
4
|
+
* What is vanagon?
|
5
|
+
* Runtime requirements
|
6
|
+
* Configuration and Usage
|
7
|
+
* Overview
|
8
|
+
* Contributing
|
9
|
+
* License
|
10
|
+
* Maintainers
|
11
|
+
|
12
|
+
What is vanagon?
|
13
|
+
---
|
14
|
+
Vanagon is a tool to build a single package out of a project, which can itself
|
15
|
+
contain one or more components. This tooling is being used to develop the
|
16
|
+
puppet-agent package, which contains components such as openssl, ruby, and
|
17
|
+
augeas among others. For a simple example, please see the examples directory.
|
18
|
+
|
19
|
+
Vanagon builds up a Makefile and packaging files (specfile for RPM,
|
20
|
+
control/rules/etc for DEB) and copies them to a remote host, where make can be
|
21
|
+
invoked to build all of the components and make a package of the contents.
|
22
|
+
|
23
|
+
Vanagon also provides a devkit command that will prepare a machine as a
|
24
|
+
development environment for the entire project, or restricted to individual
|
25
|
+
components of the project. The devkit command installs all required build tools,
|
26
|
+
creates a master makefile for the project, and configures, builds, and installs
|
27
|
+
all components. The result is an environment where you can work on individual
|
28
|
+
components, then rebuild the project and test the installed artifacts.
|
29
|
+
|
30
|
+
Runtime Requirements
|
31
|
+
---
|
32
|
+
Vanagon is self-contained. A recent version of ruby should be all that is
|
33
|
+
required. Beyond that, ssh, rsync and git are also required on the host, and
|
34
|
+
ssh-server and rsync is required on the target (package installation for the
|
35
|
+
target can be customized in the platform config for the target).
|
36
|
+
|
37
|
+
Configuration and Usage
|
38
|
+
---
|
39
|
+
Vanagon won't be much use without a project to build. Beyond that, you must
|
40
|
+
define any platforms you want to build for. Vanagon ships with some simple
|
41
|
+
binaries to use, but the one you probably care about is named 'build'.
|
42
|
+
|
43
|
+
### `build` usage
|
44
|
+
|
45
|
+
The build command has positional arguments and position independent flags.
|
46
|
+
|
47
|
+
#### Arguments (position dependent)
|
48
|
+
|
49
|
+
##### project name
|
50
|
+
The name of the project to build, and a file named \<project\_name\>.rb must be
|
51
|
+
present in configs/projects in the working directory.
|
52
|
+
|
53
|
+
##### platform name
|
54
|
+
The name of the platform to build against, and a file named
|
55
|
+
\<platform\_name\>.rb must be present in configs/platforms in the working
|
56
|
+
directory.
|
57
|
+
|
58
|
+
Platform can also be a comma separated list of platforms such as platform1,platform2.
|
59
|
+
|
60
|
+
##### target host [optional]
|
61
|
+
Target host is an optional argument to override the host selection. Instead of using
|
62
|
+
a vm collected from the pooler, the build will attempt to ssh to target as the
|
63
|
+
root user.
|
64
|
+
|
65
|
+
If building on multiple platforms, multiple targets can also be specified using
|
66
|
+
a comma separated list such as host1,host2. If less targets are specified than
|
67
|
+
platforms, the default engine (the pooler) will be used for platforms without a
|
68
|
+
target. If more targets are specified than platforms, the extra will be ignored.
|
69
|
+
|
70
|
+
#### Flagged arguments (can be anywhere in the command)
|
71
|
+
|
72
|
+
##### -w DIR, --workdir DIR
|
73
|
+
Specifies a directory where the sources should be placed and builds performed.
|
74
|
+
Defaults to a temporary directory created with Ruby's Dir.mktmpdir.
|
75
|
+
|
76
|
+
##### -c DIR, --configdir DIR
|
77
|
+
Specifies where project configuration is found. Defaults to $pwd/configs.
|
78
|
+
|
79
|
+
##### -e ENGINE, --engine ENGINE
|
80
|
+
Choose a different virtualization engine to use to select the build target.
|
81
|
+
Currently supported engines are:
|
82
|
+
* `base` - Pure ssh backend; no teardown currently defined
|
83
|
+
* `local` - Build on the local machine; platform name must match the local machine
|
84
|
+
* `docker` - Builds in a docker container
|
85
|
+
* `pooler` - Selects a vm from Puppet Labs' vm pooler to build on
|
86
|
+
|
87
|
+
#### Flags (can be anywhere in the command)
|
88
|
+
|
89
|
+
##### -p, --preserve
|
90
|
+
Indicates that the host used for building the project should be left intact
|
91
|
+
after the build instead of destroyed. The host is usually destroyed after a
|
92
|
+
successful build, or left after a failed build.
|
93
|
+
|
94
|
+
##### -v, --verbose (not yet implemented)
|
95
|
+
Increase verbosity of output.
|
96
|
+
|
97
|
+
##### -h, --help
|
98
|
+
Display command-line help.
|
99
|
+
|
100
|
+
#### Environment variables
|
101
|
+
|
102
|
+
##### VANAGON\_SSH\_KEY
|
103
|
+
A full path on disk for a private ssh key to be used in ssh and rsync
|
104
|
+
communications. This will be used instead of whatever defaults are configured
|
105
|
+
in .ssh/config.
|
106
|
+
|
107
|
+
##### VMPOOLER\_TOKEN
|
108
|
+
Used in conjunction with the pooler engine, this is a token to pass to the
|
109
|
+
vmpooler to access the API. Without this token, the default lifetime of vms
|
110
|
+
will be much shorter.
|
111
|
+
|
112
|
+
#### Example usage
|
113
|
+
`build --preserve puppet-agent el-6-i386` will build the puppet-agent project
|
114
|
+
on the el-6-i386 platform and leave the host intact afterward.
|
115
|
+
|
116
|
+
`build --engine=docker puppet-agent el-6-i386` will build the puppet-agent
|
117
|
+
project on the el-6-i386 platform using the docker engine (the platform must
|
118
|
+
have a docker\_image defined in its config).
|
119
|
+
|
120
|
+
### `devkit` usage
|
121
|
+
|
122
|
+
The devkit command has positional arguments and position independent flagged
|
123
|
+
arguments.
|
124
|
+
|
125
|
+
#### Arguments (position dependent)
|
126
|
+
|
127
|
+
##### project name
|
128
|
+
As in `build` arguments.
|
129
|
+
|
130
|
+
##### platform name
|
131
|
+
As in `build` arguments.
|
132
|
+
|
133
|
+
##### component names [optional]
|
134
|
+
Specifies specific components that should be built. If components are not
|
135
|
+
specified, then all components in the project will be built. If components
|
136
|
+
are specified as arguments, then any in the project that aren't specified
|
137
|
+
as arguments will be retrieved from packages rather than built from source.
|
138
|
+
|
139
|
+
#### Flagged arguments (can be anywhere in the command)
|
140
|
+
|
141
|
+
Supports all flagged arguments from the `build` command.
|
142
|
+
|
143
|
+
##### -t HOST, --target HOST
|
144
|
+
As in the `build` target host optional argument.
|
145
|
+
|
146
|
+
#### Flags (can be anywhere in the command)
|
147
|
+
|
148
|
+
##### -h, --help
|
149
|
+
Display command-line help.
|
150
|
+
|
151
|
+
Contributing
|
152
|
+
---
|
153
|
+
We'd love to get contributions from you! Once you are up and running, take a look at the
|
154
|
+
[Contribution Documents](CONTRIBUTING.md) to see how to get your changes merged
|
155
|
+
in.
|
156
|
+
|
157
|
+
License
|
158
|
+
---
|
159
|
+
See [LICENSE](LICENSE) file.
|
160
|
+
|
161
|
+
Overview
|
162
|
+
---
|
163
|
+
Vanagon is broken down into three core ideas: the project, the component and
|
164
|
+
the platform. The project contains one or more components and is built for a
|
165
|
+
platform. As a quick example, if I had a ruby app and wanted to package it, the
|
166
|
+
project would probably contain a component for ruby and a component for my app.
|
167
|
+
If I wanted to build it for debian wheezy, I would define a platform called
|
168
|
+
wheezy and build my project against it.
|
169
|
+
|
170
|
+
For more detailed examples of the DSLs available, please see the
|
171
|
+
[examples](examples) directory and the YARD documentation for vanagon.
|
172
|
+
|
173
|
+
Maintainers
|
174
|
+
---
|
175
|
+
The Release Engineering team at Puppet Labs
|
data/bin/build
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
load File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "vanagon.rb"))
|
3
|
+
|
4
|
+
optparse = Vanagon::OptParse.new("#{File.basename(__FILE__)} <project-name> <platform-name> [<target>] [options]",
|
5
|
+
[:workdir, :configdir, :engine, :preserve, :verbose])
|
6
|
+
options = optparse.parse! ARGV
|
7
|
+
|
8
|
+
project = ARGV[0]
|
9
|
+
platforms = ARGV[1]
|
10
|
+
targets = ARGV[2]
|
11
|
+
|
12
|
+
if project.nil? or platforms.nil?
|
13
|
+
warn "project and platform are both required arguments."
|
14
|
+
puts optparse
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
platform_list = platforms.split(',')
|
19
|
+
if targets
|
20
|
+
target_list = targets.split(',')
|
21
|
+
else
|
22
|
+
target_list = []
|
23
|
+
end
|
24
|
+
|
25
|
+
platform_list.zip(target_list).each do |pair|
|
26
|
+
platform, target = pair
|
27
|
+
artifact = Vanagon::Driver.new(platform, project, options.merge({ :target => target }))
|
28
|
+
|
29
|
+
artifact.verbose = true if options[:verbose]
|
30
|
+
artifact.preserve = true if options[:preserve]
|
31
|
+
|
32
|
+
artifact.run
|
33
|
+
end
|
data/bin/devkit
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
load File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "vanagon.rb"))
|
3
|
+
|
4
|
+
optparse = Vanagon::OptParse.new("#{File.basename(__FILE__)} <project-name> <platform-name> [<component-name>...] [options]",
|
5
|
+
[:workdir, :configdir, :target, :engine])
|
6
|
+
options = optparse.parse! ARGV
|
7
|
+
|
8
|
+
project = ARGV[0]
|
9
|
+
platform = ARGV[1]
|
10
|
+
components = ARGV.drop(2)
|
11
|
+
|
12
|
+
if project.nil? or platform.nil?
|
13
|
+
warn "project and platform are both required arguments."
|
14
|
+
puts optparse
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
|
18
|
+
artifact = Vanagon::Driver.new(platform, project, options.merge({ :components => components }))
|
19
|
+
|
20
|
+
artifact.preserve = true
|
21
|
+
|
22
|
+
artifact.prepare(options[:workdir])
|
data/bin/repo
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
ENV["PROJECT_ROOT"] = Dir.pwd
|
4
|
+
|
5
|
+
# Begin warning: This ship script is an internal tool.
|
6
|
+
# This is not intended to function outside of Puppet Labs' infrastructure.
|
7
|
+
# This presumes packages for this ref have already been build and shipped.
|
8
|
+
# End of warning.
|
9
|
+
|
10
|
+
# repo_target will allow us to be more granular with the selection of repos that will be constructed
|
11
|
+
# if we have not built debs or rpms, the packaging repo will fail when creating repos
|
12
|
+
if ARGV[0]
|
13
|
+
repo_target = ARGV[0].downcase
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'packaging'
|
17
|
+
Pkg::Util::RakeUtils.load_packaging_tasks
|
18
|
+
case repo_target
|
19
|
+
when 'rpm'
|
20
|
+
Pkg::Util::RakeUtils.invoke_task('pl:jenkins:rpm_repos')
|
21
|
+
when 'deb'
|
22
|
+
Pkg::Util::RakeUtils.invoke_task('pl:jenkins:deb_repos')
|
23
|
+
else
|
24
|
+
Pkg::Util::RakeUtils.invoke_task('pl:jenkins:rpm_repos')
|
25
|
+
Pkg::Util::RakeUtils.invoke_task('pl:jenkins:deb_repos')
|
26
|
+
end
|
data/bin/ship
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
ENV["PROJECT_ROOT"] = Dir.pwd
|
4
|
+
|
5
|
+
# Begin warning: This ship script is an internal tool.
|
6
|
+
# This is not intended to function outside of Puppet Labs' infrastructure.
|
7
|
+
# End of warning.
|
8
|
+
|
9
|
+
if Dir["output/**/*"].select { |entry| File.file?(entry) }.empty?
|
10
|
+
fail "No packages to ship in the output directory. Maybe you want to build some first?"
|
11
|
+
else
|
12
|
+
require 'packaging'
|
13
|
+
Pkg::Util::RakeUtils.load_packaging_tasks
|
14
|
+
Pkg::Util::RakeUtils.invoke_task('pl:jenkins:ship', 'artifacts', 'output')
|
15
|
+
end
|
data/lib/vanagon.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
LIBDIR = File.expand_path(File.dirname(__FILE__))
|
2
|
+
VANAGON_ROOT = File.join(File.expand_path(File.dirname(__FILE__)), "..")
|
3
|
+
|
4
|
+
$:.unshift(LIBDIR) unless
|
5
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(LIBDIR)
|
6
|
+
|
7
|
+
require 'vanagon/optparse'
|
8
|
+
require 'vanagon/driver'
|
@@ -0,0 +1,87 @@
|
|
1
|
+
class Vanagon
|
2
|
+
class Common
|
3
|
+
class Pathname
|
4
|
+
# @!attribute path
|
5
|
+
# @return [String] Returns clean pathname of self with consecutive
|
6
|
+
# slashes and useless dots removed. The filesystem is not accessed.
|
7
|
+
#
|
8
|
+
# @!attribute mode
|
9
|
+
# @return [String, Integer] Returns an integer representing the
|
10
|
+
# permission bits of self. The meaning of the bits is platform
|
11
|
+
# dependent; on Unix systems, see stat(2).
|
12
|
+
#
|
13
|
+
# @!attribute owner
|
14
|
+
# @return [String, Integer] Returns the numeric user id or string
|
15
|
+
# representing the user name of the owner of self.
|
16
|
+
#
|
17
|
+
# @!attribute group
|
18
|
+
# @return [String, Integer] Returns the numeric group id or string
|
19
|
+
# representing the group name of the owner of self.
|
20
|
+
attr_accessor :path, :mode, :owner, :group
|
21
|
+
|
22
|
+
# Each Pathname requires a filesystem path, and has many optional
|
23
|
+
# properties that may be set at initialization time.
|
24
|
+
# @param [String, Integer] mode the UNIX Octal permission string to use when this file is archived
|
25
|
+
# @param [String, Integer] owner the username or UID to use when this file is archived
|
26
|
+
# @param [String, Integer] group the groupname or GID to use when this file is archived
|
27
|
+
# @param [Boolean] config mark this file as a configuration file, stored as private state
|
28
|
+
# and exposed through the {#configfile?} method.
|
29
|
+
# @return [Vanagon::Common::Pathname] Returns a new Pathname instance.
|
30
|
+
def initialize(path, mode: nil, owner: nil, group: nil, config: false)
|
31
|
+
@path = File.expand_path(path)
|
32
|
+
@mode ||= mode
|
33
|
+
@owner ||= owner
|
34
|
+
@group ||= group
|
35
|
+
@config ||= config
|
36
|
+
end
|
37
|
+
|
38
|
+
# An alias to {Vanagon::Common::Pathname}'s constructor method,
|
39
|
+
# which returns a new Vanagon::Common::Pathname, explicitly marked as a file
|
40
|
+
# @see Vanagon::Common::Pathname#initialize
|
41
|
+
#
|
42
|
+
# @example Create a new Vanagon::Common::Pathname, marked as a file.
|
43
|
+
# Vanagon::Common::Pathname.file('/etc/puppet/puppet/puppet.conf')
|
44
|
+
def self.file(path, **args)
|
45
|
+
new(path, **args.merge!({ config: false}))
|
46
|
+
end
|
47
|
+
|
48
|
+
# An alias to {Vanagon::Common::Pathname}'s constructor method,
|
49
|
+
# which returns a new Vanagon::Common::Pathname, explicitly marked as a configuration file
|
50
|
+
# @see Vanagon::Common::Pathname#initialize
|
51
|
+
#
|
52
|
+
# @example Create a new configuration file, marked as a configuration file.
|
53
|
+
# Vanagon::Common::Pathname.configfile('/etc/puppet/puppet/puppet.conf')
|
54
|
+
def self.configfile(path, **args)
|
55
|
+
new(path, **args.merge!({ config: true}))
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Boolean] true if a self is marked as a configuration file.
|
59
|
+
def configfile?
|
60
|
+
!!@config
|
61
|
+
end
|
62
|
+
|
63
|
+
# Simple test to see if any of the non-required attributes have been set in this object.
|
64
|
+
#
|
65
|
+
# @return [Boolean] whether or not mode, owner or group has been set for the object
|
66
|
+
def has_overrides?
|
67
|
+
!!(@mode || @owner || @group)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Equality -- Two instances of Vanagon::Common::Pathname are equal if they
|
71
|
+
# contain the same number attributes and if each attribute is equal to
|
72
|
+
# (according to {Object#==}) the corresponding attribute in other_pathname.
|
73
|
+
#
|
74
|
+
# @return [Boolean] true if all attributes have equal values, or otherwise false.
|
75
|
+
def ==(other)
|
76
|
+
other.hash == hash
|
77
|
+
end
|
78
|
+
alias :eql? :==
|
79
|
+
|
80
|
+
# @return [Fixnum] Compute a hash-code for self, derived from its attributes;
|
81
|
+
# two Pathnames with the same content will have the same hash code (and will compare using {#eql?}).
|
82
|
+
def hash
|
83
|
+
instance_variables.map { |v| instance_variable_get(v) }.hash
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Vanagon
|
2
|
+
class Common
|
3
|
+
class User
|
4
|
+
attr_accessor :name, :group, :shell, :is_system, :homedir
|
5
|
+
def initialize(name, group = nil, shell = nil, is_system = false, homedir = nil)
|
6
|
+
@name = name
|
7
|
+
@group = group ? group : @name
|
8
|
+
@shell = shell if shell
|
9
|
+
@is_system = is_system if is_system
|
10
|
+
@homedir = homedir if homedir
|
11
|
+
end
|
12
|
+
|
13
|
+
# Equality. How does it even work?
|
14
|
+
#
|
15
|
+
# @return [true, false] true if all attributes have equal values. false otherwise.
|
16
|
+
def ==(other)
|
17
|
+
other.name == self.name && \
|
18
|
+
other.group == self.group && \
|
19
|
+
other.shell == self.shell && \
|
20
|
+
other.is_system == self.is_system && \
|
21
|
+
other.homedir == self.homedir
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'vanagon/component/source'
|
2
|
+
require 'vanagon/component/dsl'
|
3
|
+
|
4
|
+
class Vanagon
|
5
|
+
class Component
|
6
|
+
# @!attribute [r] files
|
7
|
+
# @return [Set] the list of files marked for installation
|
8
|
+
|
9
|
+
attr_accessor :name, :version, :source, :url, :configure, :build, :install
|
10
|
+
attr_accessor :environment, :extract_with, :dirname, :build_requires
|
11
|
+
attr_accessor :settings, :platform, :patches, :requires, :service, :options
|
12
|
+
attr_accessor :directories, :replaces, :provides, :cleanup_source, :environment
|
13
|
+
attr_accessor :sources, :preinstall_actions, :postinstall_actions
|
14
|
+
|
15
|
+
# Loads a given component from the configdir
|
16
|
+
#
|
17
|
+
# @param name [String] the name of the component
|
18
|
+
# @param configdir [String] the path to the component config file
|
19
|
+
# @param settings [Hash] the settings to be used in the component
|
20
|
+
# @param platform [Vanagon::Platform] the platform to build the component for
|
21
|
+
# @return [Vanagon::Component] the component as specified in the component config
|
22
|
+
# @raise if the instance_eval on Component fails, the exception is reraised
|
23
|
+
def self.load_component(name, configdir, settings, platform)
|
24
|
+
compfile = File.join(configdir, "#{name}.rb")
|
25
|
+
code = File.read(compfile)
|
26
|
+
dsl = Vanagon::Component::DSL.new(name, settings, platform)
|
27
|
+
dsl.instance_eval(code, __FILE__, __LINE__)
|
28
|
+
dsl._component
|
29
|
+
rescue => e
|
30
|
+
puts "Error loading project '#{name}' using '#{compfile}':"
|
31
|
+
puts e
|
32
|
+
puts e.backtrace.join("\n")
|
33
|
+
raise e
|
34
|
+
end
|
35
|
+
|
36
|
+
# Component constructor.
|
37
|
+
#
|
38
|
+
# @param name [String] the name of the component
|
39
|
+
# @param settings [Hash] the settings to be used in the component
|
40
|
+
# @param platform [Vanagon::Platform] the platform to build the component for
|
41
|
+
# @return [Vanagon::Component] the component with the given settings and platform
|
42
|
+
def initialize(name, settings, platform)
|
43
|
+
@name = name
|
44
|
+
@settings = settings
|
45
|
+
@platform = platform
|
46
|
+
@options = {}
|
47
|
+
@build_requires = []
|
48
|
+
@requires = []
|
49
|
+
@configure = []
|
50
|
+
@install = []
|
51
|
+
@build = []
|
52
|
+
@patches = []
|
53
|
+
@files = Set.new
|
54
|
+
@directories = []
|
55
|
+
@replaces = []
|
56
|
+
@provides = []
|
57
|
+
@environment = {}
|
58
|
+
@sources = []
|
59
|
+
@preinstall_actions = []
|
60
|
+
@postinstall_actions = []
|
61
|
+
end
|
62
|
+
|
63
|
+
# Adds the given file to the list of files and returns @files.
|
64
|
+
#
|
65
|
+
# @param file [Vanagon::Common::Pathname] file to add to a component's list of files
|
66
|
+
# @return [Set, nil] Returns @files if file is successfully added to @files
|
67
|
+
# or nil if file already exists
|
68
|
+
def add_file(file)
|
69
|
+
@files.add file
|
70
|
+
end
|
71
|
+
|
72
|
+
# Deletes the given file from the list of files and returns @files.
|
73
|
+
#
|
74
|
+
# @param file [String] path of file to delete from a component's list of files
|
75
|
+
# @return [Set, nil] Returns @files if file is successfully deleted
|
76
|
+
# from @files or nil if file doesn't exist; this matches strictly on
|
77
|
+
# the path of a given file, and ignores other attributes like :mode,
|
78
|
+
# :owner, or :group.
|
79
|
+
def delete_file(file)
|
80
|
+
@files.delete_if { |this_file| this_file.path == file }
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retrieve all items from @files not marked as configuration files
|
84
|
+
#
|
85
|
+
# @return [Set] all files not marked as configuration files
|
86
|
+
def files
|
87
|
+
@files.reject(&:configfile?)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Retrieve all items from @files explicitly marked as configuration files
|
91
|
+
#
|
92
|
+
# @return [Set] all files explicitly marked as configuration files
|
93
|
+
def configfiles
|
94
|
+
@files.select(&:configfile?)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Fetches the primary source for the component. As a side effect, also sets
|
98
|
+
# \@extract_with, @dirname and @version for the component for use in the
|
99
|
+
# makefile template
|
100
|
+
#
|
101
|
+
# @param workdir [String] working directory to put the source into
|
102
|
+
def get_source(workdir)
|
103
|
+
if @url
|
104
|
+
@source = Vanagon::Component::Source.source(@url, @options, workdir)
|
105
|
+
@source.fetch
|
106
|
+
@source.verify
|
107
|
+
@extract_with = @source.extract(@platform.tar) if @source.respond_to?(:extract)
|
108
|
+
@cleanup_source = @source.cleanup if @source.respond_to?(:cleanup)
|
109
|
+
@dirname = @source.dirname
|
110
|
+
|
111
|
+
# Git based sources probably won't set the version, so we load it if it hasn't been already set
|
112
|
+
@version ||= @source.version
|
113
|
+
else
|
114
|
+
warn "No source given for component '#{@name}'"
|
115
|
+
|
116
|
+
# If there is no source, we don't want to try to change directories, so we just change to the current directory.
|
117
|
+
@dirname = './'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
# Fetches secondary sources for the component. These are just dumped into the workdir currently.
|
123
|
+
#
|
124
|
+
# @param workdir [String] working directory to put the source into
|
125
|
+
def get_sources(workdir)
|
126
|
+
@sources.each do |source|
|
127
|
+
cur_source = Vanagon::Component::Source.source(source.url, { :ref => source.ref, :sum => source.sum }, workdir)
|
128
|
+
cur_source.fetch
|
129
|
+
cur_source.verify
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Fetches patches if any are provided for the project.
|
134
|
+
#
|
135
|
+
# @param workdir [String] working directory to put the patches into
|
136
|
+
def get_patches(workdir)
|
137
|
+
unless @patches.empty?
|
138
|
+
patchdir = File.join(workdir, "patches")
|
139
|
+
FileUtils.mkdir_p(patchdir)
|
140
|
+
FileUtils.cp(@patches.map(&:path), patchdir)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Prints the environment in a way suitable for use in a Makefile
|
145
|
+
# or shell script.
|
146
|
+
#
|
147
|
+
# @return [String] environment suitable for inclusion in a Makefile
|
148
|
+
def get_environment
|
149
|
+
if @environment.empty?
|
150
|
+
":"
|
151
|
+
else
|
152
|
+
env = @environment.map { |key, value| %(#{key}="#{value}") }
|
153
|
+
"export #{env.join(' ')}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|