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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 102d009c983cce91795427ba4fde405991d1e9fe792a5ca2759332379f5740d8
4
- data.tar.gz: 502dfc5b2d6dc0287b2affcc25602988078d7a8695932b38fc6b5bda60e5f44f
3
+ metadata.gz: 4b569137b6d209bf5bd4caa5d17063aa6779fb72b92dc33eb77acc35c47779de
4
+ data.tar.gz: 6b305a0234d8e5b68ee1a0c9ef46c1396f6ee43af941a60e3bf192fc1ab4c7f4
5
5
  SHA512:
6
- metadata.gz: 32858c83e0925378289ebb567f9410641bfbe10f027dacbf10e6f3371a5431b3c805b17ae2ef7bd5172763c90ba8fa59d81ad04bc4aa720cbcb06bad70f799ad
7
- data.tar.gz: 292f6afc7c31255d3055bb93c5a07c68b0fba409618958c19642ce44788dad5d7ba7a0c7ffc011fa5e5e607b6acd243ad52523b0a27c1e70b3a49dff1570b66a
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 depending on whether or not
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 true if url.to_s.start_with?('https://github.com/')
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
- # Basic factory to hand back the correct {Vanagon::Component::Source} subtype to the component
13
+ # Factory to hand back the correct {Vanagon::Component::Source} subtype to the component
14
14
  #
15
- # @param url [String] URI of the source file (includes git@... style links)
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(uri, **options) # rubocop:disable Metrics/AbcSize
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 = uri.to_s
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.info "Passing git URLs as http(s) addresses is deprecated! Please prefix your source URL with `git:`"
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
- # This method is used to obtain a vm to build upon using Puppet's internal
227
- # ABS (https://github.com/puppetlabs/always-be-scheduling) which is a level of abstraction for other
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
- raise Vanagon::Error, "Something went wrong getting a target vm to build on" if @pooler.empty?
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
- retries = 360 # ~ one hour
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 check if ABS request has been filled. (x#{i})"
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. Make sure you delete the requested job_id #{@saved_job_id}"
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
- translated(response_body, @saved_job_id)
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
- response_body.each do |host| # in this context there should be only one host
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
- # before(:each) blocks are run before each example
16
- before :each do
17
- allow(Vanagon::Component::Source::Git)
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
- it "uses the realpath of the workdir if we're in a symlinked dir" do
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
- it "with no clone options should be empty" do
43
- git_source = @klass.new(@local_url, ref: @ref_tag, workdir: "/tmp/foo")
44
- expect(git_source.clone_options)
45
- .to be {}
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 "add clone options depth and branch" do
49
- expected_clone_options = {:branch => "bar", :depth => 50 }
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
- describe "#clone" do
57
- before :each do
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 "repository" do
65
- git_source = @klass.new(@url, ref: @ref_tag, workdir: "/tmp/foo")
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 "a particular branch with a depth" do
71
- expected_clone_options = {:branch => "foo", :depth => 50 }
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 'uses a custom dirname' do
78
- git_source = @klass.new(@url, ref: @ref_tag, workdir: "/tmp/foo", dirname: 'facter-ng')
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
- describe "#dirname" do
85
- it "returns the name of the repo" do
86
- git_source = @klass.new(@local_url, ref: @ref_tag, workdir: @workdir)
87
- expect(git_source.dirname)
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
- it "returns the name of the repo and strips .git" do
92
- git_source = @klass.new(@url, ref: @ref_tag, workdir: @workdir)
93
- expect(git_source.dirname)
94
- .to eq('facter')
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
- it "returns @dirname if is set" do
98
- git_source = @klass.new(@url, ref: @ref_tag, workdir: @workdir, dirname: 'facter-ng')
99
- expect(git_source.dirname)
100
- .to eq('facter-ng')
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
- describe "#ref" do
105
- it "returns a default value of HEAD when no explicit Git reference is provided" do
106
- git_source = @klass.new(@url, workdir: @workdir)
107
- expect(git_source.ref)
108
- .to eq('HEAD')
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
- it "returns a default value of HEAD when Git reference is nil" do
112
- git_source = @klass.new(@url, ref: nil, workdir: @workdir)
113
- expect(git_source.ref)
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 "takes a Git repo" do
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 "takes a HTTP/HTTPS file" do
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 "takes a local file" do
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
- it %(reads a token from '~/.vmfloaty.yml at the top level') do
131
+
132
+ it 'reads a token from "~/.vmfloaty.yml" at the top level' do
132
133
  allow(YAML).to receive(:load_file)
133
- .with(floaty_config)
134
- .and_return({'token' => token_value})
135
- allow(ENV).to receive(:[])
134
+ .with(floaty_config)
135
+ .and_return({ 'token' => token_value })
136
136
  allow(ENV).to receive(:[])
137
- .with('VMPOOLER_TOKEN')
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
- it %(reads a token from '~/.vmfloaty.yml in the abs service') do
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
- .with(floaty_config)
147
- .and_return({'services' =>
148
- {'MYabs' => {'type'=>'abs', 'token'=>token_value, 'url'=>'foo'}}
149
- })
150
- allow(ENV).to receive(:[])
151
- allow(ENV).to receive(:[])
152
- .with('VMPOOLER_TOKEN')
153
- .and_return(nil)
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
- it %(reads a token from '~/.vmfloaty.yml in the abs service and includes the vmpooler token') do
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
- .with(floaty_config)
163
- .and_return({'services' =>
164
- {'MYabs' => {'type'=>'abs', 'token'=>token_value, 'url'=>'foo', 'vmpooler_fallback' => 'myvmp'},
165
- 'myvmp' => {'token'=>vmp_token_value, 'url'=>'bar'}}
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, "https://foobar/request").
177
- to_return({status: 202, body: "", headers: {}},{status: 200, body: '[{"hostname":"'+hostname+'","type":"aix-6.1-ppc","engine":"nspooler"}]', headers: {}})
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
- to_return({status: 404, body: "", headers: {}},{status: 200, body: '[{"hostname":"'+hostname+'","type":"aix-6.1-ppc","engine":"nspooler"}]', headers: {}})
186
- allow_any_instance_of(VanagonLogger).to receive(:info)
187
- expect_any_instance_of(VanagonLogger).to receive(:info).with("failed to request ABS with code 404")
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
- pooler = abs_service.select_target_from("https://foobar")
190
- expect(pooler).to eq('')
220
+ abs_service.select_target_from('https://foobar')
191
221
  end
192
- it 'returns a warning and retries until request is a 200' do
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, "https://foobar/request").
195
- to_return({status: 202, body: "", headers: {}},
196
- {status: 503, body: "", headers: {}},
197
- {status: 200, body: '[{"hostname":"'+hostname+'","type":"aix-6.1-ppc","engine":"nspooler"}]', headers: {}})
198
- allow_any_instance_of(VanagonLogger).to receive(:info)
199
- expect_any_instance_of(VanagonLogger).to receive(:info).with(/Waiting 1 seconds to check if ABS request has been filled/)
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.36.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-04-19 00:00:00.000000000 Z
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