vanagon 0.36.0 → 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/vanagon/component/source/git.rb +43 -12
- data/lib/vanagon/component/source.rb +6 -5
- data/lib/vanagon/engine/always_be_scheduling.rb +20 -9
- data/lib/vanagon/platform/defaults/ubuntu-22.04-amd64.rb +1 -0
- 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
- metadata +2 -4
- 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
|
@@ -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
|
@@ -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
|
@@ -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,15 +282,22 @@ 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
|
-
|
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
|
291
301
|
end
|
292
302
|
|
293
303
|
def validate_queue_status_response(status_code, body)
|
@@ -334,7 +344,8 @@ class Vanagon
|
|
334
344
|
def translated(response_body, job_id)
|
335
345
|
vmpooler_formatted_body = { 'job_id' => job_id }
|
336
346
|
|
337
|
-
|
347
|
+
# in this context there should be only one host
|
348
|
+
response_body.each do |host|
|
338
349
|
vmpooler_formatted_body[host['type']] = { 'hostname' => host['hostname'] }
|
339
350
|
end
|
340
351
|
vmpooler_formatted_body['ok'] = true
|
@@ -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
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'vanagon/component/source/git'
|
2
2
|
|
3
3
|
describe "Vanagon::Component::Source::Git" do
|
4
|
-
# before(:all) blocks are run once before all of the examples in a group
|
5
4
|
before :all do
|
6
5
|
@klass = Vanagon::Component::Source::Git
|
7
6
|
# This repo will not be cloned over the network
|
@@ -12,106 +11,136 @@ describe "Vanagon::Component::Source::Git" do
|
|
12
11
|
@workdir = nil
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
.to receive(:valid_remote?)
|
19
|
-
.and_return(true)
|
20
|
-
|
21
|
-
allow(File).to receive(:realpath).and_return(@workdir)
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "#initialize" do
|
25
|
-
it "raises error on initialization with an invalid repo" do
|
26
|
-
# Ensure initializing a repo fails without calling over the network
|
27
|
-
allow(Vanagon::Component::Source::Git)
|
28
|
-
.to receive(:valid_remote?)
|
29
|
-
.and_return(false)
|
30
|
-
|
31
|
-
expect { @klass.new(@url, ref: @ref_tag, workdir: @workdir) }
|
32
|
-
.to raise_error(Vanagon::InvalidRepo)
|
14
|
+
context 'with a github https: URI' do
|
15
|
+
let(:github_archive_uri) do
|
16
|
+
'https://github.com/2ndQuadrant/pglogical/archive/a_file_name.tar.gz'
|
33
17
|
end
|
34
|
-
|
35
|
-
|
36
|
-
expect(File).to receive(:realpath).and_return("/tmp/bar")
|
37
|
-
git_source = @klass.new(@local_url, ref: @ref_tag, workdir: "/tmp/foo")
|
38
|
-
expect(git_source.workdir)
|
39
|
-
.to eq('/tmp/bar')
|
18
|
+
let(:github_tarball_uri) do
|
19
|
+
'https://github.com/Baeldung/kotlin-tutorials/tarball/main'
|
40
20
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
21
|
+
let(:github_zipball_uri) do
|
22
|
+
'https://github.com/Baeldung/kotlin-tutorials/zipball/master'
|
23
|
+
end
|
24
|
+
let(:github_repo_uri) do
|
25
|
+
'https://github.com/cameronmcnz/rock-paper-scissors'
|
26
|
+
end
|
27
|
+
let(:github_repo_dotgit_uri) do
|
28
|
+
'https://github.com/cameronmcnz/rock-paper-scissors.git'
|
46
29
|
end
|
47
30
|
|
48
|
-
it "
|
49
|
-
|
50
|
-
git_source = @klass.new(@local_url, ref: @ref_tag, workdir: "/tmp/foo", :clone_options => expected_clone_options)
|
51
|
-
expect(git_source.clone_options)
|
52
|
-
.to be(expected_clone_options)
|
31
|
+
it "flags github archive uris as not valid repos" do
|
32
|
+
expect(Vanagon::Component::Source::Git.valid_remote?(github_archive_uri)).to be false
|
53
33
|
end
|
54
|
-
end
|
55
34
|
|
56
|
-
|
57
|
-
|
58
|
-
clone = double(Git::Base)
|
59
|
-
@file_path = "/tmp/foo"
|
60
|
-
allow(::Git).to receive(:clone).and_return(clone)
|
61
|
-
expect(File).to receive(:realpath).and_return(@file_path)
|
35
|
+
it "flags github tarball uris as not valid repos" do
|
36
|
+
expect(Vanagon::Component::Source::Git.valid_remote?(github_tarball_uri)).to be false
|
62
37
|
end
|
63
38
|
|
64
|
-
it "
|
65
|
-
|
66
|
-
expect(::Git).to receive(:clone).with(git_source.url, git_source.dirname, path: @file_path)
|
67
|
-
git_source.clone
|
39
|
+
it "flags git zipball uris as not valid repos" do
|
40
|
+
expect(Vanagon::Component::Source::Git.valid_remote?(github_zipball_uri)).to be false
|
68
41
|
end
|
69
42
|
|
70
|
-
it "
|
71
|
-
|
72
|
-
git_source = @klass.new(@url, ref: @ref_tag, workdir: "/tmp/foo", :clone_options => expected_clone_options)
|
73
|
-
expect(::Git).to receive(:clone).with(git_source.url, git_source.dirname, path: @file_path, **expected_clone_options)
|
74
|
-
git_source.clone
|
43
|
+
it "identifies git generic uris as valid repos" do
|
44
|
+
expect(Vanagon::Component::Source::Git.valid_remote?(github_repo_uri)).to be true
|
75
45
|
end
|
76
46
|
|
77
|
-
it
|
78
|
-
|
79
|
-
expect(::Git).to receive(:clone).with(git_source.url, 'facter-ng', path: @file_path)
|
80
|
-
git_source.clone
|
47
|
+
it "identifies .git repo uris as valid repos" do
|
48
|
+
expect(Vanagon::Component::Source::Git.valid_remote?(github_repo_dotgit_uri)).to be true
|
81
49
|
end
|
82
50
|
end
|
83
51
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
.to eq('puppet-agent')
|
52
|
+
context 'with other non-github URIs' do
|
53
|
+
before :each do
|
54
|
+
allow(Vanagon::Component::Source::Git).to receive(:valid_remote?).and_return(true)
|
55
|
+
allow(File).to receive(:realpath).and_return(@workdir)
|
89
56
|
end
|
90
57
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
.to
|
58
|
+
describe "#initialize" do
|
59
|
+
it "raises error on initialization with an invalid repo" do
|
60
|
+
# Ensure initializing a repo fails without calling over the network
|
61
|
+
allow(Vanagon::Component::Source::Git).to receive(:valid_remote?).and_return(false)
|
62
|
+
|
63
|
+
expect { @klass.new(@url, ref: @ref_tag, workdir: @workdir) }
|
64
|
+
.to raise_error(Vanagon::InvalidRepo)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "uses the realpath of the workdir if we're in a symlinked dir" do
|
68
|
+
expect(File).to receive(:realpath).and_return("/tmp/bar")
|
69
|
+
git_source = @klass.new(@local_url, ref: @ref_tag, workdir: "/tmp/foo")
|
70
|
+
expect(git_source.workdir).to eq('/tmp/bar')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "with no clone options should be empty" do
|
74
|
+
git_source = @klass.new(@local_url, ref: @ref_tag, workdir: "/tmp/foo")
|
75
|
+
expect(git_source.clone_options).to be {}
|
76
|
+
end
|
77
|
+
|
78
|
+
it "add clone options depth and branch" do
|
79
|
+
expected_clone_options = {branch: 'bar', depth: 50 }
|
80
|
+
git_source = @klass.new(@local_url, ref: @ref_tag,
|
81
|
+
workdir: "/tmp/foo", clone_options: expected_clone_options)
|
82
|
+
expect(git_source.clone_options).to be(expected_clone_options)
|
83
|
+
end
|
95
84
|
end
|
96
85
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
86
|
+
describe "#clone" do
|
87
|
+
before :each do
|
88
|
+
clone = double(Git::Base)
|
89
|
+
@file_path = "/tmp/foo"
|
90
|
+
allow(Git).to receive(:clone).and_return(clone)
|
91
|
+
expect(File).to receive(:realpath).and_return(@file_path)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "repository" do
|
95
|
+
git_source = @klass.new(@url, ref: @ref_tag, workdir: "/tmp/foo")
|
96
|
+
expect(Git).to receive(:clone).with(git_source.url, git_source.dirname, path: @file_path)
|
97
|
+
git_source.clone
|
98
|
+
end
|
99
|
+
|
100
|
+
it "a particular branch with a depth" do
|
101
|
+
expected_clone_options = {:branch => "foo", :depth => 50 }
|
102
|
+
git_source = @klass.new(@url, ref: @ref_tag, workdir: "/tmp/foo",
|
103
|
+
clone_options: expected_clone_options)
|
104
|
+
expect(Git)
|
105
|
+
.to receive(:clone)
|
106
|
+
.with(git_source.url, git_source.dirname, path: @file_path, **expected_clone_options)
|
107
|
+
git_source.clone
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'uses a custom dirname' do
|
111
|
+
git_source = @klass.new(@url, ref: @ref_tag, workdir: "/tmp/foo", dirname: 'facter-ng')
|
112
|
+
expect(Git).to receive(:clone).with(git_source.url, 'facter-ng', path: @file_path)
|
113
|
+
git_source.clone
|
114
|
+
end
|
101
115
|
end
|
102
|
-
end
|
103
116
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
117
|
+
describe "#dirname" do
|
118
|
+
it "returns the name of the repo" do
|
119
|
+
git_source = @klass.new(@local_url, ref: @ref_tag, workdir: @workdir)
|
120
|
+
expect(git_source.dirname).to eq('puppet-agent')
|
121
|
+
end
|
122
|
+
|
123
|
+
it "returns the name of the repo and strips .git" do
|
124
|
+
git_source = @klass.new(@url, ref: @ref_tag, workdir: @workdir)
|
125
|
+
expect(git_source.dirname).to eq('facter')
|
126
|
+
end
|
127
|
+
|
128
|
+
it "returns @dirname if is set" do
|
129
|
+
git_source = @klass.new(@url, ref: @ref_tag, workdir: @workdir, dirname: 'facter-ng')
|
130
|
+
expect(git_source.dirname).to eq('facter-ng')
|
131
|
+
end
|
109
132
|
end
|
110
133
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
.to eq('HEAD')
|
134
|
+
describe "#ref" do
|
135
|
+
it "returns a default value of HEAD when no explicit Git reference is provided" do
|
136
|
+
git_source = @klass.new(@url, workdir: @workdir)
|
137
|
+
expect(git_source.ref).to eq('HEAD')
|
138
|
+
end
|
139
|
+
|
140
|
+
it "returns a default value of HEAD when Git reference is nil" do
|
141
|
+
git_source = @klass.new(@url, ref: nil, workdir: @workdir)
|
142
|
+
expect(git_source.ref).to eq('HEAD')
|
143
|
+
end
|
115
144
|
end
|
116
145
|
end
|
117
146
|
end
|
@@ -36,7 +36,7 @@ describe "Vanagon::Component::Source" do
|
|
36
36
|
.to raise_error(URI::InvalidURIError)
|
37
37
|
end
|
38
38
|
|
39
|
-
context "
|
39
|
+
context "with a Git repo" do
|
40
40
|
before do
|
41
41
|
allow_any_instance_of(Vanagon::Component::Source::Git)
|
42
42
|
.to receive(:valid_remote?)
|
@@ -64,12 +64,16 @@ describe "Vanagon::Component::Source" do
|
|
64
64
|
|
65
65
|
it "returns a Git object for git:http:// repositories" do
|
66
66
|
component_source = klass.source(git_prefixed_http, ref: ref, workdir: workdir)
|
67
|
-
expect(component_source.url.to_s).to eq 'http://github.com/abcd/things'
|
68
67
|
expect(component_source.class).to eq Vanagon::Component::Source::Git
|
69
68
|
end
|
69
|
+
|
70
|
+
it "returns a Git url for git:http:// repositories" do
|
71
|
+
component_source = klass.source(git_prefixed_http, ref: ref, workdir: workdir)
|
72
|
+
expect(component_source.url.to_s).to eq 'http://github.com/abcd/things'
|
73
|
+
end
|
70
74
|
end
|
71
75
|
|
72
|
-
context "
|
76
|
+
context "with a HTTP/HTTPS file" do
|
73
77
|
before do
|
74
78
|
allow(Vanagon::Component::Source::Http)
|
75
79
|
.to receive(:valid_url?)
|
@@ -96,7 +100,7 @@ describe "Vanagon::Component::Source" do
|
|
96
100
|
end
|
97
101
|
end
|
98
102
|
|
99
|
-
context "
|
103
|
+
context "with a local file" do
|
100
104
|
before do
|
101
105
|
allow_any_instance_of(Vanagon::Component::Source::Local)
|
102
106
|
.to receive(:valid_file?)
|
@@ -113,4 +117,74 @@ describe "Vanagon::Component::Source" do
|
|
113
117
|
end
|
114
118
|
end
|
115
119
|
end
|
120
|
+
|
121
|
+
describe "#determine_source_type" do
|
122
|
+
context 'with a github https: URI' do
|
123
|
+
|
124
|
+
let(:github_archive_uri) do
|
125
|
+
'https://github.com/2ndQuadrant/pglogical/archive/a_file_name.tar.gz'
|
126
|
+
end
|
127
|
+
let(:github_tarball_uri) do
|
128
|
+
'https://github.com/Baeldung/kotlin-tutorials/tarball/main'
|
129
|
+
end
|
130
|
+
let(:github_zipball_uri) do
|
131
|
+
'https://github.com/Baeldung/kotlin-tutorials/zipball/master'
|
132
|
+
end
|
133
|
+
let(:github_repo_uri) do
|
134
|
+
'https://github.com/cameronmcnz/rock-paper-scissors'
|
135
|
+
end
|
136
|
+
let(:github_repo_dotgit_uri) do
|
137
|
+
'https://github.com/cameronmcnz/rock-paper-scissors.git'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "identifies github archive uris" do
|
141
|
+
stub_request(:head, github_archive_uri).with(
|
142
|
+
headers: {
|
143
|
+
'Accept' => '*/*',
|
144
|
+
'Host' => 'github.com',
|
145
|
+
'User-Agent' => 'Ruby'
|
146
|
+
}
|
147
|
+
).to_return(status: 200, body: "", headers: {})
|
148
|
+
|
149
|
+
expect(Vanagon::Component::Source.determine_source_type(github_archive_uri))
|
150
|
+
.to eq(:http)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "identifies github tarball uris" do
|
154
|
+
stub_request(:head, github_tarball_uri).with(
|
155
|
+
headers: {
|
156
|
+
'Accept' => '*/*',
|
157
|
+
'Host' => 'github.com',
|
158
|
+
'User-Agent' => 'Ruby'
|
159
|
+
}
|
160
|
+
).to_return(status: 200, body: "", headers: {})
|
161
|
+
|
162
|
+
expect(Vanagon::Component::Source.determine_source_type(github_tarball_uri))
|
163
|
+
.to eq(:http)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "identifies github zipball uris" do
|
167
|
+
stub_request(:head, github_zipball_uri).with(
|
168
|
+
headers: {
|
169
|
+
'Accept' => '*/*',
|
170
|
+
'Host' => 'github.com',
|
171
|
+
'User-Agent' => 'Ruby'
|
172
|
+
}
|
173
|
+
).to_return(status: 200, body: "", headers: {})
|
174
|
+
|
175
|
+
expect(Vanagon::Component::Source.determine_source_type(github_zipball_uri))
|
176
|
+
.to eq(:http)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "identifies github generic repo uris" do
|
180
|
+
expect(Vanagon::Component::Source.determine_source_type(github_repo_uri))
|
181
|
+
.to eq(:git)
|
182
|
+
end
|
183
|
+
|
184
|
+
it "identifies github .git repo uris" do
|
185
|
+
expect(Vanagon::Component::Source.determine_source_type(github_repo_dotgit_uri))
|
186
|
+
.to eq(:git)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
116
190
|
end
|
@@ -128,75 +128,133 @@ describe 'Vanagon::Engine::AlwaysBeScheduling' do
|
|
128
128
|
|
129
129
|
end
|
130
130
|
token_value = 'decade'
|
131
|
-
|
131
|
+
|
132
|
+
it 'reads a token from "~/.vmfloaty.yml" at the top level' do
|
132
133
|
allow(YAML).to receive(:load_file)
|
133
|
-
|
134
|
-
|
135
|
-
allow(ENV).to receive(:[])
|
134
|
+
.with(floaty_config)
|
135
|
+
.and_return({ 'token' => token_value })
|
136
136
|
allow(ENV).to receive(:[])
|
137
|
-
|
138
|
-
.and_return(nil)
|
139
|
-
|
137
|
+
allow(ENV).to receive(:[]).with('VMPOOLER_TOKEN').and_return(nil)
|
140
138
|
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
141
139
|
expect(abs_service.token).to eq(token_value)
|
142
|
-
expect(abs_service.token_vmpooler).to eq(nil)
|
143
140
|
end
|
144
|
-
|
141
|
+
|
142
|
+
it 'reads a token from "~/.vmfloaty.yml" in the abs service' do
|
143
|
+
vmp_token_value = 'deecade'
|
145
144
|
allow(YAML).to receive(:load_file)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
145
|
+
.with(floaty_config)
|
146
|
+
.and_return(
|
147
|
+
{
|
148
|
+
'services' => {
|
149
|
+
'MYabs' => {
|
150
|
+
'type' => 'abs',
|
151
|
+
'token' => token_value,
|
152
|
+
'url' => 'foo',
|
153
|
+
'vmpooler_fallback' => 'myvmp'
|
154
|
+
},
|
155
|
+
'myvmp' => { 'token' => vmp_token_value, 'url' => 'bar' }
|
156
|
+
}
|
157
|
+
}
|
158
|
+
)
|
154
159
|
|
155
160
|
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
156
161
|
expect(abs_service.token).to eq(token_value)
|
157
|
-
expect(abs_service.token_vmpooler).to eq(nil)
|
158
162
|
end
|
159
|
-
|
163
|
+
|
164
|
+
it 'reads a token from "~/.vmfloaty.yml" and includes the vmpooler token' do
|
160
165
|
vmp_token_value = 'deecade'
|
161
166
|
allow(YAML).to receive(:load_file)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
+
.with(floaty_config)
|
168
|
+
.and_return(
|
169
|
+
{
|
170
|
+
'services' => {
|
171
|
+
'MYabs' => {
|
172
|
+
'type' => 'abs',
|
173
|
+
'token' => token_value,
|
174
|
+
'url' => 'foo',
|
175
|
+
'vmpooler_fallback' => 'myvmp'
|
176
|
+
},
|
177
|
+
'myvmp' => { 'token' => vmp_token_value, 'url' => 'bar' }
|
178
|
+
}
|
179
|
+
}
|
180
|
+
)
|
167
181
|
|
168
182
|
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
169
|
-
expect(abs_service.token).to eq(token_value)
|
170
183
|
expect(abs_service.token_vmpooler).to eq(vmp_token_value)
|
171
184
|
end
|
172
185
|
end
|
186
|
+
|
173
187
|
describe '#select_target_from' do
|
174
188
|
it 'runs successfully' do
|
175
189
|
hostname = 'faint-whirlwind.puppet.com'
|
176
|
-
stub_request(:post,
|
177
|
-
|
190
|
+
stub_request(:post, 'https://foobar/request')
|
191
|
+
.to_return(
|
192
|
+
{ status: 202, body: "", headers: {} },
|
193
|
+
{
|
194
|
+
status: 200,
|
195
|
+
body: [{ 'hostname' => hostname, 'type' => 'aix-6.1-ppc', 'engine' => 'nspooler' }]
|
196
|
+
.to_json,
|
197
|
+
headers: {}
|
198
|
+
}
|
199
|
+
)
|
178
200
|
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
179
201
|
abs_service.select_target_from("https://foobar")
|
180
202
|
expect(abs_service.target).to eq(hostname)
|
181
203
|
end
|
204
|
+
|
182
205
|
it 'returns a warning if the first request is not a 202' do
|
183
206
|
hostname = 'fainter-whirlwind.puppet.com'
|
184
|
-
stub_request(:post, "https://foobar/request")
|
185
|
-
|
186
|
-
|
187
|
-
|
207
|
+
stub_request(:post, "https://foobar/request")
|
208
|
+
.to_return(
|
209
|
+
{ status: 404, body: "", headers: {} },
|
210
|
+
{
|
211
|
+
status: 200,
|
212
|
+
body:
|
213
|
+
[{ 'hostname' => hostname, 'type' => 'aix-6.1-ppc', 'engine' => 'nspooler' }].to_json,
|
214
|
+
headers: {}
|
215
|
+
}
|
216
|
+
)
|
217
|
+
allow(VanagonLogger).to receive(:info)
|
218
|
+
expect(VanagonLogger).to receive(:info).with('failed to request ABS with code 404')
|
188
219
|
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
189
|
-
|
190
|
-
expect(pooler).to eq('')
|
220
|
+
abs_service.select_target_from('https://foobar')
|
191
221
|
end
|
192
|
-
|
222
|
+
|
223
|
+
it 'retries until request is a 200' do
|
224
|
+
hostname = 'faintest-whirlwind.puppet.com'
|
225
|
+
stub_request(:post, 'https://foobar/request')
|
226
|
+
.to_return(
|
227
|
+
{ status: 202, body: "", headers: {} },
|
228
|
+
{ status: 503, body: "", headers: {} },
|
229
|
+
{
|
230
|
+
status: 200,
|
231
|
+
body: [{
|
232
|
+
'hostname' => hostname, 'type' => 'aix-6.1-ppc', 'engine' => "nspooler"
|
233
|
+
}].to_json,
|
234
|
+
headers: {}
|
235
|
+
}
|
236
|
+
)
|
237
|
+
allow(VanagonLogger).to receive(:info)
|
238
|
+
expect(VanagonLogger).to receive(:info).with(/^Waiting 1 second.*to fill/)
|
239
|
+
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
240
|
+
abs_service.select_target_from("https://foobar")
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'sets a service target when request is a 200' do
|
193
244
|
hostname = 'faintest-whirlwind.puppet.com'
|
194
|
-
stub_request(:post,
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
245
|
+
stub_request(:post, 'https://foobar/request')
|
246
|
+
.to_return(
|
247
|
+
{ status: 202, body: "", headers: {} },
|
248
|
+
{ status: 503, body: "", headers: {} },
|
249
|
+
{
|
250
|
+
status: 200,
|
251
|
+
body: [{
|
252
|
+
'hostname' => hostname, 'type' => 'aix-6.1-ppc', 'engine' => "nspooler"
|
253
|
+
}].to_json,
|
254
|
+
headers: {}
|
255
|
+
}
|
256
|
+
)
|
257
|
+
allow(VanagonLogger).to receive(:info)
|
200
258
|
abs_service = Vanagon::Engine::AlwaysBeScheduling.new(platform, nil)
|
201
259
|
abs_service.select_target_from("https://foobar")
|
202
260
|
expect(abs_service.target).to eq(hostname)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vanagon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.37.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet By Perforce
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docopt
|
@@ -162,7 +162,6 @@ files:
|
|
162
162
|
- lib/vanagon/platform/defaults/debian-8-i386.rb
|
163
163
|
- lib/vanagon/platform/defaults/el-6-i386.rb
|
164
164
|
- lib/vanagon/platform/defaults/el-6-x86_64.rb
|
165
|
-
- lib/vanagon/platform/defaults/el-7-aarch64.rb
|
166
165
|
- lib/vanagon/platform/defaults/el-7-x86_64.rb
|
167
166
|
- lib/vanagon/platform/defaults/el-8-aarch64.rb
|
168
167
|
- lib/vanagon/platform/defaults/el-8-ppc64le.rb
|
@@ -170,7 +169,6 @@ files:
|
|
170
169
|
- lib/vanagon/platform/defaults/el-9-aarch64.rb
|
171
170
|
- lib/vanagon/platform/defaults/el-9-x86_64.rb
|
172
171
|
- lib/vanagon/platform/defaults/fedora-36-x86_64.rb
|
173
|
-
- lib/vanagon/platform/defaults/osx-10.15-x86_64.rb
|
174
172
|
- lib/vanagon/platform/defaults/osx-11-arm64.rb
|
175
173
|
- lib/vanagon/platform/defaults/osx-11-x86_64.rb
|
176
174
|
- lib/vanagon/platform/defaults/osx-12-arm64.rb
|
@@ -1,13 +0,0 @@
|
|
1
|
-
platform "el-7-aarch64" do |plat|
|
2
|
-
plat.servicedir "/usr/lib/systemd/system"
|
3
|
-
plat.defaultdir "/etc/sysconfig"
|
4
|
-
plat.servicetype "systemd"
|
5
|
-
|
6
|
-
plat.add_build_repository "http://pl-build-tools.delivery.puppetlabs.net/yum/el/7/aarch64/pl-build-tools-aarch64.repo"
|
7
|
-
plat.add_build_repository "http://pl-build-tools.delivery.puppetlabs.net/yum/el/7/x86_64/pl-build-tools-x86_64.repo"
|
8
|
-
packages = %w(autoconf automake createrepo rsync gcc make rpmdevtools rpm-libs yum-utils rpm-sign)
|
9
|
-
plat.provision_with "yum install --assumeyes #{packages.join(' ')}"
|
10
|
-
plat.install_build_dependencies_with "yum install --assumeyes"
|
11
|
-
plat.cross_compiled true
|
12
|
-
plat.vmpooler_template "redhat-7-x86_64"
|
13
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
platform "osx-10.15-x86_64" do |plat|
|
2
|
-
plat.servicetype "launchd"
|
3
|
-
plat.servicedir "/Library/LaunchDaemons"
|
4
|
-
plat.codename "catalina"
|
5
|
-
|
6
|
-
plat.provision_with "export HOMEBREW_NO_EMOJI=true"
|
7
|
-
plat.provision_with "export HOMEBREW_VERBOSE=true"
|
8
|
-
plat.provision_with "export HOMEBREW_NO_ANALYTICS=1"
|
9
|
-
|
10
|
-
plat.provision_with "sudo dscl . -create /Users/test"
|
11
|
-
plat.provision_with "sudo dscl . -create /Users/test UserShell /bin/bash"
|
12
|
-
plat.provision_with "sudo dscl . -create /Users/test UniqueID 1001"
|
13
|
-
plat.provision_with "sudo dscl . -create /Users/test PrimaryGroupID 1000"
|
14
|
-
plat.provision_with "sudo dscl . -create /Users/test NFSHomeDirectory /Users/test"
|
15
|
-
plat.provision_with "sudo dscl . -passwd /Users/test password"
|
16
|
-
plat.provision_with "sudo dscl . -merge /Groups/admin GroupMembership test"
|
17
|
-
plat.provision_with "echo 'test ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/username"
|
18
|
-
plat.provision_with "mkdir -p /etc/homebrew"
|
19
|
-
plat.provision_with "cd /etc/homebrew"
|
20
|
-
plat.provision_with "createhomedir -c -u test"
|
21
|
-
plat.provision_with %Q(su test -c 'echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"')
|
22
|
-
plat.vmpooler_template "osx-1015-x86_64"
|
23
|
-
end
|