vanagon 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/bin/build +1 -1
- data/lib/makefile.rb +67 -0
- data/lib/vanagon/component.rb +16 -2
- data/lib/vanagon/component/dsl.rb +34 -3
- data/lib/vanagon/component/rules.rb +217 -0
- data/lib/vanagon/component/source/http.rb +8 -3
- data/lib/vanagon/driver.rb +12 -5
- data/lib/vanagon/engine/hardware.rb +64 -0
- data/lib/vanagon/optparse.rb +16 -33
- data/lib/vanagon/patch.rb +39 -0
- data/lib/vanagon/platform.rb +3 -2
- data/lib/vanagon/platform/dsl.rb +23 -5
- data/lib/vanagon/platform/rpm/eos.rb +83 -0
- data/lib/vanagon/platform/solaris_10.rb +19 -4
- data/lib/vanagon/utilities/shell_utilities.rb +29 -0
- data/spec/lib/makefile_spec.rb +50 -0
- data/spec/lib/vanagon/component/dsl_spec.rb +61 -2
- data/spec/lib/vanagon/component/rules_spec.rb +302 -0
- data/spec/lib/vanagon/component_spec.rb +17 -0
- data/spec/lib/vanagon/engine/hardware_spec.rb +48 -0
- data/spec/lib/vanagon/optparse_spec.rb +40 -0
- data/spec/lib/vanagon/utilities/shell_utilities_spec.rb +32 -0
- data/templates/Makefile.erb +1 -58
- data/templates/rpm/project.spec.erb +1 -1
- metadata +33 -4
- data/lib/vanagon/platform/swix.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0277e8af73f3165f6e9b9dac09f09afbf92257d1
|
4
|
+
data.tar.gz: b6d18711b68b4ca2ce845bb1cae01bbf019dfd90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8cccacd01204b1474944ec8975597369883ea354e71e58724802ab27b2581af7a009dd3ab07fe770fadd121180fb35b53bed8ae6bd409b3e031839c5d353d4d
|
7
|
+
data.tar.gz: a8b4f78d37aa2844f1615b7aded498e6c5ca47c5d34d5a18e229125062928d1c6033d9bb97beb3725a1bfeb2250bf714262af187d2509014b4573e18c95bf338
|
data/README.md
CHANGED
@@ -84,6 +84,7 @@ Currently supported engines are:
|
|
84
84
|
* `local` - Build on the local machine; platform name must match the local machine
|
85
85
|
* `docker` - Builds in a docker container
|
86
86
|
* `pooler` - Selects a vm from Puppet Labs' vm pooler to build on
|
87
|
+
* `hardware` - Build on a specific taget and lock it in redis
|
87
88
|
|
88
89
|
#### Flags (can be anywhere in the command)
|
89
90
|
|
@@ -110,6 +111,13 @@ Used in conjunction with the pooler engine, this is a token to pass to the
|
|
110
111
|
vmpooler to access the API. Without this token, the default lifetime of vms
|
111
112
|
will be much shorter.
|
112
113
|
|
114
|
+
##### LOCK\_MANAGER\_HOST
|
115
|
+
The name of the host where redis is running. Redis is used to handle a lock
|
116
|
+
when using the hardware engine. It defaults to *redis*, with no domain.
|
117
|
+
|
118
|
+
#### LOCK\_MANAGER\_PORT
|
119
|
+
Port of the system where redis is running. Defaults to *6379*.
|
120
|
+
|
113
121
|
#### Example usage
|
114
122
|
`build --preserve puppet-agent el-6-i386` will build the puppet-agent project
|
115
123
|
on the el-6-i386 platform and leave the host intact afterward.
|
data/bin/build
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
load File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "vanagon.rb"))
|
3
3
|
|
4
4
|
optparse = Vanagon::OptParse.new("#{File.basename(__FILE__)} <project-name> <platform-name> [<target>] [options]",
|
5
|
-
[:workdir, :configdir, :engine, :preserve, :verbose])
|
5
|
+
[:workdir, :configdir, :engine, :preserve, :verbose, :skipcheck])
|
6
6
|
options = optparse.parse! ARGV
|
7
7
|
|
8
8
|
project = ARGV[0]
|
data/lib/makefile.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
class Makefile
|
2
|
+
|
3
|
+
# The Rule class defines a single Makefile rule.
|
4
|
+
#
|
5
|
+
# @see http://www.gnu.org/software/make/manual/make.html#Rule-Introduction
|
6
|
+
class Rule
|
7
|
+
|
8
|
+
# @!attribute [rw] target
|
9
|
+
# @return [String] The target generated by this rule.
|
10
|
+
attr_accessor :target
|
11
|
+
|
12
|
+
# @!attribute [rw] dependencies
|
13
|
+
# @return [Array<String>] A list of dependencies that this rule depends on.
|
14
|
+
attr_accessor :dependencies
|
15
|
+
|
16
|
+
# @!attribute [rw] recipe
|
17
|
+
# @return [Array<String>] A list of commands to execute upon invocation of this rule.
|
18
|
+
attr_accessor :recipe
|
19
|
+
|
20
|
+
# Create a new Makefile rule. When a block is provided then it is called and passed the
|
21
|
+
# newly created Rule object.
|
22
|
+
#
|
23
|
+
# @overload initialize(target, dependencies: [], recipe: [])
|
24
|
+
# @param target [String] target
|
25
|
+
# @param dependencies [Array<String>]]
|
26
|
+
# @param recipe [Array<String>]
|
27
|
+
#
|
28
|
+
# @overload initialize(target, dependencies: [], recipe: [], &block)
|
29
|
+
# @param target [String] target
|
30
|
+
# @param dependencies [Array<String>]]
|
31
|
+
# @param recipe [Array<String>]
|
32
|
+
# @yieldparam rule [Makefile::Rule]
|
33
|
+
#
|
34
|
+
# @example Providing a block to #initialize
|
35
|
+
# newrule = Makefile::Rule.new("test", dependencies: ["all"]) do |rule|
|
36
|
+
# rule.recipe = [
|
37
|
+
# "make test",
|
38
|
+
# "make cpplint",
|
39
|
+
# ]
|
40
|
+
# end
|
41
|
+
def initialize(target, dependencies: [], recipe: [], &block)
|
42
|
+
@target = target
|
43
|
+
@dependencies = dependencies
|
44
|
+
@recipe = recipe
|
45
|
+
|
46
|
+
block.call(self) if block
|
47
|
+
end
|
48
|
+
|
49
|
+
# Format this rule as a Makefile rule.
|
50
|
+
#
|
51
|
+
# Recipes that have multiline statements will have tabs inserted after each
|
52
|
+
# newline to ensure that the recipe is parsed as part of a single makefile rule.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
def format
|
56
|
+
s = @target + ":"
|
57
|
+
unless @dependencies.empty?
|
58
|
+
s << " " << @dependencies.join(" ")
|
59
|
+
end
|
60
|
+
s << "\n"
|
61
|
+
s << @recipe.map { |line| "\t" + line.gsub("\n", "\n\t") + "\n" }.join
|
62
|
+
s
|
63
|
+
end
|
64
|
+
|
65
|
+
alias to_s format
|
66
|
+
end
|
67
|
+
end
|
data/lib/vanagon/component.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
require 'vanagon/component/source'
|
2
2
|
require 'vanagon/component/dsl'
|
3
|
+
require 'vanagon/component/rules'
|
3
4
|
|
4
5
|
class Vanagon
|
5
6
|
class Component
|
6
7
|
# @!attribute [r] files
|
7
8
|
# @return [Set] the list of files marked for installation
|
8
9
|
|
9
|
-
attr_accessor :name, :version, :source, :url, :configure, :build, :install
|
10
|
-
attr_accessor :environment, :extract_with, :dirname, :build_requires
|
10
|
+
attr_accessor :name, :version, :source, :url, :configure, :build, :check, :install
|
11
|
+
attr_accessor :environment, :extract_with, :dirname, :build_requires, :build_dir
|
11
12
|
attr_accessor :settings, :platform, :patches, :requires, :service, :options
|
12
13
|
attr_accessor :directories, :replaces, :provides, :cleanup_source, :environment
|
13
14
|
attr_accessor :sources, :preinstall_actions, :postinstall_actions
|
@@ -50,6 +51,7 @@ class Vanagon
|
|
50
51
|
@configure = []
|
51
52
|
@install = []
|
52
53
|
@build = []
|
54
|
+
@check = []
|
53
55
|
@patches = []
|
54
56
|
@files = Set.new
|
55
57
|
@directories = []
|
@@ -121,6 +123,14 @@ class Vanagon
|
|
121
123
|
end
|
122
124
|
end
|
123
125
|
|
126
|
+
# Expands the build directory
|
127
|
+
def get_build_dir
|
128
|
+
if @build_dir
|
129
|
+
File.join(@dirname, @build_dir)
|
130
|
+
else
|
131
|
+
@dirname
|
132
|
+
end
|
133
|
+
end
|
124
134
|
|
125
135
|
# Fetches secondary sources for the component. These are just dumped into the workdir currently.
|
126
136
|
#
|
@@ -156,5 +166,9 @@ class Vanagon
|
|
156
166
|
"export #{env.join(' ')}"
|
157
167
|
end
|
158
168
|
end
|
169
|
+
|
170
|
+
def rules(project, platform)
|
171
|
+
Vanagon::Component::Rules.new(self, project, platform)
|
172
|
+
end
|
159
173
|
end
|
160
174
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'vanagon/component'
|
2
|
+
require 'vanagon/patch'
|
2
3
|
require 'ostruct'
|
3
4
|
require 'json'
|
4
5
|
|
@@ -56,13 +57,20 @@ class Vanagon
|
|
56
57
|
@component.configure << block.call
|
57
58
|
end
|
58
59
|
|
59
|
-
# Set or add to the build call for the component. The commands required to build the component before installing it.
|
60
|
+
# Set or add to the build call for the component. The commands required to build the component before testing/installing it.
|
60
61
|
#
|
61
62
|
# @param block [Proc] the command(s) required to build the component
|
62
63
|
def build(&block)
|
63
64
|
@component.build << block.call
|
64
65
|
end
|
65
66
|
|
67
|
+
# Set or add to the check call for the component. The commands required to test the component before installing it.
|
68
|
+
#
|
69
|
+
# @param block [Proc] the command(s) required to test the component
|
70
|
+
def check(&block)
|
71
|
+
@component.check << block.call
|
72
|
+
end
|
73
|
+
|
66
74
|
# Set or add to the install call for the component. The commands required to install the component.
|
67
75
|
#
|
68
76
|
# @param block [Proc] the command(s) required to install the component
|
@@ -80,10 +88,12 @@ class Vanagon
|
|
80
88
|
# Add a patch to the list of patches to apply to the component's source after unpacking
|
81
89
|
#
|
82
90
|
# @param patch [String] Path to the patch that should be applied
|
91
|
+
# @param destination [String] Path to the location where the patch should be applied
|
83
92
|
# @param strip [String, Integer] directory levels to skip in applying patch
|
84
93
|
# @param fuzz [String, Integer] levels of context miss to ignore in applying patch
|
85
|
-
|
86
|
-
|
94
|
+
# @param after [String] the location in the makefile where the patch command should be run
|
95
|
+
def apply_patch(patch, destination: @component.dirname, strip: 1, fuzz: 0, after: 'unpack')
|
96
|
+
@component.patches << Vanagon::Patch.new(patch, strip, fuzz, after, destination)
|
87
97
|
end
|
88
98
|
|
89
99
|
# Loads and parses json from a file. Will treat the keys in the
|
@@ -263,6 +273,27 @@ class Vanagon
|
|
263
273
|
@component.options[:ref] = the_ref
|
264
274
|
end
|
265
275
|
|
276
|
+
# Set a build dir relative to the source directory.
|
277
|
+
#
|
278
|
+
# The build dir will be created before the configure block runs and configure/build/install commands will be run
|
279
|
+
# in the build dir.
|
280
|
+
#
|
281
|
+
# @example
|
282
|
+
# pkg.build_dir "build"
|
283
|
+
# pkg.source "my-cmake-project" # Will create the path "my-cmake-project/build"
|
284
|
+
# pkg.configure { ["cmake .."] }
|
285
|
+
# pkg.build { ["make -j 3"] }
|
286
|
+
# pkg.install { ["make install"] }
|
287
|
+
#
|
288
|
+
# @param path [String] The build directory to use for building the project
|
289
|
+
def build_dir(path)
|
290
|
+
if Pathname.new(path).relative?
|
291
|
+
@component.build_dir = path
|
292
|
+
else
|
293
|
+
raise Vanagon::Error, "build_dir should be a relative path, but '#{path}' looks to be absolute."
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
266
297
|
# This will add a source to the project and put it in the workdir alongside the other sources
|
267
298
|
#
|
268
299
|
# @param url [String] url of the source
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'vanagon/component'
|
2
|
+
require 'vanagon/utilities/shell_utilities'
|
3
|
+
require 'makefile'
|
4
|
+
|
5
|
+
class Vanagon
|
6
|
+
class Component
|
7
|
+
# Vanagon::Component::Rules creates all Makefile rules for a given component.
|
8
|
+
class Rules
|
9
|
+
|
10
|
+
include Vanagon::Utilities::ShellUtilities
|
11
|
+
|
12
|
+
# Create methods that generate Makefile rules.
|
13
|
+
#
|
14
|
+
# This method cuts out some of the boilerplate of creating Makefile rules
|
15
|
+
# by creating methods and Makefile objects with a common name.
|
16
|
+
#
|
17
|
+
# @param target [Symbol] The rule target name.
|
18
|
+
# @param dependencies [Array<String>] An optional list of dependencies for the rule
|
19
|
+
# @yieldparam rule [Makefile::Rule] The generated Makefile rule
|
20
|
+
# @return [void]
|
21
|
+
#
|
22
|
+
# @!macro [attach] rule
|
23
|
+
# @return [Makefile::Rule] The $1 rule
|
24
|
+
def self.rule(target, dependencies: [], &block)
|
25
|
+
define_method("#{target}_rule") do
|
26
|
+
Makefile::Rule.new("#{@component.name}-#{target}", dependencies: dependencies) do |rule|
|
27
|
+
instance_exec(rule, &block)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param component [Vanagon::Component] The component to create rules for.
|
33
|
+
# @param project [Vanagon::Project] The project associated with the component.
|
34
|
+
# @param platform [Vanagon::Platform] The platform where this component will be built.
|
35
|
+
def initialize(component, project, platform)
|
36
|
+
@component = component
|
37
|
+
@project = project
|
38
|
+
@platform = platform
|
39
|
+
end
|
40
|
+
|
41
|
+
# Generate all Makefile rules for this component.
|
42
|
+
#
|
43
|
+
# If the project has the cleanup attribute set, a cleanup rule will be included
|
44
|
+
# in the returned rules.
|
45
|
+
#
|
46
|
+
# @return [Array<Makefile::Rule>]
|
47
|
+
def rules
|
48
|
+
list = [
|
49
|
+
component_rule,
|
50
|
+
unpack_rule,
|
51
|
+
patch_rule,
|
52
|
+
configure_rule,
|
53
|
+
build_rule,
|
54
|
+
check_rule,
|
55
|
+
install_rule,
|
56
|
+
clean_rule,
|
57
|
+
clobber_rule,
|
58
|
+
]
|
59
|
+
if @project.cleanup
|
60
|
+
list << cleanup_rule
|
61
|
+
end
|
62
|
+
|
63
|
+
list
|
64
|
+
end
|
65
|
+
|
66
|
+
# Generate a top level rule to build this component.
|
67
|
+
#
|
68
|
+
# @return [Makefile::Rule]
|
69
|
+
def component_rule
|
70
|
+
Makefile::Rule.new("#{@component.name}", dependencies: ["#{@component.name}-install"])
|
71
|
+
end
|
72
|
+
|
73
|
+
# Unpack the source for this component. The unpacking behavior depends on
|
74
|
+
# the source type of the component.
|
75
|
+
#
|
76
|
+
# @see [Vanagon::Component::Source]
|
77
|
+
rule("unpack", dependencies: ['file-list-before-build']) do |r|
|
78
|
+
r.recipe << andand(@component.get_environment, @component.extract_with)
|
79
|
+
r.recipe << "touch #{r.target}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# Apply any patches for this component.
|
83
|
+
rule("patch") do |r|
|
84
|
+
r.dependencies = ["#{@component.name}-unpack"]
|
85
|
+
|
86
|
+
after_unpack_patches = @component.patches.select { |patch| patch.after == "unpack" }
|
87
|
+
unless after_unpack_patches.empty?
|
88
|
+
r.recipe << andand_multiline(
|
89
|
+
"cd #{@component.dirname}",
|
90
|
+
after_unpack_patches.map { |patch| patch.cmd(@platform) }
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
r.recipe << "touch #{r.target}"
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create a build directory for this component if an out of source tree build is specified,
|
98
|
+
# and any configure steps, if any.
|
99
|
+
rule("configure") do |r|
|
100
|
+
r.dependencies = ["#{@component.name}-patch"].concat(@project.list_component_dependencies(@component))
|
101
|
+
|
102
|
+
if @component.get_build_dir
|
103
|
+
r.recipe << "[ -d #{@component.get_build_dir} ] || mkdir -p #{@component.get_build_dir}"
|
104
|
+
end
|
105
|
+
|
106
|
+
unless @component.configure.empty?
|
107
|
+
r.recipe << andand_multiline(
|
108
|
+
"cd #{@component.get_build_dir}",
|
109
|
+
@component.get_environment,
|
110
|
+
@component.configure
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
r.recipe << "touch #{r.target}"
|
115
|
+
end
|
116
|
+
|
117
|
+
# Build this component.
|
118
|
+
rule("build") do |r|
|
119
|
+
r.dependencies = ["#{@component.name}-configure"]
|
120
|
+
|
121
|
+
unless @component.build.empty?
|
122
|
+
r.recipe << andand_multiline(
|
123
|
+
"cd #{@component.get_build_dir}",
|
124
|
+
@component.get_environment,
|
125
|
+
@component.build
|
126
|
+
)
|
127
|
+
end
|
128
|
+
|
129
|
+
r.recipe << "touch #{r.target}"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Run tests for this component.
|
133
|
+
rule("check") do |r|
|
134
|
+
r.dependencies = ["#{@component.name}-build"]
|
135
|
+
|
136
|
+
unless @component.check.empty? || @project.settings[:skipcheck]
|
137
|
+
r.recipe << andand_multiline(
|
138
|
+
"cd #{@component.get_build_dir}",
|
139
|
+
@component.get_environment,
|
140
|
+
@component.check
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
r.recipe << "touch #{r.target}"
|
145
|
+
end
|
146
|
+
|
147
|
+
# Install this component.
|
148
|
+
rule("install") do |r|
|
149
|
+
r.dependencies = ["#{@component.name}-check"]
|
150
|
+
|
151
|
+
unless @component.install.empty?
|
152
|
+
r.recipe << andand_multiline(
|
153
|
+
"cd #{@component.get_build_dir}",
|
154
|
+
@component.get_environment,
|
155
|
+
@component.install
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
159
|
+
after_install_patches = @component.patches.select { |patch| patch.after == "install" }
|
160
|
+
after_install_patches.each do |patch|
|
161
|
+
r.recipe << andand(
|
162
|
+
"cd #{patch.destination}",
|
163
|
+
patch.cmd(@platform),
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
r.recipe << "touch #{r.target}"
|
168
|
+
end
|
169
|
+
|
170
|
+
# Run any post-installation cleanup steps for this component.
|
171
|
+
#
|
172
|
+
# This component is only included by {#rules} if the associated project has
|
173
|
+
# the `cleanup` attribute set.
|
174
|
+
rule("cleanup") do |r|
|
175
|
+
r.dependencies = ["#{@component.name}-install"]
|
176
|
+
r.recipe = [@component.cleanup_source, "touch #{r.target}"]
|
177
|
+
end
|
178
|
+
|
179
|
+
# Clean up any files generated while building this project.
|
180
|
+
#
|
181
|
+
# This cleans up the project by invoking `make clean` and removing the touch files
|
182
|
+
# for the configure/build/install steps.
|
183
|
+
rule("clean") do |r|
|
184
|
+
r.recipe << andand(
|
185
|
+
"[ -d #{@component.get_build_dir} ]",
|
186
|
+
"cd #{@component.get_build_dir}",
|
187
|
+
"#{@platform[:make]} clean"
|
188
|
+
)
|
189
|
+
|
190
|
+
%w(configure build install).each do |type|
|
191
|
+
touchfile = "#{@component.name}-#{type}"
|
192
|
+
r.recipe << andand(
|
193
|
+
"[ -e #{touchfile} ]",
|
194
|
+
"rm #{touchfile}"
|
195
|
+
)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Remove all files associated with this component.
|
200
|
+
rule("clobber") do |r|
|
201
|
+
r.dependencies = ["#{@component.name}-clean"]
|
202
|
+
r.recipe = [
|
203
|
+
andand("[ -d #{@component.dirname} ]", "rm -r #{@component.dirname}"),
|
204
|
+
andand("[ -e #{@component.name}-unpack ]", "rm #{@component.name}-unpack")
|
205
|
+
]
|
206
|
+
end
|
207
|
+
|
208
|
+
# Generate a Makefile fragment that contains all of the rules for the component.
|
209
|
+
# @return [String]
|
210
|
+
def format
|
211
|
+
rules.map(&:to_s).join("\n")
|
212
|
+
end
|
213
|
+
|
214
|
+
alias to_s format
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|