dockly 1.5.8 → 1.5.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dockly::BashBuilder do
4
+ describe "#normalize_for_dockly" do
5
+ it "sets up log and fatal and makes /opt/dockly" do
6
+ output = subject.normalize_for_dockly
7
+ expect(output).to include("function log")
8
+ expect(output).to include("function fatal")
9
+ expect(output).to include("mkdir -p /opt/dockly")
10
+ end
11
+ end
12
+
13
+ describe "#get_from_s3" do
14
+ let(:s3_url) { "s3://url-for-s3/file.tar.gz" }
15
+ context "uses the default output" do
16
+ it "polls from s3 and sets the s3_path" do
17
+ output = subject.get_from_s3(s3_url)
18
+ expect(output).to include("s3cmd -f get $s3_path $output_path")
19
+ expect(output).to include("s3_path=\"#{s3_url}\"")
20
+ expect(output).to include("output_path=\"-\"")
21
+ end
22
+ end
23
+ context "uses a specific output directory" do
24
+ let(:output_dir) { "test" }
25
+ it "polls from s3 and sets the s3_path and output_path" do
26
+ output = subject.get_from_s3(s3_url, output_dir)
27
+ expect(output).to include("s3cmd -f get $s3_path $output_path")
28
+ expect(output).to include("s3_path=\"#{s3_url}\"")
29
+ expect(output).to include("output_path=\"#{output_dir}\"")
30
+ end
31
+ end
32
+ end
33
+
34
+ describe "#install_package" do
35
+ let(:path) { "/opt/dockly/deb.deb" }
36
+ it "installs from the given path" do
37
+ output = subject.install_package(path)
38
+ expect(output.strip).to eq("dpkg -i \"#{path}\"")
39
+ end
40
+ end
41
+
42
+ describe "#get_and_install_deb" do
43
+ let(:s3_url) { "s3://bucket/path-to-deb.deb" }
44
+ let(:deb_path) { "/opt/dockly/deb_path.deb" }
45
+ it "gets from s3 and installs the package" do
46
+ expect(subject).to receive(:get_from_s3).with(s3_url, deb_path)
47
+ expect(subject).to receive(:install_package).with(deb_path)
48
+ subject.get_and_install_deb(s3_url, deb_path)
49
+ end
50
+ end
51
+
52
+ describe "#docker_import" do
53
+ context "when not given a repo" do
54
+ it "imports with no tagging" do
55
+ output = subject.docker_import
56
+ expect(output).to include("docker import -")
57
+ end
58
+ end
59
+
60
+ context "when given a repo" do
61
+ let(:repo) { "aRepo" }
62
+ it "imports with repo and latest" do
63
+ output = subject.docker_import(repo)
64
+ expect(output).to include("docker import - #{repo}:latest")
65
+ end
66
+
67
+ context "and a non-default tag" do
68
+ let(:tag) { "aTag" }
69
+ it "imports with repo and the tag" do
70
+ output = subject.docker_import(repo, tag)
71
+ expect(output).to include("docker import - #{repo}:#{tag}")
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "#file_docker_import" do
78
+ let(:path) { "/opt/dockly/file.tar.gz" }
79
+ it "cats, gunzips and passes to docker import" do
80
+ expect(subject).to receive(:docker_import)
81
+ output = subject.file_docker_import(path)
82
+ expect(output).to include("cat")
83
+ expect(output).to include("gunzip -c")
84
+ end
85
+ end
86
+
87
+ describe "#file_diff_docker_import" do
88
+ let(:base_image) { "s3://bucket/base_image.tar.gz" }
89
+ let(:diff_image) { "/opt/dockly/diff_image.tar.gz" }
90
+ it "gets the base file from S3 and cats that with the diff image and imports to docker" do
91
+ expect(subject).to receive(:get_from_s3).with(base_image)
92
+ expect(subject).to receive(:docker_import)
93
+ expect(subject.file_diff_docker_import(base_image, diff_image)).to include("cat \"#{diff_image}\"")
94
+ end
95
+ end
96
+
97
+ describe "#s3_docker_import" do
98
+ let(:s3_url) { "s3://bucket/image.tar.gz" }
99
+ it "pulls, gunzips and passes to docker import" do
100
+ expect(subject).to receive(:get_from_s3)
101
+ expect(subject).to receive(:docker_import)
102
+ output = subject.s3_docker_import(s3_url)
103
+ expect(output).to include("gunzip -c")
104
+ end
105
+ end
106
+
107
+ describe "#s3_diff_docker_import" do
108
+ let(:base_image) { "s3://bucket/base_image.tar.gz" }
109
+ let(:diff_image) { "s3://bucket/diff_image.tar.gz" }
110
+ it "makes two functions for getting from s3, finds the size, and imports both to docker" do
111
+ expect(subject).to receive(:get_from_s3).twice
112
+ expect(subject).to receive(:docker_import)
113
+ output = subject.s3_diff_docker_import(base_image, diff_image)
114
+ expect(output).to include("stat --format \"%s\"") # get file size
115
+ expect(output).to include("$(($size - 1024))") # compute file size
116
+ expect(output).to include("head -c $head_size")
117
+ expect(output).to include("gunzip")
118
+ end
119
+ end
120
+
121
+ describe "#registry_import" do
122
+ let(:repo) { "aRepo" }
123
+ context "not given a tag" do
124
+ it "pulls the latest" do
125
+ output = subject.registry_import(repo)
126
+ expect(output).to include("docker pull #{repo}:latest")
127
+ end
128
+ end
129
+
130
+ context "given a tag" do
131
+ let(:tag) { "aTag" }
132
+ it "pulls to specified tag" do
133
+ output = subject.registry_import(repo, tag)
134
+ expect(output).to include("docker pull #{repo}:#{tag}")
135
+ end
136
+ end
137
+ end
138
+ end
@@ -83,7 +83,7 @@ describe Dockly::BuildCache::Local do
83
83
 
84
84
  describe '#hash_output' do
85
85
  let(:output) {
86
- "f683463a09482287c33959ab71a87189"
86
+ "5ebe2fbf321fa1008833574649e986a3"
87
87
  }
88
88
 
89
89
  context "when hash command returns successfully" do
@@ -10,7 +10,7 @@ describe Dockly::Deb do
10
10
  release '8'
11
11
  pre_install "ls"
12
12
  post_install "rd /s /q C:\*"
13
- build_dir 'build/deb'
13
+ build_dir 'build'
14
14
  end
15
15
  end
16
16
  let(:filename) { "build/deb/my-sweet-deb_77.0.8_x86_64.deb" }
@@ -71,11 +71,12 @@ describe Dockly::Deb do
71
71
  git_archive '.'
72
72
  build 'touch /deb_worked'
73
73
  build_dir 'build/docker'
74
- auth_config_file '/etc/docker/.dockercfg'
75
74
 
76
75
  registry :test_docker_registry do
77
- username 'nahiluhmot'
78
- email 'hulihan.tom159@gmail.com'
76
+ auth_config_file '/etc/docker/.dockercfg'
77
+ username 'tlunter'
78
+ email 'tlunter@gmail.com'
79
+ password '******'
79
80
  end
80
81
  end
81
82
  end
@@ -119,10 +120,13 @@ describe Dockly::Deb do
119
120
  end
120
121
 
121
122
  context 'when there is no docker or foreman export' do
123
+ let(:output) { `dpkg --contents #{filename}` }
122
124
  it 'does nothing with docker or foreman' do
123
- subject.docker.should_not_receive(:generate!)
124
125
  subject.foreman.should_not_receive(:create!)
125
126
  subject.create_package!
127
+ expect(output).to_not include("deb_test-image.tgz")
128
+ expect(output).to_not include("/etc/systemd")
129
+ expect(output).to_not include("/etc/init")
126
130
  end
127
131
 
128
132
  it 'creates a deb package' do
@@ -130,6 +134,11 @@ describe Dockly::Deb do
130
134
  File.exist?(subject.build_path).should be_true
131
135
  end
132
136
  end
137
+
138
+ it "places a startup script in the package" do
139
+ subject.create_package!
140
+ expect(`dpkg --contents #{filename}`).to include("dockly-startup.sh")
141
+ end
133
142
  end
134
143
 
135
144
  describe '#exists?' do
@@ -191,9 +200,8 @@ describe Dockly::Deb do
191
200
  context 'when the package has yet to be created' do
192
201
  before { FileUtils.rm(subject.build_path) rescue nil }
193
202
 
194
- it 'creates it' do
195
- subject.should_receive(:create_package!).and_call_original
196
- subject.upload_to_s3
203
+ it 'raises an error' do
204
+ expect { subject.upload_to_s3 }.to raise_error
197
205
  end
198
206
  end
199
207
 
@@ -84,7 +84,7 @@ describe Dockly::Docker do
84
84
  subject.build "run touch /lol"
85
85
  image = subject.build_image(image)
86
86
  container = Docker::Container.create('Image' => image.id, 'Cmd' => ['ls', '-1', '/'])
87
- output = container.tap(&:start).attach
87
+ output = container.tap(&:start).attach(logs: true)
88
88
  output[0].grep(/lol/).should_not be_empty
89
89
  # TODO: stop resetting the connection, once no longer necessary after attach
90
90
  Docker.reset_connection!
@@ -147,6 +147,105 @@ describe Dockly::Docker do
147
147
  end
148
148
  end
149
149
 
150
+ describe "#export_image", :docker do
151
+ let(:image) { Docker::Image.create('fromImage' => 'base') }
152
+
153
+ context "with a registry export" do
154
+ let(:registry) { double(:registry) }
155
+ before do
156
+ subject.instance_variable_set(:"@registry", registry)
157
+ expect(subject).to receive(:push_to_registry)
158
+ end
159
+
160
+ it "pushes the image to the registry" do
161
+ subject.export_image(image)
162
+ end
163
+ end
164
+
165
+ context "with an S3 export" do
166
+ let(:export) { double(:export) }
167
+ before do
168
+ expect(Dockly::AWS::S3Writer).to receive(:new).and_return(export)
169
+ expect(export).to receive(:write).once
170
+ expect(export).to receive(:close).once
171
+ subject.s3_bucket "test-bucket"
172
+ end
173
+
174
+ context "and a whole export" do
175
+ before do
176
+ expect(subject).to receive(:export_image_whole)
177
+ end
178
+
179
+ it "exports the whole image" do
180
+ subject.export_image(image)
181
+ end
182
+ end
183
+
184
+ context "and a diff export" do
185
+ before do
186
+ subject.tar_diff true
187
+ expect(subject).to receive(:export_image_diff)
188
+ end
189
+
190
+ it "exports the diff image" do
191
+ subject.export_image(image)
192
+ end
193
+ end
194
+ end
195
+
196
+ context "with a file export" do
197
+ let(:export) { double(:export) }
198
+ before do
199
+ expect(File).to receive(:open).and_return(export)
200
+ expect(export).to receive(:write).once
201
+ expect(export).to receive(:close)
202
+ end
203
+
204
+ context "and a whole export" do
205
+ before do
206
+ expect(subject).to receive(:export_image_whole)
207
+ end
208
+
209
+ it "exports the whole image" do
210
+ subject.export_image(image)
211
+ end
212
+ end
213
+
214
+ context "and a diff export" do
215
+ before do
216
+ subject.tar_diff true
217
+ expect(subject).to receive(:export_image_diff)
218
+ end
219
+
220
+ it "exports the diff image" do
221
+ subject.export_image(image)
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ describe '#export_image_diff', :docker do
228
+ let(:output) { StringIO.new }
229
+ before do
230
+ subject.instance_eval do
231
+ import 'https://s3.amazonaws.com/swipely-pub/docker-export-ubuntu-test.tgz'
232
+ build "run touch /it_worked"
233
+ repository "dockly_export_image_diff"
234
+ end
235
+ end
236
+
237
+ it "should export only the tar with the new file" do
238
+ docker_tar = File.absolute_path(subject.ensure_tar(subject.fetch_import))
239
+ image = subject.import_base(docker_tar)
240
+ image = subject.build_image(image)
241
+ container = image.run('true').tap { |c| c.wait(10) }
242
+ subject.export_image_diff(container, output)
243
+
244
+ expect(output.string).to include('it_worked')
245
+ expect(output.string).to_not include('bin')
246
+ end
247
+ end
248
+
150
249
  describe '#generate!', :docker do
151
250
  let(:docker_file) { 'build/docker/dockly_test-image.tgz' }
152
251
  before { FileUtils.rm_rf(docker_file) }
@@ -162,6 +261,7 @@ describe Dockly::Docker do
162
261
  cleanup_images false
163
262
  end
164
263
  end
264
+
165
265
  it 'builds a docker image' do
166
266
  expect {
167
267
  subject.generate!
@@ -220,8 +320,9 @@ describe Dockly::Docker do
220
320
  build_dir 'build/docker'
221
321
 
222
322
  registry do
223
- username 'nahiluhmot'
224
- email 'tomhulihan@swipely.com'
323
+ username 'tlunter'
324
+ email 'tlunter@gmail.com'
325
+ password '******'
225
326
  end
226
327
  end
227
328
  }
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dockly::TarDiff do
4
+ let(:base) { StringIO.new }
5
+ let(:input) { StringIO.new }
6
+ let(:output) { StringIO.new }
7
+ subject { described_class.new(base, input, output) }
8
+
9
+ describe "#quick_write" do
10
+ let(:input) { StringIO.new(message) }
11
+
12
+ context "for a message under 4096 bytes" do
13
+ let(:message) { "\0" * 100 }
14
+
15
+ it "reads and writes only once" do
16
+ input.should_receive(:read).once.and_call_original
17
+ subject.quick_write(message.size)
18
+ end
19
+ end
20
+
21
+ context "for a message over 4096 bytes" do
22
+ let(:message) { "\0" * 4097 }
23
+
24
+ it "reads and writes only once" do
25
+ input.should_receive(:read).twice.and_call_original
26
+ subject.quick_write(message.size)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#write_tar_section" do
32
+ let(:header) { "ab" }
33
+ let(:message) { "cd" }
34
+ let(:input) { StringIO.new(message) }
35
+ let(:size) { message.size }
36
+ let(:remainder) { 3 }
37
+ let(:output_message) { "abcd\0\0\0" }
38
+
39
+ it "it writes the header, size length message and remainder to the output" do
40
+ subject.write_tar_section(header, message, remainder)
41
+ expect(output.string).to be == output_message
42
+ end
43
+ end
44
+
45
+ describe "#read_header" do
46
+ let(:input) { File.open("spec/fixtures/test-3.tar") }
47
+
48
+ it "with a tar with 2 files should yield exactly four times; 2 files + 2 512 byte null blocks" do
49
+ expect do |b|
50
+ block = b.to_proc
51
+ subject.read_header(input) do |*args|
52
+ block.call(*args)
53
+
54
+ data, name, prefix, mtime, typeflag, size, remainder, empty = args
55
+
56
+ case b.num_yields
57
+ when 1
58
+ expect(name).to be == "Rakefile"
59
+ when 2
60
+ expect(name).to be == "Procfile"
61
+ when 3
62
+ expect(empty).to be_true
63
+ when 4
64
+ expect(empty).to be_true
65
+ else
66
+ raise "Failed"
67
+ end
68
+
69
+ input.read(size)
70
+ end
71
+ end.to yield_control.exactly(4).times
72
+ end
73
+ end
74
+
75
+ describe "#process" do
76
+ let(:base) { File.open('spec/fixtures/test-1.tar') }
77
+ let(:input) { File.open('spec/fixtures/test-3.tar') }
78
+
79
+ it "only adds the new file to the output" do
80
+ subject.process
81
+ expect(output.string).to include("Procfile")
82
+ expect(output.string).to_not include("Rakefile")
83
+ end
84
+ end
85
+ end
Binary file
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dockly
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.8
4
+ version: 1.5.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-07-18 00:00:00.000000000 Z
12
+ date: 2014-07-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: clamp
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 1.8.4
37
+ version: 1.13.1
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: 1.8.4
45
+ version: 1.13.1
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: dockly-util
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -259,6 +259,8 @@ files:
259
259
  - img/dockly.png
260
260
  - lib/dockly.rb
261
261
  - lib/dockly/aws.rb
262
+ - lib/dockly/aws/s3_writer.rb
263
+ - lib/dockly/bash_builder.rb
262
264
  - lib/dockly/build_cache.rb
263
265
  - lib/dockly/build_cache/base.rb
264
266
  - lib/dockly/build_cache/docker.rb
@@ -269,12 +271,25 @@ files:
269
271
  - lib/dockly/docker/registry.rb
270
272
  - lib/dockly/foreman.rb
271
273
  - lib/dockly/rake_task.rb
274
+ - lib/dockly/tar_diff.rb
272
275
  - lib/dockly/util/git.rb
273
276
  - lib/dockly/util/tar.rb
274
277
  - lib/dockly/version.rb
275
278
  - lib/foreman/cli_fix.rb
276
279
  - lib/foreman/export/base_fix.rb
280
+ - snippets/docker_import.erb
281
+ - snippets/file_diff_docker_import.erb
282
+ - snippets/file_docker_import.erb
283
+ - snippets/get_and_install_deb.erb
284
+ - snippets/get_from_s3.erb
285
+ - snippets/install_package.erb
286
+ - snippets/normalize_for_dockly.erb
287
+ - snippets/registry_import.erb
288
+ - snippets/s3_diff_docker_import.erb
289
+ - snippets/s3_docker_import.erb
290
+ - spec/dockly/aws/s3_writer_spec.rb
277
291
  - spec/dockly/aws_spec.rb
292
+ - spec/dockly/bash_builder_spec.rb
278
293
  - spec/dockly/build_cache/base_spec.rb
279
294
  - spec/dockly/build_cache/docker_spec.rb
280
295
  - spec/dockly/build_cache/local_spec.rb
@@ -283,6 +298,7 @@ files:
283
298
  - spec/dockly/docker/registry_spec.rb
284
299
  - spec/dockly/docker_spec.rb
285
300
  - spec/dockly/foreman_spec.rb
301
+ - spec/dockly/tar_diff_spec.rb
286
302
  - spec/dockly_spec.rb
287
303
  - spec/fixtures/Procfile
288
304
  - spec/fixtures/Rakefile
@@ -291,6 +307,7 @@ files:
291
307
  - spec/fixtures/tar-2.tar
292
308
  - spec/fixtures/test-1.tar
293
309
  - spec/fixtures/test-2.tar.gz
310
+ - spec/fixtures/test-3.tar
294
311
  - spec/spec_helper.rb
295
312
  - spec/support/vcr.rb
296
313
  homepage: https://github.com/swipely/dockly
@@ -319,7 +336,9 @@ signing_key:
319
336
  specification_version: 3
320
337
  summary: Packaging made easy
321
338
  test_files:
339
+ - spec/dockly/aws/s3_writer_spec.rb
322
340
  - spec/dockly/aws_spec.rb
341
+ - spec/dockly/bash_builder_spec.rb
323
342
  - spec/dockly/build_cache/base_spec.rb
324
343
  - spec/dockly/build_cache/docker_spec.rb
325
344
  - spec/dockly/build_cache/local_spec.rb
@@ -328,6 +347,7 @@ test_files:
328
347
  - spec/dockly/docker/registry_spec.rb
329
348
  - spec/dockly/docker_spec.rb
330
349
  - spec/dockly/foreman_spec.rb
350
+ - spec/dockly/tar_diff_spec.rb
331
351
  - spec/dockly_spec.rb
332
352
  - spec/fixtures/Procfile
333
353
  - spec/fixtures/Rakefile
@@ -336,5 +356,6 @@ test_files:
336
356
  - spec/fixtures/tar-2.tar
337
357
  - spec/fixtures/test-1.tar
338
358
  - spec/fixtures/test-2.tar.gz
359
+ - spec/fixtures/test-3.tar
339
360
  - spec/spec_helper.rb
340
361
  - spec/support/vcr.rb