stemcell 0.11.11 → 0.13.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.
@@ -54,16 +54,33 @@ encrypted_data_bag_secret_path='<%= opts['chef_data_bag_secret_path'].to_s %>'
54
54
  ##
55
55
 
56
56
  update() {
57
- echo updating apt repo
58
- apt-get update 1>&2
57
+ echo updating repository metadata
58
+
59
+ case $OS_PACKAGE_MANAGER in
60
+ apt)
61
+ apt-get update 1>&2
62
+ ;;
63
+ yum)
64
+ # yum install will check if metadata needs to be updated
65
+ # so it's just for consistency with apt-based distros
66
+ yum check-update 1>&2 || true
67
+ ;;
68
+ esac
59
69
  }
60
70
 
61
71
  install() {
62
- if ! (dpkg -l | awk '{print $2}' | grep -q ^$1$ ) ; then
63
- echo installing $1...
64
- export DEBIAN_FRONTEND=noninteractive
65
- apt-get install -y $1 1>&2
66
- fi
72
+ case $OS_PACKAGE_MANAGER in
73
+ apt)
74
+ if ! (dpkg -l | awk '{print $2}' | grep -q ^$1$ ) ; then
75
+ echo installing $1...
76
+ export DEBIAN_FRONTEND=noninteractive
77
+ apt-get install -y $1 1>&2
78
+ fi
79
+ ;;
80
+ yum)
81
+ rpm -q $1 2>&1 >/dev/null || yum install -y $1
82
+ ;;
83
+ esac
67
84
  }
68
85
 
69
86
  set_hostname() {
@@ -86,22 +103,34 @@ set_hostname() {
86
103
  echo "$local_ip $fqdn $hostname" >> /etc/hosts
87
104
  }
88
105
 
106
+ download_chef_package() {
107
+ echo "Downloading chef from $1"
108
+ wget "$1" -O "$2" --progress=dot:mega --tries=15 --retry-connrefused --timeout=5 --wait=10 --random-wait --continue --no-dns-cache
109
+ }
110
+
89
111
  install_chef() {
112
+ package_local="/tmp/chef_${chef_version}.${OS_PACKAGE_EXT}"
113
+ package_url="$(render_chef_url)"
114
+
90
115
  # check to see if chef is already installed
91
116
  if ! which chef-solo > /dev/null ; then
92
- platform=`lsb_release -s -i | tr '[:upper:]' '[:lower:]'`
93
- platform_version=`lsb_release -s -r`
94
- arch=`uname -m`
95
- package_local="/tmp/chef_${chef_version}.deb"
96
- package_url="<%= opts['chef_package_source'] %>"
97
- echo "Downloading chef from $package_url"
98
- wget $package_url -O $package_local --progress=dot:mega
99
- echo "Installing chef $chef_version"
100
- dpkg -i $package_local
101
- rm $package_local
117
+ case $OS_PACKAGE_MANAGER in
118
+ apt)
119
+ download_chef_package "$package_url" "$package_local"
120
+ echo "Installing chef $chef_version"
121
+ dpkg -i $package_local
122
+ ;;
123
+ yum)
124
+ download_chef_package "$package_url" "$package_local"
125
+ echo "Installing chef $chef_version"
126
+ rpm -ivh "$package_local"
127
+ ;;
128
+ esac
102
129
  else
103
130
  echo chef is already installed
104
131
  fi
132
+
133
+ rm -f $package_local
105
134
  }
106
135
 
107
136
  create_ohai_hint() {
@@ -147,16 +176,17 @@ configure_chef() {
147
176
 
148
177
  echo "configuring chef solo..."
149
178
  cat<<EOF > ${chef_dir}/solo.rb
179
+ # chef config (https://docs.chef.io/config_rb_client.html)
150
180
  repo_dir = "${repo_dir}"
151
181
 
152
182
  cookbook_path ["#{repo_dir}/site-cookbooks", "#{repo_dir}/cookbooks"]
153
183
  role_path "#{repo_dir}/roles"
154
184
  data_bag_path "#{repo_dir}/data_bags"
185
+ ohai.plugin_path << "#{repo_dir}/ohai_plugins"
155
186
  ssl_verify_mode :verify_peer
156
187
  log_level :info
157
188
  log_location STDOUT
158
189
 
159
- Ohai::Config[:plugin_path] << "#{repo_dir}/ohai_plugins"
160
190
  EOF
161
191
 
162
192
  if [ -n "$encrypted_data_bag_secret_path" ]; then
@@ -197,7 +227,7 @@ git reset --hard origin/\${branch}
197
227
  git clean -fdx
198
228
 
199
229
  json="{\"role\": \"\${role}\", \"env\": \"\${env}\", \"branch\": \"\${branch}\"}"
200
- json_file=\`tempfile\`
230
+ json_file=\`mktemp\`
201
231
  echo \$json > \$json_file
202
232
  trap "{ rm -f '\$json_file' ; }" EXIT
203
233
 
@@ -235,12 +265,55 @@ run_chef() {
235
265
  set -e
236
266
  }
237
267
 
268
+ render_chef_url() {
269
+ base_url="<%= opts['chef_package_source'] %>"
270
+ echo $base_url | sed \
271
+ -e "s/%{platform}/$OS_PLATFORM/g" \
272
+ -e "s/%{platform_version}/$OS_PLATFORM_VERSION/g" \
273
+ -e "s/%{chef_version}/$chef_version/g" \
274
+ -e "s/%{package_manager}/$OS_PACKAGE_MANAGER/g" \
275
+ -e "s/%{package_arch}/$OS_PACKAGE_ARCH/g" \
276
+ -e "s/%{package_ext}/$OS_PACKAGE_EXT/g"
277
+ }
278
+
279
+ check_os_version() {
280
+ NAME=unsupported
281
+
282
+ if [ -f /etc/os-release ]; then
283
+ . /etc/os-release
284
+ fi
285
+
286
+ case "$NAME" in
287
+ "Ubuntu")
288
+ OS_VERSION="$NAME $VERSION_ID"
289
+ OS_PLATFORM=ubuntu
290
+ OS_PLATFORM_VERSION=$VERSION_ID
291
+ OS_PACKAGE_MANAGER=apt
292
+ OS_PACKAGE_ARCH=$(dpkg --print-architecture)
293
+ OS_PACKAGE_EXT=deb
294
+ ;;
295
+ "Amazon Linux")
296
+ OS_VERSION="$NAME $VERSION_ID"
297
+ OS_PLATFORM=amazon
298
+ OS_PLATFORM_VERSION=$VERSION_ID
299
+ OS_PACKAGE_MANAGER=yum
300
+ OS_PACKAGE_ARCH=$(uname -m)
301
+ OS_PACKAGE_EXT=rpm
302
+ ;;
303
+ *)
304
+ echo "Unsupported operating system"
305
+ exit 1
306
+ ;;
307
+ esac
308
+ }
238
309
 
239
310
  ##
240
311
  ## main
241
312
  ##
242
313
 
243
- echo "starting chef bootstrapping..."
314
+ check_os_version
315
+
316
+ echo "starting chef bootstrapping on ${OS_VERSION}..."
244
317
  update
245
318
  install curl
246
319
  install git
@@ -1,3 +1,3 @@
1
1
  module Stemcell
2
- VERSION = "0.11.11"
2
+ VERSION = "0.13.0"
3
3
  end
@@ -4,7 +4,9 @@
4
4
  },
5
5
  "backing_store": {
6
6
  "instance_store": {
7
- "image_id": "ami-d9d6a6b0"
7
+ "us-east-1": {
8
+ "image_id": "ami-d9d6a6b0"
9
+ }
8
10
  }
9
11
  }
10
12
  }
@@ -0,0 +1,13 @@
1
+ {
2
+ "defaults": {
3
+ "instance_type": "m1.small"
4
+ },
5
+ "backing_store": {
6
+ "instance_store": {
7
+ "image_id": "ami-d9d6a6b0"
8
+ }
9
+ },
10
+ "availability_zones": {
11
+ "us-east-1": ["us-east-1a"]
12
+ }
13
+ }
@@ -5,7 +5,9 @@
5
5
  },
6
6
  "backing_store": {
7
7
  "instance_store": {
8
- "image_id": "ami-d9d6a6b0"
8
+ "us-east-1": {
9
+ "image_id": "ami-d9d6a6b0"
10
+ }
9
11
  }
10
12
  },
11
13
  "availability_zones": {
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "backing_store": {
3
3
  "instance_store": {
4
- "baz": "woo"
4
+ "us-east-1": {
5
+ "baz": "woo"
6
+ }
5
7
  }
6
8
  },
7
9
  "availability_zones": {
@@ -16,10 +16,14 @@
16
16
 
17
17
  "backing_store": {
18
18
  "hvm1": {
19
- "image_id": "ami-1"
19
+ "us-east-1": {
20
+ "image_id": "ami-1"
21
+ }
20
22
  },
21
23
  "pv1": {
22
- "image_id": "ami-2"
24
+ "us-east-1": {
25
+ "image_id": "ami-2"
26
+ }
23
27
  }
24
28
  },
25
29
 
@@ -4,7 +4,9 @@
4
4
  },
5
5
  "backing_store": {
6
6
  "instance_store": {
7
- "image_id": "ami-d9d6a6b0"
7
+ "us-east-1": {
8
+ "image_id": "ami-d9d6a6b0"
9
+ }
8
10
  }
9
11
  },
10
12
  "availability_zones": {
@@ -1,45 +1,56 @@
1
1
  require 'spec_helper'
2
+ require 'base64'
2
3
 
3
- class MockInstance
4
- def initialize(id)
5
- @id = id
6
- end
7
-
8
- def id
9
- @id
10
- end
11
-
12
- def status
13
- :running
14
- end
15
- end
16
-
17
- class MockSecurityGroup
18
- attr_reader :group_id, :name, :vpc_id
19
- def initialize(id, name, vpc_id)
20
- @group_id = id
21
- @name = name
22
- @vpc_id = vpc_id
4
+ describe Stemcell::Launcher do
5
+ before do
6
+ Aws.config[:stub_responses] = true
23
7
  end
24
- end
25
-
26
- class MockException < StandardError
27
- end
28
8
 
29
- describe Stemcell::Launcher do
30
9
  let(:launcher) {
31
10
  opts = {'region' => 'region'}
32
11
  launcher = Stemcell::Launcher.new(opts)
33
12
  launcher
34
13
  }
35
14
  let(:operation) { 'op' }
36
- let(:instances) { (1..4).map { |id| MockInstance.new(id) } }
15
+ let(:instances) do
16
+ ('1'..'4').map do |id|
17
+ Aws::EC2::Types::Instance.new(
18
+ instance_id: id,
19
+ private_ip_address: "10.10.10.#{id}",
20
+ state: Aws::EC2::Types::InstanceState.new(name: 'pending')
21
+ )
22
+ end
23
+ end
37
24
  let(:instance_ids) { instances.map(&:id) }
38
25
 
39
26
  describe '#launch' do
40
- let(:ec2) { instance_double(AWS::EC2) }
41
- let(:client) { double(AWS::EC2::Client) }
42
- let(:response) { instance_double(AWS::Core::Response) }
27
+ let(:ec2) do
28
+ ec2 = Aws::EC2::Client.new
29
+ ec2.stub_responses(
30
+ :describe_security_groups,
31
+ security_groups: [
32
+ {group_id: 'sg-1', group_name: 'sg_name1', vpc_id:'vpc-1'},
33
+ {group_id: 'sg-2', group_name: 'sg_name2', vpc_id:'vpc-1'},
34
+ ],
35
+ )
36
+ ec2.stub_responses(
37
+ :describe_instances,
38
+ reservations: [{
39
+ instances: ('1'..'4').map do |id|
40
+ {
41
+ instance_id: id,
42
+ private_ip_address: "10.10.10.#{id}",
43
+ public_ip_address: "24.10.10.#{id}",
44
+ state: {
45
+ name: 'running'
46
+ }
47
+ }
48
+ end
49
+ }]
50
+ )
51
+ ec2
52
+ end
53
+ let(:response) { instance_double(Seahorse::Client::Response) }
43
54
  let(:launcher) {
44
55
  opts = {'region' => 'region', 'vpc_id' => 'vpc-1'}
45
56
  launcher = Stemcell::Launcher.new(opts)
@@ -59,7 +70,8 @@ describe Stemcell::Launcher do
59
70
  'availability_zone' => 'us-east-1a',
60
71
  'count' => 2,
61
72
  'security_groups' => ['sg_name1', 'sg_name2'],
62
- 'wait' => false
73
+ 'user' => 'some_user',
74
+ 'wait' => true
63
75
  }
64
76
  }
65
77
 
@@ -67,132 +79,105 @@ describe Stemcell::Launcher do
67
79
  allow(launcher).to receive(:try_file).and_return('secret')
68
80
  allow(launcher).to receive(:render_template).and_return('template')
69
81
  allow(launcher).to receive(:ec2).and_return(ec2)
70
- allow(ec2).to receive(:client).and_return(client)
71
82
  allow(response).to receive(:error).and_return(nil)
72
83
  end
73
84
 
74
85
  it 'launches all of the instances' do
75
86
  expect(launcher).to receive(:get_vpc_security_group_ids).
76
87
  with('vpc-1', ['sg_name1', 'sg_name2']).and_call_original
77
- expect_any_instance_of(AWS::EC2::VPC).to receive(:security_groups).
78
- and_return([1,2].map { |i| MockSecurityGroup.new("sg-#{i}", "sg_name#{i}", 'vpc-1')})
88
+ expect(ec2).to receive(:describe_security_groups).and_call_original
79
89
  expect(launcher).to receive(:do_launch).with(a_hash_including(
80
90
  :image_id => 'ami-d9d6a6b0',
81
91
  :instance_type => 'c1.xlarge',
82
92
  :key_name => 'key',
83
- :count => 2,
84
- :security_group_ids => ['sg-1', 'sg-2'],
85
- :availability_zone => 'us-east-1a',
86
- :user_data => 'template'
93
+ :min_count => 2,
94
+ :max_count => 2,
95
+ :placement => { :availability_zone => 'us-east-1a' },
96
+ :network_interfaces => [{
97
+ :device_index => 0,
98
+ :groups => ['sg-1', 'sg-2' ]
99
+ }],
100
+ :tag_specifications => [
101
+ {
102
+ :resource_type => 'instance',
103
+ :tags => [
104
+ { :key => "Name", :value => "role-environment" },
105
+ { :key => "Group", :value => "role-environment" },
106
+ { :key => "created_by", :value => "some_user" },
107
+ { :key => "stemcell", :value => Stemcell::VERSION },
108
+ ]},
109
+ ],
110
+ :user_data => Base64.encode64('template')
87
111
  )).and_return(instances)
88
- expect(launcher).to receive(:set_tags).with(kind_of(Array), kind_of(Hash)).and_return(nil)
89
- # set_classic_link should not be set on vpc hosts.
90
- expect(launcher).not_to receive(:set_classic_link)
91
-
92
- launcher.send(:launch, launch_options)
93
- end
94
-
95
- it 'calls set_classic_link for non vpc instances' do
96
- launcher = Stemcell::Launcher.new({'region' => 'region', 'vpc_id' => false})
97
- expect(launcher).to receive(:set_classic_link)
98
- expect(launcher).to receive(:set_tags).with(kind_of(Array), kind_of(Hash)).and_return(nil)
99
- expect(launcher).to receive(:do_launch).and_return(instances)
100
- launcher.send(:launch, launch_options)
112
+ launched_instances = launcher.send(:launch, launch_options)
113
+ expect(launched_instances.map(&:public_ip_address)).to all(be_truthy)
101
114
  end
102
115
  end
103
116
 
104
- describe '#set_classic_link' do
105
- let(:ec2) { instance_double(AWS::EC2) }
106
- let(:client) { double(AWS::EC2::Client) }
107
- let(:response) { instance_double(AWS::Core::Response) }
108
- before do
109
- allow(launcher).to receive(:ec2).and_return(ec2)
110
- allow(ec2).to receive(:client).and_return(client)
111
- allow(response).to receive(:error).and_return(nil)
117
+ describe '#kill' do
118
+ let(:ec2) do
119
+ ec2 = Aws::EC2::Client.new
120
+ ec2.stub_responses(
121
+ :terminate_instances, -> (context) {
122
+ instance_ids = context.params[:instance_ids]
123
+ if instance_ids.include? 'i-3'
124
+ Aws::EC2::Errors::InvalidInstanceIDNotFound.new(nil, "The instance ID 'i-3' do not exist")
125
+ else
126
+ {} # success
127
+ end
128
+ })
129
+ ec2
112
130
  end
113
131
 
114
- let(:classic_link) {
115
- {
116
- 'vpc_id' => 'vpc-1',
117
- 'security_group_ids' => ['sg-1', 'sg-2'],
118
- 'security_groups' => ['sg_name']
119
- }
120
- }
121
-
122
- it 'invokes classic link on all of the instances' do
123
- expect(launcher).to receive(:get_vpc_security_group_ids).with('vpc-1', ['sg_name']).
124
- and_call_original
125
- expect_any_instance_of(AWS::EC2::VPC).to receive(:security_groups).
126
- and_return([MockSecurityGroup.new('sg-3', 'sg_name', 'vpc-1')])
127
- instances.each do |instance|
128
- expect(client).to receive(:attach_classic_link_vpc).ordered.with(a_hash_including(
129
- :instance_id => instance.id,
130
- :vpc_id => classic_link['vpc_id'],
131
- :groups => ['sg-1', 'sg-2', 'sg-3'],
132
- )).and_return(response)
133
- end
132
+ let(:instance_ids) { ('i-1'..'i-4').to_a }
134
133
 
135
- launcher.send(:set_classic_link, instances, classic_link)
136
- end
137
- end
138
-
139
- describe '#run_batch_operation' do
140
- it "raises no exception when no internal error occur" do
141
- errors = launcher.send(:run_batch_operation, instances) {}
142
- expect(errors.all?(&:nil?)).to be true
134
+ before do
135
+ allow(launcher).to receive(:ec2).and_return(ec2)
143
136
  end
144
137
 
145
- it "runs full batch even when there are two error" do
146
- errors = launcher.send(:run_batch_operation,
147
- instances) do |instance, error|
148
- raise "error-#{instance.id}" if instance.id % 2 == 0
138
+ context 'when ignore_not_found is true' do
139
+ it 'terminates valid instances even if an invalid instance id is provided' do
140
+ launcher.kill(instance_ids, ignore_not_found: true)
149
141
  end
150
- expect(errors.count(&:nil?)).to be_eql(2)
151
- expect(errors.reject(&:nil?).map { |e| e.message }).to \
152
- be_eql([2, 4].map { |id| "error-#{id}" })
153
- end
154
142
 
155
- it "retries after an intermittent error" do
156
- count = 0
157
- errors = launcher.send(:run_batch_operation,
158
- instances) do |instance|
159
- if instance.id == 3
160
- count += 1
161
- count < 3 ?
162
- AWS::EC2::Errors::InvalidInstanceID::NotFound.new("error-#{instance.id}"):
163
- nil
164
- end
143
+ it 'finishes without error even if no instance ids are valid' do
144
+ launcher.kill(['i-3'], ignore_not_found: true)
165
145
  end
166
- expect(errors.all?(&:nil?)).to be true
167
146
  end
168
147
 
169
- it "retries up to max_attempts option per instance" do
170
- max_attempts = 6
171
- opts = {'region' => 'region', 'max_attempts' => max_attempts}
172
- launcher = Stemcell::Launcher.new(opts)
173
- allow(launcher).to receive(:sleep).and_return(0)
174
- tags = double("Tags")
175
- instances = (1..2).map do |id|
176
- inst = MockInstance.new(id)
177
- allow(inst).to receive(:tags).and_return(tags)
178
- inst
148
+ context 'when ignore_not_found is false' do
149
+ it 'raises an error' do
150
+ expect { launcher.kill(instance_ids) }.to raise_error(Aws::EC2::Errors::InvalidInstanceIDNotFound)
179
151
  end
180
- expect(tags).to receive(:set).with({'a' => 'b'}).exactly(12).times.
181
- and_raise(AWS::EC2::Errors::InvalidInstanceID::NotFound.new("error"))
182
- expect do
183
- launcher.send(:set_tags, instances, {'a' => 'b'})
184
- end.to raise_error(Stemcell::IncompleteOperation)
185
152
  end
186
153
  end
187
154
 
188
155
  describe '#configure_aws_creds_and_region' do
189
- it 'AWS region is configured after launcher is instanciated' do
190
- expect(AWS.config.region).to be_eql('region')
156
+ it 'AWS region is configured after launcher is instantiated' do
157
+ expect(Aws.config[:region]).to be_eql('region')
191
158
  end
192
159
 
193
160
  it 'AWS region configuration changed' do
194
161
  mock_launcher = Stemcell::Launcher.new('region' => 'ap-northeast-1')
195
- expect(AWS.config.region).to be_eql('ap-northeast-1')
162
+ expect(Aws.config[:region]).to be_eql('ap-northeast-1')
163
+ end
164
+ end
165
+
166
+ describe '#ec2' do
167
+
168
+ it 'can return a client with regional endpoint' do
169
+ launcher = Stemcell::Launcher.new({'region' => 'us-east-1', 'ec2_endpoint' => nil})
170
+ client = launcher.send(:ec2)
171
+ expect(client.config[:endpoint].to_s).to be_eql('https://ec2.us-east-1.amazonaws.com')
172
+ end
173
+
174
+ it 'can return a client with custom endpoint' do
175
+ launcher = Stemcell::Launcher.new({
176
+ 'region' => 'region1',
177
+ 'ec2_endpoint' => 'https://endpoint1',
178
+ })
179
+ client = launcher.send(:ec2)
180
+ expect(client.config[:endpoint].to_s).to be_eql('https://endpoint1')
196
181
  end
197
182
  end
198
183
  end
@@ -32,7 +32,9 @@ describe Stemcell::MetadataSource::Configuration do
32
32
  it "sets backing_store_options" do
33
33
  expect(config.backing_store_options).to eql({
34
34
  'instance_store' => {
35
- 'image_id' => 'ami-d9d6a6b0'
35
+ 'us-east-1' => {
36
+ 'image_id' => 'ami-d9d6a6b0'
37
+ }
36
38
  }
37
39
  })
38
40
  end
@@ -86,10 +88,11 @@ describe Stemcell::MetadataSource::Configuration do
86
88
 
87
89
  describe '#options_for_backing_store' do
88
90
  let(:backing_store) { 'instance_store' }
91
+ let(:region) { 'us-east-1' }
89
92
 
90
93
  context "when the backing store definition exists" do
91
94
  it "returns the options" do
92
- expect(config.options_for_backing_store(backing_store)).to eql({
95
+ expect(config.options_for_backing_store(backing_store, region)).to eql({
93
96
  'image_id' => 'ami-d9d6a6b0'
94
97
  })
95
98
  end
@@ -97,13 +100,23 @@ describe Stemcell::MetadataSource::Configuration do
97
100
 
98
101
  context "when the backing store isn't defined" do
99
102
  let(:backing_store) { 'nyanstore' }
103
+ let(:region) { 'us-east-1' }
100
104
  it "raises" do
101
- expect { config.options_for_backing_store(backing_store) }.to raise_error(
105
+ expect { config.options_for_backing_store(backing_store, region) }.to raise_error(
102
106
  Stemcell::UnknownBackingStoreError
103
107
  )
104
108
  end
105
109
  end
106
110
 
111
+ context "when the legacy backing store definition exists" do
112
+ let(:config_filename) { 'stemcell-backing-store-legacy.json' }
113
+ it "returns the options" do
114
+ expect(config.options_for_backing_store(backing_store, region)).to eql({
115
+ 'image_id' => 'ami-d9d6a6b0'
116
+ })
117
+ end
118
+ end
119
+
107
120
  end
108
121
 
109
122
  describe '#random_az_in_region' do
@@ -161,7 +161,8 @@ describe Stemcell::MetadataSource do
161
161
  it "calls the config object to retrieve the backing store options" do
162
162
  backing_options.merge!('image_id' => 'ami-nyancat')
163
163
  override_options.merge!('backing_store' => 'ebs')
164
- expect(config).to receive(:options_for_backing_store).with('ebs') { backing_options }
164
+ override_options.merge!('region' => 'us-east-1')
165
+ expect(config).to receive(:options_for_backing_store).with('ebs', 'us-east-1') { backing_options }
165
166
  expect(expansion['image_id']).to eql 'ami-nyancat'
166
167
  end
167
168
 
data/stemcell.gemspec CHANGED
@@ -17,8 +17,11 @@ Gem::Specification.new do |s|
17
17
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
18
  s.require_paths = ["lib"]
19
19
 
20
- s.add_runtime_dependency 'aws-sdk-v1', '~> 1.63'
21
- s.add_runtime_dependency 'net-ssh', '~> 2.9'
20
+ # pins several aws sdk transitive dependencies to maintain compatibility with Ruby < 2.3
21
+ s.add_runtime_dependency 'aws-eventstream', '~> 1.1.1'
22
+ s.add_runtime_dependency 'aws-sdk-ec2', '~> 1'
23
+ s.add_runtime_dependency 'aws-sigv4', '~> 1.2.4'
24
+ s.add_runtime_dependency 'net-ssh', '~> 2.9'
22
25
  if RUBY_VERSION >= '2.0'
23
26
  s.add_runtime_dependency 'chef', '>= 11.4.0'
24
27
  else
@@ -29,7 +32,7 @@ Gem::Specification.new do |s|
29
32
  # version dependency. lets explicitly include it here. if this becomes
30
33
  # no-longer a dependency of chef via chef-zero, then remove it
31
34
  s.add_runtime_dependency 'rack', '< 2.0.0'
32
- s.add_runtime_dependency 'nokogiri', '< 1.7.0'
35
+ s.add_runtime_dependency 'nokogiri', '~> 1.8.2'
33
36
  s.add_runtime_dependency 'ffi-yajl', '< 2.3.1'
34
37
 
35
38
  s.add_runtime_dependency 'trollop', '~> 2.1'