vanagon 0.36.0 → 0.37.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/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
|