vanagon 0.4.1 → 0.5.0
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 +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
|