prima-twig 1.2.6 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/twig-packer-builder +84 -0
- data/bin/twig-update-ami +48 -114
- data/lib/prima_aws_client.rb +26 -0
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94183c3b380822569fa755c6cd914da1eb15d36378d93a8faf827cf8b2a8a119
|
4
|
+
data.tar.gz: 865c21d79254b4b4ad2e8034d665f74301585fd50f4fd20b019e0c6bde977183
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7604f33c35162fde446fb5e91e92451745d7eab126d09f417c36c835254949f2690c77c3f4ebbd8248c885c6c19b7786498da0cfbfe44adcb798b5641e53613f
|
7
|
+
data.tar.gz: 24f093ea1a89deef5debd86afdf69b5dbb43f5f1a6aef9bc68f8a8a0b9e2e938baee20ba897116d8a2d66e5e8d7b8d60a9e1f6af267973003e7357c34d138884
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require_relative '../lib/prima_twig'
|
5
|
+
require 'launchy'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
class TwigPackerBuilder
|
9
|
+
include Command
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
output 'Checking for new gem releases...'
|
13
|
+
unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
|
14
|
+
exec "gem update prima-twig && twig update-ami #{ARGV.join ' '}"
|
15
|
+
end
|
16
|
+
@templates_path = "#{Dir.pwd}/amis"
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute!(args)
|
20
|
+
@template_name = args[0]
|
21
|
+
@env = args[1]
|
22
|
+
@country = args[2]
|
23
|
+
|
24
|
+
File.open("#{Dir.pwd}/ami_state.yml", 'r') do |f|
|
25
|
+
@config = YAML.load(f.read)
|
26
|
+
end
|
27
|
+
|
28
|
+
@country_conf = @config['countries'].detect { |country| country['name'] == @country }
|
29
|
+
stop_if(@country_conf.nil?, "Cannot find country #{@country} inside ami_state.yml, exiting...".red)
|
30
|
+
|
31
|
+
@ami_conf = @country_conf['amis'].detect { |ami| ami['template'] == @template_name and ami['env'] == @env }
|
32
|
+
stop_if(@ami_conf.nil?, "Cannot find an ami in #{@country} generated from #{@template_name} and env #{@env} inside ami_state.yml, exiting...".red)
|
33
|
+
|
34
|
+
output "Starting update process with #{@template_name} in env #{@env} in country #{@country}".light_green
|
35
|
+
output 'running packer (this could take some time)'.light_green
|
36
|
+
new_ami_id = execute_packer
|
37
|
+
stop_if(new_ami_id.to_s.empty?, 'Failed to generate AMI!'.red)
|
38
|
+
|
39
|
+
output "new ami id: #{new_ami_id}".light_green
|
40
|
+
output "ami id that can be replaced: #{@ami_conf['id']}".light_green
|
41
|
+
output "you can run \"aws-vault exec YOUR_CONTRY_PROFILE -- twig-update-ami #{@ami_conf['id']} #{new_ami_id}\" to update all stacks".light_green
|
42
|
+
output 'Done'.light_green
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def execute_packer
|
48
|
+
execute_command "AWS_MAX_ATTEMPTS=90 AWS_POLL_DELAY_SECONDS=60 packer build -var env=#{@env} -var teams_mapping=#{@ami_conf['teams_mapping']} -var country=#{@country} -var aws_account=#{@country_conf['aws_account']} -machine-readable #{@templates_path}/#{@template_name} | tee build.log"
|
49
|
+
|
50
|
+
`grep 'artifact,0,id' build.log | cut -d, -f6 | cut -d: -f2`.sub(/\n/, '')
|
51
|
+
end
|
52
|
+
|
53
|
+
def help_content
|
54
|
+
<<-HELP
|
55
|
+
|
56
|
+
twig-packer-builder
|
57
|
+
===========
|
58
|
+
|
59
|
+
Creates AMIs using umami's templates
|
60
|
+
|
61
|
+
Synopsis
|
62
|
+
--------
|
63
|
+
|
64
|
+
twig-packer-builder
|
65
|
+
|
66
|
+
Description
|
67
|
+
-----------
|
68
|
+
|
69
|
+
from umami main folder run
|
70
|
+
`aws-vault exec AWS_PROFILE_WITH_ACCESS_TO_COMMON_ACCOUNT -- twig-update-ami ${AMI_TEMPLATE} ${ENV} ${COUNTRY}`
|
71
|
+
|
72
|
+
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
73
|
+
HELP
|
74
|
+
end
|
75
|
+
|
76
|
+
args = ARGV.dup
|
77
|
+
|
78
|
+
if args.include?('--help')
|
79
|
+
puts help_content
|
80
|
+
exit
|
81
|
+
end
|
82
|
+
|
83
|
+
TwigPackerBuilder.new.execute!(args)
|
84
|
+
end
|
data/bin/twig-update-ami
CHANGED
@@ -1,164 +1,105 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
-
require_relative '../lib/prima_twig
|
5
|
-
require_relative '../lib/prima_aws_client
|
4
|
+
require_relative '../lib/prima_twig'
|
5
|
+
require_relative '../lib/prima_aws_client'
|
6
6
|
require 'launchy'
|
7
|
-
require '
|
8
|
-
require 'aws-sdk-s3'
|
7
|
+
require 'yaml'
|
9
8
|
|
10
9
|
class TwigUpdateAmi
|
11
10
|
include Command
|
12
11
|
include PrimaAwsClient
|
12
|
+
|
13
13
|
def initialize
|
14
|
-
output '
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@
|
14
|
+
output 'Checking for new gem releases...'
|
15
|
+
unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
|
16
|
+
exec "gem update prima-twig && twig update-ami #{ARGV.join ' '}"
|
17
|
+
end
|
18
|
+
@state_path = "#{Dir.pwd}/ami_state.yml"
|
19
19
|
end
|
20
20
|
|
21
21
|
def execute!(args)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def update_amis(ami_template, ami_id, ami_name, ami_description, env)
|
28
|
-
output "updating instance definition #{ami_template}".light_green
|
29
|
-
Dir.chdir 'ami'
|
30
|
-
update_instance_name(ami_id, ami_name, ami_description, ami_template)
|
31
|
-
output 'running packer update (this could take some time)'.light_green
|
32
|
-
ami_mappings = JSON.parse(@s3.get_object(bucket: @s3_bucket, key: "ami/ami-mappings.json")["body"].read())
|
33
|
-
|
34
|
-
ami_mapping = nil
|
35
|
-
ami_mappings.each do |item|
|
36
|
-
if item['ami_template'].eql?(ami_template) and item['env'].eql?(env)
|
37
|
-
ami_mapping = item
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
stop_if(ami_mapping == nil, "No AMI found with parameters #{ami_template} and #{env}")
|
22
|
+
old_ami = args[0]
|
23
|
+
new_ami = args[1]
|
42
24
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
stop_if(new_ami_id.to_s.empty?, 'Failed to generate AMI!'.red)
|
47
|
-
output "new ami id: #{new_ami_id}"
|
48
|
-
|
49
|
-
output 'searching for ami to update...'
|
50
|
-
old_amis = update_ami_mappings(ami_mappings, ami_template, env, new_ami_id)
|
51
|
-
stop_if(old_amis.empty?, "No ami to update! No #{ami_template} in env #{env}, exiting".yellow)
|
52
|
-
|
53
|
-
output "retrieving stacks that uses old ami ids: #{old_amis}"
|
54
|
-
exports = list_exports()
|
55
|
-
stacks = get_stacks_from_exports(exports, old_amis)
|
56
|
-
stop_if(stacks.empty?, "No stack to update found! This means that ami-mapping file is not in sync, please check manually")
|
25
|
+
output "retrieving stacks that uses old ami #{old_ami}".light_green
|
26
|
+
stacks = get_stacks_from_exports(list_exports, old_ami)
|
27
|
+
stop_if(stacks.empty?, 'No stack to update! Please check manually'.red)
|
57
28
|
|
58
29
|
stacks.each do |stack|
|
59
|
-
output "processing stack #{stack}"
|
30
|
+
output "processing stack #{stack}".light_green
|
60
31
|
if stack.include?('qa')
|
61
|
-
output "skipping stack #{stack} because is a qa"
|
32
|
+
output "skipping stack #{stack} because is a qa".yellow
|
62
33
|
next
|
63
34
|
else
|
64
35
|
stack_parameters = get_stack_parameters(stack)
|
65
|
-
stack_parameters = update_stack_parameters(stack_parameters,
|
66
|
-
|
67
|
-
|
68
|
-
stack_template = File.read("./cloudformation/stacks/batch/compute-environment-offsite-backups.yml")
|
69
|
-
else
|
70
|
-
stack_template = File.read("./cloudformation/stacks/batch/compute-environment.yml")
|
71
|
-
end
|
72
|
-
else
|
73
|
-
stack_parameters = update_stack_parameters(stack_parameters, "DesiredCapacity", get_desired_capacity(stack).to_s)
|
74
|
-
stack_template = File.read("./cloudformation/stacks/asg/#{stack.to_s.split("/")[1]}.yml")
|
36
|
+
stack_parameters = update_stack_parameters(stack_parameters, 'AMIID', new_ami)
|
37
|
+
unless stack.include?('batch')
|
38
|
+
stack_parameters = update_stack_parameters(stack_parameters, 'DesiredCapacity', get_desired_capacity(stack).to_s)
|
75
39
|
end
|
76
|
-
|
40
|
+
|
41
|
+
update_stack_reuse_template(stack, stack_parameters)
|
77
42
|
end
|
78
43
|
end
|
79
44
|
|
80
45
|
stacks.each do |stack|
|
81
|
-
if stack.include?('qa')
|
82
|
-
|
46
|
+
next if stack.include?('qa')
|
47
|
+
|
48
|
+
wait_for_stack_ready(stack, %w[CREATE_FAILED ROLLBACK_IN_PROGRESS ROLLBACK_FAILED DELETE_IN_PROGRESS DELETE_FAILED DELETE_COMPLETE UPDATE_ROLLBACK_FAILED UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS UPDATE_ROLLBACK_COMPLETE ROLLBACK_COMPLETE])
|
49
|
+
end
|
50
|
+
|
51
|
+
output 'Saving new ami in ami_state.yml'.light_green
|
52
|
+
File.open(@state_path, 'r') do |f|
|
53
|
+
@config = YAML.load(f.read)
|
54
|
+
end
|
55
|
+
|
56
|
+
@config['countries'].each do |country|
|
57
|
+
country['amis'].each do |ami|
|
58
|
+
ami['id'] = new_ami if ami['id'] == old_ami
|
83
59
|
end
|
84
|
-
wait_for_stack_ready(stack, ['CREATE_FAILED', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'DELETE_IN_PROGRESS', 'DELETE_FAILED', 'DELETE_COMPLETE', 'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_COMPLETE', 'ROLLBACK_COMPLETE'])
|
85
60
|
end
|
86
61
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
f.write(mapping_file)
|
91
|
-
@s3.put_object(bucket: @s3_bucket, key: "ami/ami-mappings.json", body: mapping_file)
|
62
|
+
File.open(@state_path, 'w+') do |f|
|
63
|
+
yaml = YAML.dump(@config)
|
64
|
+
f.write(yaml)
|
92
65
|
end
|
93
66
|
|
94
|
-
output 'Update finished! ( ͡° ͜ʖ ͡°)'
|
67
|
+
output 'Update finished! ( ͡° ͜ʖ ͡°)'.light_green
|
95
68
|
end
|
96
69
|
|
97
|
-
|
70
|
+
private
|
71
|
+
|
72
|
+
def get_stacks_from_exports(exports, old_ami)
|
98
73
|
stacks = []
|
99
|
-
|
100
|
-
|
101
|
-
if export.value.eql?(old_ami)
|
102
|
-
stacks.insert(0,export.exporting_stack_id)
|
103
|
-
end
|
104
|
-
end
|
74
|
+
exports.each do |export|
|
75
|
+
stacks.insert(0, export.exporting_stack_id) if export.value.eql?(old_ami)
|
105
76
|
end
|
106
77
|
stacks
|
107
78
|
end
|
108
79
|
|
109
|
-
def update_ami_mappings(mappings, ami_template, env, new_ami_id)
|
110
|
-
old_values = []
|
111
|
-
mappings.each do |item|
|
112
|
-
if item['ami_template'].eql?(ami_template) and item['env'].eql?(env)
|
113
|
-
old_values.insert(0,item['ami_id'])
|
114
|
-
item['ami_id'] = new_ami_id
|
115
|
-
end
|
116
|
-
end
|
117
|
-
old_values.uniq
|
118
|
-
end
|
119
|
-
|
120
80
|
def update_stack_parameters(stack_parameters, key, value)
|
121
81
|
stack_parameters.each do |param|
|
122
|
-
if param.parameter_key == key
|
123
|
-
param.parameter_value = value
|
124
|
-
end
|
82
|
+
param.parameter_value = value if param.parameter_key == key
|
125
83
|
end
|
126
84
|
stack_parameters
|
127
85
|
end
|
128
86
|
|
129
|
-
def update_instance_name(ami_id, ami_name, ami_description, ecs_json_path)
|
130
|
-
ecs_json = JSON.parse File.read(ecs_json_path)
|
131
|
-
|
132
|
-
ecs_json['builders'][0]['source_ami'] = ami_id
|
133
|
-
ecs_json['builders'][0]['ami_name'] = ami_name
|
134
|
-
ecs_json['builders'][0]['ami_description'] = ami_description
|
135
|
-
|
136
|
-
File.open ecs_json_path, 'w' do |f|
|
137
|
-
f.write(JSON.pretty_generate(ecs_json))
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
87
|
def get_desired_capacity(stack_name)
|
142
88
|
stack_outputs = get_stack_outputs(stack_name)
|
143
89
|
stack_outputs.each do |out|
|
144
|
-
if out.export_name.include?('EC2Fleet')
|
90
|
+
if out.export_name.include?('EC2Fleet') || out.export_name.include?('AutoScalingGroup') || out.export_name.include?('NodeGroup')
|
145
91
|
return get_autoscaling_capacity(out.output_value)
|
146
92
|
end
|
147
93
|
end
|
148
94
|
end
|
149
95
|
|
150
|
-
def update_packer(json_filename, env, teams, country)
|
151
|
-
execute_command "AWS_MAX_ATTEMPTS=90 AWS_POLL_DELAY_SECONDS=60 packer build -var datadog_apikey=`biscuit get -f ../configs/secrets/common.yml common_production_apikey_datadog` -var github_token=`biscuit get -f ../configs/secrets/common.yml common_private_repo_github_token` -var drone_key=\"`biscuit get -f ../configs/secrets/common.yml drone_license_key`\" -var env=#{env} -var teams_mapping=#{teams} -var country=#{country} -machine-readable ./#{json_filename} | tee build.log"
|
152
|
-
`grep 'artifact,0,id' build.log | cut -d, -f6 | cut -d: -f2`.sub(/\n/, '')
|
153
|
-
end
|
154
|
-
|
155
96
|
def help_content
|
156
97
|
<<-HELP
|
157
98
|
|
158
99
|
twig-update-ami
|
159
100
|
===========
|
160
101
|
|
161
|
-
Updates
|
102
|
+
Updates AutoScalingGroups/BatchComputeEnvs with a new AMI
|
162
103
|
|
163
104
|
Synopsis
|
164
105
|
--------
|
@@ -168,8 +109,8 @@ class TwigUpdateAmi
|
|
168
109
|
Description
|
169
110
|
-----------
|
170
111
|
|
171
|
-
from
|
172
|
-
`twig-update-ami ${
|
112
|
+
from tsunami main folder run
|
113
|
+
`aws-vault exec AWS_PROFILE_WITH_ACCESS_TO_COUNTRY_ACCOUNT -- twig-update-ami ${OLD_AMI} ${NEW_AMI}`
|
173
114
|
|
174
115
|
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
175
116
|
Author: Eugenio Laghi <https://github.com/eugeniolaghi>
|
@@ -177,13 +118,6 @@ class TwigUpdateAmi
|
|
177
118
|
HELP
|
178
119
|
end
|
179
120
|
|
180
|
-
class ::Hash
|
181
|
-
def deep_merge(second)
|
182
|
-
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
183
|
-
self.merge(second.to_h, &merger)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
121
|
args = ARGV.dup
|
188
122
|
|
189
123
|
if args.include?('--help')
|
data/lib/prima_aws_client.rb
CHANGED
@@ -175,6 +175,32 @@ module PrimaAwsClient
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
+
def update_stack_reuse_template(stack_name, parameters = [], tags = [], role = nil)
|
179
|
+
cf_args = {
|
180
|
+
stack_name: stack_name,
|
181
|
+
use_previous_template: true,
|
182
|
+
parameters: parameters,
|
183
|
+
tags: tags,
|
184
|
+
capabilities: ['CAPABILITY_IAM']
|
185
|
+
}
|
186
|
+
|
187
|
+
if role != nil then
|
188
|
+
cf_args.merge!(role_arn: role)
|
189
|
+
end
|
190
|
+
|
191
|
+
begin
|
192
|
+
cf_client.update_stack(cf_args)
|
193
|
+
rescue Aws::CloudFormation::Errors::Throttling => e
|
194
|
+
output 'Throttling, retrying in 15 seconds'.red
|
195
|
+
sleep 15
|
196
|
+
update_stack(stack_name, template_body, parameters = [], tags = [])
|
197
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
198
|
+
raise e
|
199
|
+
else
|
200
|
+
output "L'update dello stack #{stack_name} è stato avviato".green
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
178
204
|
def stack_exists?(stack_name)
|
179
205
|
begin
|
180
206
|
cf_client.describe_stacks(stack_name: stack_name)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prima-twig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matteo Giachino
|
@@ -14,7 +14,7 @@ authors:
|
|
14
14
|
autorequire:
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
|
-
date: 2020-
|
17
|
+
date: 2020-11-16 00:00:00.000000000 Z
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
20
20
|
name: aws-sdk-autoscaling
|
@@ -73,21 +73,21 @@ dependencies:
|
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '1'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
|
-
name: aws-sdk-
|
76
|
+
name: aws-sdk-core
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '3'
|
82
82
|
type: :runtime
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '3'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
|
-
name: aws-sdk-
|
90
|
+
name: aws-sdk-ec2
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
93
|
- - "~>"
|
@@ -101,7 +101,7 @@ dependencies:
|
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '1'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
|
-
name: aws-sdk-
|
104
|
+
name: aws-sdk-ecs
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
107
|
- - "~>"
|
@@ -115,7 +115,7 @@ dependencies:
|
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '1'
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
|
-
name: aws-sdk-
|
118
|
+
name: aws-sdk-elasticloadbalancingv2
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
120
120
|
requirements:
|
121
121
|
- - "~>"
|
@@ -129,19 +129,19 @@ dependencies:
|
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '1'
|
131
131
|
- !ruby/object:Gem::Dependency
|
132
|
-
name: aws-sdk-
|
132
|
+
name: aws-sdk-s3
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
135
|
- - "~>"
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version: '
|
137
|
+
version: '1'
|
138
138
|
type: :runtime
|
139
139
|
prerelease: false
|
140
140
|
version_requirements: !ruby/object:Gem::Requirement
|
141
141
|
requirements:
|
142
142
|
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version: '
|
144
|
+
version: '1'
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
146
|
name: colorize
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -286,11 +286,13 @@ description: Our tools to manage git and github
|
|
286
286
|
email: matteo.giachino@prima.it
|
287
287
|
executables:
|
288
288
|
- twig-feature
|
289
|
+
- twig-packer-builder
|
289
290
|
- twig-update-ami
|
290
291
|
extensions: []
|
291
292
|
extra_rdoc_files: []
|
292
293
|
files:
|
293
294
|
- bin/twig-feature
|
295
|
+
- bin/twig-packer-builder
|
294
296
|
- bin/twig-update-ami
|
295
297
|
- lib/command.rb
|
296
298
|
- lib/prima_aws_client.rb
|
@@ -314,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
314
316
|
- !ruby/object:Gem::Version
|
315
317
|
version: '0'
|
316
318
|
requirements: []
|
317
|
-
rubygems_version: 3.0.
|
319
|
+
rubygems_version: 3.0.3
|
318
320
|
signing_key:
|
319
321
|
specification_version: 4
|
320
322
|
summary: The Prima twig toolbelt
|