vanagon 0.35.1 → 0.37.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/makefile.rb +1 -1
- data/lib/vanagon/cli/build.rb +2 -3
- data/lib/vanagon/cli/dependencies.rb +33 -23
- data/lib/vanagon/cli/inspect.rb +1 -2
- data/lib/vanagon/cli/list.rb +27 -18
- data/lib/vanagon/common/user.rb +1 -0
- data/lib/vanagon/component/dsl.rb +6 -6
- data/lib/vanagon/component/source/git.rb +43 -12
- data/lib/vanagon/component/source/http.rb +3 -3
- data/lib/vanagon/component/source.rb +6 -5
- data/lib/vanagon/driver.rb +4 -4
- data/lib/vanagon/engine/always_be_scheduling.rb +23 -15
- data/lib/vanagon/engine/ec2.rb +1 -1
- data/lib/vanagon/engine/pooler.rb +3 -3
- data/lib/vanagon/environment.rb +13 -12
- data/lib/vanagon/errors.rb +0 -7
- data/lib/vanagon/logger.rb +3 -3
- data/lib/vanagon/platform/deb.rb +2 -2
- data/lib/vanagon/platform/defaults/ubuntu-22.04-amd64.rb +1 -0
- data/lib/vanagon/platform/rpm.rb +2 -2
- data/lib/vanagon/platform/solaris_10.rb +4 -4
- data/lib/vanagon/platform/windows.rb +6 -6
- data/lib/vanagon/platform.rb +2 -2
- data/lib/vanagon/project.rb +46 -18
- data/lib/vanagon/utilities.rb +3 -4
- data/lib/vanagon.rb +0 -4
- data/spec/lib/vanagon/component/source/git_spec.rb +107 -78
- data/spec/lib/vanagon/component/source_spec.rb +78 -4
- data/spec/lib/vanagon/engine/always_be_scheduling_spec.rb +98 -40
- data/spec/lib/vanagon/engine/ec2_spec.rb +12 -5
- data/spec/lib/vanagon/project_spec.rb +11 -4
- metadata +14 -52
- data/lib/vanagon/platform/defaults/el-7-aarch64.rb +0 -13
- data/lib/vanagon/platform/defaults/osx-10.15-x86_64.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b569137b6d209bf5bd4caa5d17063aa6779fb72b92dc33eb77acc35c47779de
|
4
|
+
data.tar.gz: 6b305a0234d8e5b68ee1a0c9ef46c1396f6ee43af941a60e3bf192fc1ab4c7f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 948f95345c029e5ff95212741a3d58e0c8b0bafe807996dcfb655ebf18374c7ed7b608edc88aac00b74ede53f20bb92d5a7c07214a1242c5c1d32e515144c79b
|
7
|
+
data.tar.gz: c555fad2d59dbe124168443ca5ec327bb9558d61c29cf96c07865bdd598fcc6f03c05cd69c0ab4dff3a040cc2883c69c9dca3ccc518e37d716cefafe94735d7b
|
data/lib/makefile.rb
CHANGED
data/lib/vanagon/cli/build.rb
CHANGED
@@ -61,7 +61,7 @@ class Vanagon
|
|
61
61
|
translations = {
|
62
62
|
'--verbose' => :verbose,
|
63
63
|
'--workdir' => :workdir,
|
64
|
-
'--remote-workdir' => :
|
64
|
+
'--remote-workdir' => :'remote-workdir',
|
65
65
|
'--configdir' => :configdir,
|
66
66
|
'--engine' => :engine,
|
67
67
|
'--skipcheck' => :skipcheck,
|
@@ -78,8 +78,7 @@ class Vanagon
|
|
78
78
|
# Handle --preserve option checking
|
79
79
|
valid_preserves = %w[always never on-failure]
|
80
80
|
unless valid_preserves.include? options[:preserve]
|
81
|
-
raise InvalidArgument, "--preserve option can only be one of: "
|
82
|
-
valid_preserves.join(', ')
|
81
|
+
raise InvalidArgument, "--preserve option can only be one of: #{valid_preserves.join(', ')}"
|
83
82
|
end
|
84
83
|
options[:preserve] = options[:preserve].to_sym
|
85
84
|
return options
|
@@ -28,29 +28,9 @@ class Vanagon
|
|
28
28
|
exit 1
|
29
29
|
end
|
30
30
|
|
31
|
-
def run(options)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
unless Dir.exist?(projects_directory) && Dir.exist?(platforms_directory)
|
36
|
-
VanagonLogger.error "Path to #{platforms_directory} or #{projects_directory} not found."
|
37
|
-
exit 1
|
38
|
-
end
|
39
|
-
|
40
|
-
projects = [options[:project_name]]
|
41
|
-
if projects.include?('all')
|
42
|
-
projects = Dir.children(projects_directory).map do |project|
|
43
|
-
File.basename(project, File.extname(project))
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
platforms = options[:platforms].split(',')
|
48
|
-
if platforms.include?('all')
|
49
|
-
platforms = Dir.children(platforms_directory).map do |platform|
|
50
|
-
File.basename(platform, File.extname(platform))
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
31
|
+
def run(options)
|
32
|
+
projects = get_projects(options)
|
33
|
+
platforms = get_platforms(options)
|
54
34
|
failures = []
|
55
35
|
|
56
36
|
projects.each do |project|
|
@@ -74,6 +54,36 @@ class Vanagon
|
|
74
54
|
VanagonLogger.info "Finished generating dependencies"
|
75
55
|
end
|
76
56
|
|
57
|
+
def get_projects(options)
|
58
|
+
platforms_directory = File.join(options[:configdir], 'platforms')
|
59
|
+
projects_directory = File.join(options[:configdir], 'projects')
|
60
|
+
|
61
|
+
unless Dir.exist?(projects_directory) && Dir.exist?(platforms_directory)
|
62
|
+
VanagonLogger.error "Path to #{platforms_directory} or #{projects_directory} not found."
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
|
66
|
+
projects = [options[:project_name]]
|
67
|
+
if projects.include?('all')
|
68
|
+
Dir.children(projects_directory).map do |project|
|
69
|
+
File.basename(project, File.extname(project))
|
70
|
+
end
|
71
|
+
else
|
72
|
+
projects
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_platforms(options)
|
77
|
+
platforms = options[:platforms].split(',')
|
78
|
+
if platforms.include?('all')
|
79
|
+
Dir.children(platforms_directory).map do |platform|
|
80
|
+
File.basename(platform, File.extname(platform))
|
81
|
+
end
|
82
|
+
else
|
83
|
+
platforms
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
77
87
|
def options_translate(docopt_options)
|
78
88
|
translations = {
|
79
89
|
'--verbose' => :verbose,
|
data/lib/vanagon/cli/inspect.rb
CHANGED
@@ -63,8 +63,7 @@ class Vanagon
|
|
63
63
|
# Handle --preserve option checking
|
64
64
|
valid_preserves = %w[always never on-failure]
|
65
65
|
unless valid_preserves.include? options[:preserve]
|
66
|
-
raise InvalidArgument, "--preserve option can only be one of: "
|
67
|
-
valid_preserves.join(', ')
|
66
|
+
raise InvalidArgument, "--preserve option can only be one of: #{valid_preserves.join(', ')}"
|
68
67
|
end
|
69
68
|
options[:preserve] = options[:preserve].to_sym
|
70
69
|
return options
|
data/lib/vanagon/cli/list.rb
CHANGED
@@ -30,24 +30,11 @@ class Vanagon
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def run(options) # rubocop:disable Metrics/AbcSize
|
33
|
-
|
34
|
-
Dir.exist?(File.join(options[:configdir], 'projects')) == false
|
33
|
+
check_directories(options)
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
default_list = Dir.children(File.join(File.dirname(__FILE__), '..', 'platform', 'defaults')).map do |platform|
|
41
|
-
File.basename(platform, File.extname(platform))
|
42
|
-
end.sort
|
43
|
-
|
44
|
-
platform_list = Dir.children(File.join(options[:configdir], 'platforms')).map do |platform|
|
45
|
-
File.basename(platform, File.extname(platform))
|
46
|
-
end.sort
|
47
|
-
|
48
|
-
project_list = Dir.children(File.join(options[:configdir], 'projects')).map do |project|
|
49
|
-
File.basename(project, File.extname(project))
|
50
|
-
end.sort
|
35
|
+
default_list = topic_list(File.dirname(__FILE__), '..', 'platform', 'defaults')
|
36
|
+
platform_list = topic_list(options[:configdir], 'platforms')
|
37
|
+
project_list = topic_list(options[:configdir], 'projects')
|
51
38
|
|
52
39
|
if options[:defaults]
|
53
40
|
puts "- Defaults", output(default_list, options[:use_spaces])
|
@@ -55,7 +42,8 @@ class Vanagon
|
|
55
42
|
end
|
56
43
|
|
57
44
|
if options[:projects] == options[:platforms]
|
58
|
-
puts "- Projects", output(project_list, options[:use_spaces]), "\n",
|
45
|
+
puts "- Projects", output(project_list, options[:use_spaces]), "\n",
|
46
|
+
"- Platforms", output(platform_list, options[:use_spaces])
|
59
47
|
return
|
60
48
|
end
|
61
49
|
|
@@ -70,6 +58,27 @@ class Vanagon
|
|
70
58
|
end
|
71
59
|
end
|
72
60
|
|
61
|
+
def check_directories(options)
|
62
|
+
platforms_directory = File.join(options[:configdir], 'platforms')
|
63
|
+
projects_directory = File.join(options[:configdir], 'projects')
|
64
|
+
|
65
|
+
unless Dir.exist?(platforms_directory)
|
66
|
+
VanagonLogger.error "Platforms directory \"#{platforms_directory}\" does not exist."
|
67
|
+
exit 1
|
68
|
+
end
|
69
|
+
|
70
|
+
unless Dir.exist?(projects_directory)
|
71
|
+
VanagonLogger.error "Projectss directory \"#{projects_directory}\" does not exist."
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def topic_list(*topic_path_items)
|
77
|
+
Dir.children(File.join(topic_path_items)).map do |t|
|
78
|
+
File.basename(t, File.extname(t))
|
79
|
+
end.sort
|
80
|
+
end
|
81
|
+
|
73
82
|
def options_translate(docopt_options)
|
74
83
|
translations = {
|
75
84
|
'--configdir' => :configdir,
|
data/lib/vanagon/common/user.rb
CHANGED
@@ -103,7 +103,7 @@ class Vanagon
|
|
103
103
|
# @raise [RuntimeError] exceptions are raised if there is no file,
|
104
104
|
# if it refers to methods that don't exist, or if it does not contain a Hash
|
105
105
|
def load_from_json(file)
|
106
|
-
if File.
|
106
|
+
if File.exist?(file)
|
107
107
|
data = JSON.parse(File.read(file))
|
108
108
|
raise "Hash required. Got '#{data.class}' when parsing '#{file}'" unless data.is_a?(Hash)
|
109
109
|
data.each do |key, value|
|
@@ -203,10 +203,10 @@ class Vanagon
|
|
203
203
|
# Return here because there is no file to install, just a string read in
|
204
204
|
return
|
205
205
|
when "windows"
|
206
|
-
@component.service << OpenStruct.new(\
|
206
|
+
@component.service << OpenStruct.new( \
|
207
207
|
:bindir_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '').upcase}BINDIR", \
|
208
208
|
:service_file => service_file, \
|
209
|
-
:component_group_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '')}Component"\
|
209
|
+
:component_group_id => "#{service_name.gsub(/[^A-Za-z0-9]/, '')}Component" \
|
210
210
|
)
|
211
211
|
# return here as we are just collecting the name of the service file to put into the harvest filter list.
|
212
212
|
return
|
@@ -392,15 +392,15 @@ class Vanagon
|
|
392
392
|
end
|
393
393
|
end
|
394
394
|
|
395
|
-
|
396
395
|
# This will add a source to the project and put it in the workdir alongside the other sources
|
397
396
|
#
|
398
397
|
# @param uri [String] uri of the source
|
399
398
|
# @param [Hash] options optional keyword arguments used to instatiate a new source
|
400
399
|
# @option opts [String] :sum
|
401
400
|
# @option opts [String] :ref
|
402
|
-
# @option opts [Bool] :erb set to 'true' to specify that the source file should be
|
403
|
-
|
401
|
+
# @option opts [Bool] :erb set to 'true' to specify that the source file should be
|
402
|
+
# translated by erb
|
403
|
+
def add_source(uri, options = {})
|
404
404
|
@component.sources << OpenStruct.new(options.merge({ url: uri }))
|
405
405
|
end
|
406
406
|
|
@@ -18,8 +18,7 @@ class Vanagon
|
|
18
18
|
|
19
19
|
class << self
|
20
20
|
# Attempt to connect to whatever URL is provided and
|
21
|
-
# return true or false
|
22
|
-
# `git` thinks it's a valid Git repo.
|
21
|
+
# return true or false base on a number of guesses of whether it's a valid Git repo.
|
23
22
|
#
|
24
23
|
# @param url [#to_s] A URI::HTTPS, URI:HTTP, or String with the the URL of the
|
25
24
|
# remote git repository.
|
@@ -27,21 +26,18 @@ class Vanagon
|
|
27
26
|
# git command has failed. Useful in instances where a URL
|
28
27
|
# prompts for credentials despite not being a git remote
|
29
28
|
# @return [Boolean] whether #url is a valid Git repo or not
|
30
|
-
|
31
|
-
# [RE-13837] This ought to be the way to do this. Unfortunately,
|
32
|
-
# there's a bug in Git.ls_remote that when ssh prints something like
|
33
|
-
# Warning: Permanently added 'github.com,192.30.255.113' (RSA)
|
34
|
-
# Git.ls_remote attempts to parse it as actual git output and fails
|
35
|
-
# with: NoMethodError: undefined method `split' for nil:NilClass
|
36
|
-
#
|
37
|
-
# We'll work around that case by calling 'git ls-remote' directly ourselves.
|
38
|
-
|
39
29
|
def valid_remote?(url, timeout = 0)
|
40
30
|
# RE-15209. To relieve github rate-limiting, if the URL starts with
|
41
31
|
# https://github.com/... just accept it rather than ping github over and over.
|
42
|
-
return
|
32
|
+
return github_remote?(url) if url.to_s.start_with?(github_url_prefix)
|
43
33
|
|
44
34
|
begin
|
35
|
+
# [RE-13837] there's a bug in Git.ls_remote that when ssh prints something like
|
36
|
+
# Warning: Permanently added 'github.com,192.30.255.113' (RSA)
|
37
|
+
# Git.ls_remote attempts to parse it as actual git output and fails
|
38
|
+
# with: NoMethodError: undefined method `split' for nil:NilClass
|
39
|
+
#
|
40
|
+
# Work around it by calling 'git ls-remote' directly ourselves.
|
45
41
|
Timeout.timeout(timeout) do
|
46
42
|
Vanagon::Utilities.local_command("git ls-remote --heads #{url} > /dev/null 2>&1")
|
47
43
|
$?.exitstatus.zero?
|
@@ -52,6 +48,41 @@ class Vanagon
|
|
52
48
|
false
|
53
49
|
end
|
54
50
|
end
|
51
|
+
|
52
|
+
def github_url_prefix
|
53
|
+
'https://github.com/'
|
54
|
+
end
|
55
|
+
|
56
|
+
def github_remote?(url)
|
57
|
+
github_source_type(url) == :github_remote
|
58
|
+
end
|
59
|
+
|
60
|
+
# VANAGON-227 We need to be careful when guessing whether a https://github.com/...
|
61
|
+
# URL is actually a true git repo. Make some rules around it based on the github API.
|
62
|
+
# Decide that anything with a documented media_type is just an http url.
|
63
|
+
# See:
|
64
|
+
# https://docs.github.com/en/repositories/working-with-files/using-files/downloading-source-code-archives
|
65
|
+
# https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#download-a-repository-archive-tar
|
66
|
+
# https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#download-a-repository-archive-zip
|
67
|
+
def github_source_type(url)
|
68
|
+
url_directory = url.to_s.delete_prefix(github_url_prefix)
|
69
|
+
url_components = url_directory.split('/')
|
70
|
+
|
71
|
+
return :github_remote if url_directory.end_with?('.git')
|
72
|
+
|
73
|
+
# Find cases of supported github media types.
|
74
|
+
# [ owner, repo, media_type, ref ]
|
75
|
+
case url_components[2]
|
76
|
+
when 'archive'
|
77
|
+
:github_archive
|
78
|
+
when 'tarball'
|
79
|
+
:github_tarball
|
80
|
+
when 'zipball'
|
81
|
+
:github_zipball
|
82
|
+
else
|
83
|
+
:github_remote
|
84
|
+
end
|
85
|
+
end
|
55
86
|
end
|
56
87
|
|
57
88
|
# Default options used when cloning; this may expand
|
@@ -17,7 +17,7 @@ class Vanagon
|
|
17
17
|
CHECKSUM_TYPES = %w[md5 sha1 sha256 sha512].freeze
|
18
18
|
|
19
19
|
class << self
|
20
|
-
def valid_url?(target_url)
|
20
|
+
def valid_url?(target_url)
|
21
21
|
uri = URI.parse(target_url.to_s)
|
22
22
|
return false unless ['http', 'https'].include? uri.scheme
|
23
23
|
|
@@ -49,7 +49,7 @@ class Vanagon
|
|
49
49
|
# @param workdir [String] working directory to download into
|
50
50
|
# @param sum_type [String] type of sum we are verifying
|
51
51
|
# @raise [RuntimeError] an exception is raised is sum is nil
|
52
|
-
def initialize(url, sum:, workdir:, sum_type:, **options)
|
52
|
+
def initialize(url, sum:, workdir:, sum_type:, **options)
|
53
53
|
unless sum
|
54
54
|
fail "sum is required to validate the http source"
|
55
55
|
end
|
@@ -93,7 +93,7 @@ class Vanagon
|
|
93
93
|
# Verify the downloaded file matches the provided sum
|
94
94
|
#
|
95
95
|
# @raise [RuntimeError] an exception is raised if the sum does not match the sum of the file
|
96
|
-
def verify
|
96
|
+
def verify
|
97
97
|
VanagonLogger.info "Verifying file: #{file} against sum: '#{sum}'"
|
98
98
|
actual = get_sum(File.join(workdir, file), sum_type)
|
99
99
|
return true if sum == actual
|
@@ -10,18 +10,18 @@ class Vanagon
|
|
10
10
|
SUPPORTED_PROTOCOLS = %w[file http https git].freeze
|
11
11
|
|
12
12
|
class << self
|
13
|
-
#
|
13
|
+
# Factory to hand back the correct {Vanagon::Component::Source} subtype to the component
|
14
14
|
#
|
15
|
-
# @param
|
15
|
+
# @param uri_instance [#to_s] URI of the source file (includes git@... style links)
|
16
16
|
# @param options [Hash] hash of the options needed for the subtype
|
17
17
|
# @param workdir [String] working directory to fetch the source into
|
18
18
|
# @return [Vanagon::Component::Source] the correct subtype for the given source
|
19
|
-
def source(
|
19
|
+
def source(uri_instance, **options) # rubocop:disable Metrics/AbcSize
|
20
20
|
# Sometimes the uri comes in as a string, but sometimes it's already been
|
21
21
|
# coerced into a URI object. The individual source providers will turn
|
22
22
|
# the passed uri into a URI object if needed, but for this method we
|
23
23
|
# want to work with the uri as a string.
|
24
|
-
uri =
|
24
|
+
uri = uri_instance.to_s
|
25
25
|
if uri.start_with?('git')
|
26
26
|
source_type = :git
|
27
27
|
# when using an http(s) source for a git repo, you should prefix the
|
@@ -68,7 +68,8 @@ class Vanagon
|
|
68
68
|
timeout = 5
|
69
69
|
if Vanagon::Component::Source::Git.valid_remote?(uri, timeout)
|
70
70
|
if uri =~ /^http/
|
71
|
-
VanagonLogger.
|
71
|
+
VanagonLogger.warn "Using http(s) URIs for github is deprecated. " \
|
72
|
+
"Use `git:` URI scheme instead."
|
72
73
|
end
|
73
74
|
return :git
|
74
75
|
end
|
data/lib/vanagon/driver.rb
CHANGED
@@ -42,7 +42,7 @@ class Vanagon
|
|
42
42
|
end
|
43
43
|
loginit('vanagon_hosts.log')
|
44
44
|
|
45
|
-
@remote_workdir = options[:
|
45
|
+
@remote_workdir = options[:'remote-workdir']
|
46
46
|
|
47
47
|
engine = pick_engine(options)
|
48
48
|
load_engine_object(engine, @platform, options[:target])
|
@@ -58,7 +58,7 @@ class Vanagon
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
def pick_engine(options)
|
61
|
+
def pick_engine(options)
|
62
62
|
if options[:engine] && !options[:target]
|
63
63
|
options[:engine]
|
64
64
|
elsif @platform.build_hosts
|
@@ -133,7 +133,7 @@ class Vanagon
|
|
133
133
|
# whole makefile. Instead just perform the installation.
|
134
134
|
make_target = ''
|
135
135
|
if @project.no_packaging
|
136
|
-
make_target = @project.name
|
136
|
+
make_target = "#{@project.name}-project"
|
137
137
|
end
|
138
138
|
|
139
139
|
@engine.startup(workdir)
|
@@ -171,7 +171,7 @@ class Vanagon
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
def render
|
174
|
+
def render
|
175
175
|
# Simple sanity check for the project
|
176
176
|
if @project.version.nil? || @project.version.empty?
|
177
177
|
raise Vanagon::Error, "Project requires a version set, all is lost."
|
@@ -223,13 +223,15 @@ class Vanagon
|
|
223
223
|
end
|
224
224
|
private :read_vmfloaty_token
|
225
225
|
|
226
|
-
#
|
227
|
-
#
|
228
|
-
# engines using similar APIs
|
226
|
+
# Used to obtain a vm to build upon using Puppet's internal ABS
|
227
|
+
# (https://github.com/puppetlabs/always-be-scheduling) which is
|
228
|
+
# a level of abstraction for other engines using similar APIs
|
229
229
|
# @raise [Vanagon::Error] if a target cannot be obtained
|
230
230
|
def select_target
|
231
231
|
@pooler = select_target_from(@available_abs_endpoint)
|
232
|
-
|
232
|
+
if @pooler.empty?
|
233
|
+
raise Vanagon::Error, "No available ABS machine from #{@available_abs_endpoint}"
|
234
|
+
end
|
233
235
|
end
|
234
236
|
|
235
237
|
# Attempt to provision a host from a specific pooler.
|
@@ -264,7 +266,8 @@ class Vanagon
|
|
264
266
|
# main loop where the status of the request is checked, to see if the request
|
265
267
|
# has been allocated
|
266
268
|
def check_queue(pooler, request_object)
|
267
|
-
|
269
|
+
# 360 retries takes about an hour
|
270
|
+
retries = 360
|
268
271
|
response_body = nil
|
269
272
|
begin
|
270
273
|
(1..retries).each do |i|
|
@@ -279,28 +282,32 @@ class Vanagon
|
|
279
282
|
|
280
283
|
sleep_seconds = 10 if i >= 10
|
281
284
|
sleep_seconds = i if i < 10
|
282
|
-
VanagonLogger.info "Waiting #{sleep_seconds} seconds to
|
285
|
+
VanagonLogger.info "Waiting #{sleep_seconds} seconds to fill ABS request (x#{i})"
|
283
286
|
|
284
287
|
sleep(sleep_seconds)
|
285
288
|
end
|
286
289
|
rescue SystemExit, Interrupt
|
287
|
-
VanagonLogger.error "\nVanagon interrupted during mains ABS polling.
|
290
|
+
VanagonLogger.error "\nVanagon interrupted during mains ABS polling. " \
|
291
|
+
"Remember to delete the requested job_id #{@saved_job_id}"
|
288
292
|
raise
|
289
293
|
end
|
290
|
-
|
291
|
-
response_body
|
294
|
+
|
295
|
+
if response_body
|
296
|
+
translated(response_body, @saved_job_id)
|
297
|
+
else
|
298
|
+
VanagonLogger.error "ABS timed out after #{retries} retries."
|
299
|
+
{ 'retry-failure': retries }
|
300
|
+
end
|
292
301
|
end
|
293
302
|
|
294
303
|
def validate_queue_status_response(status_code, body)
|
295
304
|
case status_code
|
296
305
|
when "200"
|
297
306
|
return JSON.parse(body) unless body.empty? || !valid_json?(body)
|
298
|
-
when "202"
|
307
|
+
when "202", "503"
|
299
308
|
return nil
|
300
309
|
when "401"
|
301
310
|
raise Vanagon::Error, "HTTP #{status_code}: The token provided could not authenticate.\n#{body}"
|
302
|
-
when "503"
|
303
|
-
return nil
|
304
311
|
else
|
305
312
|
raise Vanagon::Error, "HTTP #{status_code}: request to ABS failed!\n#{body}"
|
306
313
|
end
|
@@ -309,7 +316,7 @@ class Vanagon
|
|
309
316
|
# This method is used to tell the ABS to delete the job_id requested
|
310
317
|
# otherwise the resources will eventually get allocated asynchronously
|
311
318
|
# and will keep running until the end of their lifetime.
|
312
|
-
def teardown
|
319
|
+
def teardown
|
313
320
|
request_object = {
|
314
321
|
'job_id' => @saved_job_id,
|
315
322
|
}
|
@@ -337,7 +344,8 @@ class Vanagon
|
|
337
344
|
def translated(response_body, job_id)
|
338
345
|
vmpooler_formatted_body = { 'job_id' => job_id }
|
339
346
|
|
340
|
-
|
347
|
+
# in this context there should be only one host
|
348
|
+
response_body.each do |host|
|
341
349
|
vmpooler_formatted_body[host['type']] = { 'hostname' => host['hostname'] }
|
342
350
|
end
|
343
351
|
vmpooler_formatted_body['ok'] = true
|
@@ -348,7 +356,7 @@ class Vanagon
|
|
348
356
|
def build_request_object
|
349
357
|
user = ENV['USER'] || ENV['USERNAME'] || 'vanagon'
|
350
358
|
|
351
|
-
@saved_job_id = user
|
359
|
+
@saved_job_id = "#{user}-#{DateTime.now.strftime('%Q')}"
|
352
360
|
request_object = {
|
353
361
|
:resources => { build_host_name => 1 },
|
354
362
|
:job => {
|
data/lib/vanagon/engine/ec2.rb
CHANGED
@@ -10,7 +10,7 @@ class Vanagon
|
|
10
10
|
attr_accessor :ami, :key_name, :userdata, :key, :shutdown_behavior
|
11
11
|
attr_accessor :subnet_id, :instance_type
|
12
12
|
|
13
|
-
def initialize(platform, target = nil, **opts)
|
13
|
+
def initialize(platform, target = nil, **opts)
|
14
14
|
super
|
15
15
|
|
16
16
|
@ami = @platform.aws_ami
|
@@ -97,11 +97,11 @@ class Vanagon
|
|
97
97
|
|
98
98
|
# Attempt to provision a host from a specific pooler.
|
99
99
|
#
|
100
|
-
def select_target_from(pooler)
|
100
|
+
def select_target_from(pooler)
|
101
101
|
response = Vanagon::Utilities.http_request(
|
102
102
|
"#{pooler}/vm",
|
103
103
|
'POST',
|
104
|
-
|
104
|
+
"{\"#{build_host_name}\":\"1\"}",
|
105
105
|
{ 'X-AUTH-TOKEN' => @token }
|
106
106
|
)
|
107
107
|
if response["ok"]
|
@@ -110,7 +110,7 @@ class Vanagon
|
|
110
110
|
# in the future we should make the two APIs the same in this sense, but for now, just check
|
111
111
|
# if 'domain' is a thing and use it if so.
|
112
112
|
if response['domain']
|
113
|
-
@target +=
|
113
|
+
@target += ".#{response['domain']}"
|
114
114
|
end
|
115
115
|
Vanagon::Driver.logger.info "Reserving #{@target} (#{build_host_name}) [#{@token ? 'token used' : 'no token used'}]"
|
116
116
|
add_tags_to_target(pooler, response[build_host_name]['hostname'])
|
data/lib/vanagon/environment.rb
CHANGED
@@ -176,21 +176,22 @@ class Vanagon
|
|
176
176
|
# @param key [Object]
|
177
177
|
# @raise [ArgumentError] if key is not a String, if key contains invalid
|
178
178
|
# characters, or if key begins with a digit
|
179
|
-
def validate_key(
|
180
|
-
|
179
|
+
def validate_key(key)
|
180
|
+
environment_string = key.to_s
|
181
181
|
|
182
|
-
if
|
183
|
-
raise ArgumentError,
|
184
|
-
'environment variable Name cannot begin with a digit'
|
182
|
+
if environment_string[0] =~ /\d/
|
183
|
+
raise ArgumentError, 'environment variable Name cannot begin with a digit'
|
185
184
|
end
|
186
185
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
186
|
+
invalid_characters = environment_string
|
187
|
+
.scan(/[^\w]/)
|
188
|
+
.uniq
|
189
|
+
.map { |char| %("#{char}") }
|
190
|
+
.join(', ')
|
191
|
+
|
192
|
+
return environment_string if invalid_characters.empty?
|
193
|
+
raise ArgumentError,
|
194
|
+
"environment variable Name contains invalid characters: #{invalid_characters}"
|
194
195
|
end
|
195
196
|
private :validate_key
|
196
197
|
|
data/lib/vanagon/errors.rb
CHANGED
data/lib/vanagon/logger.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
|
-
class VanagonLogger <
|
3
|
+
class VanagonLogger < Logger
|
4
4
|
def self.logger
|
5
5
|
@@logger ||= VanagonLogger.new
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.debug_logger
|
9
|
-
@@debug_logger ||= VanagonLogger.new(
|
9
|
+
@@debug_logger ||= VanagonLogger.new($stderr)
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.info(msg)
|
@@ -21,7 +21,7 @@ class VanagonLogger < ::Logger
|
|
21
21
|
VanagonLogger.logger.error msg
|
22
22
|
end
|
23
23
|
|
24
|
-
def initialize(output =
|
24
|
+
def initialize(output = $stdout)
|
25
25
|
super(output)
|
26
26
|
self.level = ::Logger::INFO
|
27
27
|
self.formatter = proc do |severity, datetime, progname, msg|
|
data/lib/vanagon/platform/deb.rb
CHANGED
@@ -21,7 +21,7 @@ class Vanagon
|
|
21
21
|
"cat file-list >> debian/install",
|
22
22
|
"cp -pr debian $(tempdir)/#{project.name}-#{project.version}",
|
23
23
|
"gunzip -c #{project.name}-#{project.version}.tar.gz | '#{@tar}' -C '$(tempdir)/#{project.name}-#{project.version}' --strip-components 1 -xf -",
|
24
|
-
"#{sed} -i 's
|
24
|
+
"#{sed} -i 's/ /?/g' $(tempdir)/#{project.name}-#{project.version}/debian/install",
|
25
25
|
"(cd $(tempdir)/#{project.name}-#{project.version}; debuild --no-lintian #{pkg_arch_opt} -uc -us)",
|
26
26
|
"cp $(tempdir)/#{copy_extensions} ./output/#{target_dir}"]
|
27
27
|
end
|
@@ -125,7 +125,7 @@ class Vanagon
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def version_munger(version_string, default: '=')
|
128
|
-
operator, version = super.split
|
128
|
+
operator, version = super.split
|
129
129
|
if operator =~ /^[<>]$/
|
130
130
|
operator = "#{operator}#{operator}"
|
131
131
|
end
|
@@ -6,6 +6,7 @@ platform "ubuntu-22.04-amd64" do |plat|
|
|
6
6
|
|
7
7
|
packages = %w(build-essential devscripts make quilt pkg-config debhelper rsync fakeroot cmake)
|
8
8
|
plat.provision_with "export DEBIAN_FRONTEND=noninteractive; apt-get update -qq; apt-get install -qy --no-install-recommends #{packages.join(' ')}"
|
9
|
+
plat.provision_with "curl https://apt.puppet.com/DEB-GPG-KEY-puppet-20250406 | apt-key add -"
|
9
10
|
plat.install_build_dependencies_with "DEBIAN_FRONTEND=noninteractive; apt-get install -qy --no-install-recommends "
|
10
11
|
plat.vmpooler_template "ubuntu-2204-x86_64"
|
11
12
|
end
|