docker-spec 0.1.0 → 0.2.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/.gitignore +3 -0
- data/README.md +1 -0
- data/docker-spec.gemspec +10 -0
- data/lib/docker/spec.rb +179 -4
- data/lib/docker/spec/docker.rb +35 -0
- data/lib/docker/spec/version.rb +1 -1
- metadata +129 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a736a70e119ee3d55295140138d5f220f382fd4e
|
4
|
+
data.tar.gz: 7945ce843581eb476e90346fc40f63cde87db0a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3af787003c12260f552e08fdf2a23a80f6377c8c5e243cae6e06abd954643f6918f28cc80262f138510cb20f4c69f5d471c666f531c4f00a7107da83dd82dfe
|
7
|
+
data.tar.gz: 88d4133cfb8a0a4b2e2946e0cb80a8d401a763b473f0c23b9a2eae4b18ff3a435ac99f0d27632ddc0e3f5cb6c95369b79fdc962d319b7116a6211b2abc7d2d2d
|
data/.gitignore
CHANGED
data/README.md
CHANGED
data/docker-spec.gemspec
CHANGED
@@ -21,4 +21,14 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.10"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
|
25
|
+
spec.add_dependency 'serverspec'
|
26
|
+
spec.add_dependency 'docker-api'
|
27
|
+
spec.add_dependency 'pry'
|
28
|
+
spec.add_dependency 'timeout'
|
29
|
+
spec.add_dependency 'highline'
|
30
|
+
spec.add_dependency 'popen4'
|
31
|
+
spec.add_dependency 'colorize'
|
32
|
+
spec.add_dependency 'logger'
|
33
|
+
spec.add_dependency 'moneta'
|
24
34
|
end
|
data/lib/docker/spec.rb
CHANGED
@@ -1,7 +1,182 @@
|
|
1
|
-
require
|
1
|
+
require 'docker/spec/version'
|
2
|
+
require 'docker/spec/docker'
|
3
|
+
require 'serverspec'
|
4
|
+
require 'docker'
|
5
|
+
require 'pry'
|
6
|
+
require 'timeout'
|
7
|
+
require 'highline/import'
|
8
|
+
require 'popen4'
|
9
|
+
require 'colorize'
|
10
|
+
require 'yaml'
|
11
|
+
require 'logger'
|
12
|
+
require 'moneta'
|
13
|
+
require 'pp'
|
2
14
|
|
3
|
-
|
4
|
-
|
5
|
-
|
15
|
+
# Documentation
|
16
|
+
module DockerSpec
|
17
|
+
CONTAINER_RUN_WAIT_TIMEOUT = 60
|
18
|
+
CONFIG_FILE = 'docker_spec.yml'
|
19
|
+
ROOT_DIR = 'root'
|
20
|
+
STDOUT.sync = true
|
21
|
+
|
22
|
+
def self.run
|
23
|
+
load_config
|
24
|
+
build_root if @config[:build_root]
|
25
|
+
build_docker_image
|
26
|
+
rspec_run
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.push
|
30
|
+
@config[:push_container] = DockerSpec.get_config(:push_container, 'DOCKER_SPEC_PUSH_CONTAINER',
|
31
|
+
'Push new tag? ')
|
32
|
+
if @config[:push_container]
|
33
|
+
|
34
|
+
@config[:tag_db] ||
|
35
|
+
fail('tag_db is not defined in docker_spec.yml')
|
36
|
+
@config[:dockerhub] ||
|
37
|
+
fail('dockerhub is not defined in docker_spec.yml')
|
38
|
+
@config[:dockerhub][:username] ||
|
39
|
+
fail('dockerhub->username is not defined in docker_spec.yml')
|
40
|
+
@config[:dockerhub][:password] ||
|
41
|
+
fail('dockerhub->password is not defined in docker_spec.yml')
|
42
|
+
@config[:dockerhub][:email] ||
|
43
|
+
fail('dockerhub->email is not defined in docker_spec.yml')
|
44
|
+
|
45
|
+
# Open key value store and get the current tag for this repo
|
46
|
+
store = Moneta.new(:YAML, file: @config[:tag_db])
|
47
|
+
current_tag = store.key?(@config[:image_name]) ? store[@config[:image_name]].to_i : 0
|
48
|
+
new_tag = current_tag + 1
|
49
|
+
|
50
|
+
image = Docker::Image.all.detect do |i|
|
51
|
+
i.info['RepoTags'].include?(@config[:image_name] + ':latest')
|
52
|
+
end
|
53
|
+
|
54
|
+
# Login to docker hub and push latest and new_tag
|
55
|
+
Docker.authenticate! username: @config[:dockerhub][:username],
|
56
|
+
password: @config[:dockerhub][:password],
|
57
|
+
email: @config[:dockerhub][:email]
|
58
|
+
|
59
|
+
image.tag repo: @config[:image_name], tag: new_tag, force: true
|
60
|
+
puts "\nINFO: pushing #{@config[:image_name]}:#{new_tag} to DockerHub"
|
61
|
+
image.push nil, tag: new_tag
|
62
|
+
|
63
|
+
image.tag repo: @config[:image_name], tag: 'latest', force: true
|
64
|
+
puts "INFO: pushing #{@config[:image_name]}:latest to DockerHub"
|
65
|
+
image.push nil, tag: 'latest'
|
66
|
+
|
67
|
+
# Store the new tag in the tag_db
|
68
|
+
store[@config[:image_name]] = new_tag
|
69
|
+
store.close
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.load_config
|
74
|
+
File.exist?(CONFIG_FILE) || fail('Could not load docker_spec.yml')
|
75
|
+
@config = YAML.load(File.read(CONFIG_FILE)) ||
|
76
|
+
fail('docker_spec.yml is not a valid yml file')
|
77
|
+
|
78
|
+
@config[:name] || fail('name is not defined in docker_spec.yml')
|
79
|
+
@config[:account] || fail('account is not defined in docker_spec.yml')
|
80
|
+
@config[:image_name] = format '%s/%s', @config[:account], @config[:name]
|
81
|
+
@config[:container_name] = format 'docker_spec-%s', @config[:name]
|
82
|
+
@config[:build_root] = DockerSpec.get_config(:build_root, 'DOCKER_SPEC_BUILD_ROOT',
|
83
|
+
'Rebuild root filesystem? ')
|
84
|
+
@config[:clear_cache] = DockerSpec.get_config(:clear_cache, 'DOCKER_SPEC_CLEAR_CACHE',
|
85
|
+
'Clear docker cache? ')
|
86
|
+
@config
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.build_root
|
90
|
+
system 'bash -ec \'sudo chown root:root -R root &&' \
|
91
|
+
'(cd root && sudo tar zcf ../root.tar.gz .) && ' \
|
92
|
+
'sudo chown -R `id -u`:`id -g` root.tar.gz root\'' \
|
93
|
+
if Dir.exist?(ROOT_DIR)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.build_docker_image
|
97
|
+
# Rebuild the cache filesystem
|
98
|
+
build_args = ''
|
99
|
+
build_args += ' --no-cache' if @config[:clear_cache]
|
100
|
+
|
101
|
+
# Build the docker image
|
102
|
+
build_cmd = "docker build -t #{@config[:image_name]} #{build_args} ."
|
103
|
+
status = POpen4.popen4(build_cmd) do |stdout, stderr, _stdin|
|
104
|
+
stdout.each { |line| puts line }
|
105
|
+
stderr.each { |line| puts line.red }
|
106
|
+
end
|
107
|
+
fail("#{build_cmd} failed") if status.exitstatus != 0
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.rspec_run
|
111
|
+
set :backend, :docker
|
112
|
+
|
113
|
+
RSpec.configure do |rc|
|
114
|
+
rc.fail_fast = true
|
115
|
+
|
116
|
+
rc.before(:suite) do
|
117
|
+
DockerSpec.delete_container
|
118
|
+
DockerSpec.start_container
|
119
|
+
end
|
120
|
+
|
121
|
+
rc.after(:suite) do
|
122
|
+
DockerSpec.clean_up
|
123
|
+
DockerSpec.push
|
124
|
+
end
|
125
|
+
end
|
126
|
+
docker_tests
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.start_container
|
130
|
+
# Run the container with options
|
131
|
+
opts = {}
|
132
|
+
opts['HostConfig'] = { 'NetworkMode' => @config[:network_mode] } \
|
133
|
+
unless @config[:network_mode].nil?
|
134
|
+
|
135
|
+
opts['env'] = @config[:env] unless @config[:env].nil?
|
136
|
+
opts['Image'] = @config[:image_name]
|
137
|
+
opts['name'] = @config[:container_name]
|
138
|
+
container = Docker::Container.create(opts).start
|
139
|
+
|
140
|
+
# Check the logs, when it stops logging we can assume the container
|
141
|
+
# is fully up and running
|
142
|
+
log_size_ary = []
|
143
|
+
CONTAINER_RUN_WAIT_TIMEOUT.times do
|
144
|
+
log_size_ary << container.logs(stdout: true).size
|
145
|
+
break if log_size_ary.last(3).sort.uniq.size == 1 &&
|
146
|
+
log_size_ary.last(3).sort.uniq.last > 0
|
147
|
+
sleep 1
|
148
|
+
end
|
149
|
+
set :docker_container, container.id
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.delete_container
|
153
|
+
filters = { name: [@config[:container_name]] }.to_json
|
154
|
+
Docker::Container.all(all: true, filters: filters).each do |c|
|
155
|
+
c.kill
|
156
|
+
c.delete
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def self.clean_up
|
161
|
+
# Keep container running
|
162
|
+
@config[:keep_running] = DockerSpec.get_config(:keep_running, 'DOCKER_SPEC_KEEP_RUNNING',
|
163
|
+
'Keep container running? ')
|
164
|
+
if @config[:keep_running]
|
165
|
+
puts "\nINFO: To connect to a running container: \n\n" \
|
166
|
+
"docker exec -ti #{@config[:container_name]} bash"
|
167
|
+
else
|
168
|
+
delete_container
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.get_config(key, envvar, question)
|
173
|
+
value = to_boolean(ENV[envvar])
|
174
|
+
value ||= @config[key]
|
175
|
+
value ||= agree(question, 'n') if value.nil?
|
176
|
+
value
|
177
|
+
end
|
178
|
+
|
179
|
+
def self.to_boolean(str)
|
180
|
+
str == 'true' unless str.nil?
|
6
181
|
end
|
7
182
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module DockerSpec
|
2
|
+
def self.docker_tests
|
3
|
+
describe 'Running a docker container' do
|
4
|
+
before(:all) do
|
5
|
+
@config = DockerSpec.load_config
|
6
|
+
@image = Docker::Image.all.detect do |i|
|
7
|
+
i.info['RepoTags'].include?(@config[:image_name] + ':latest')
|
8
|
+
end
|
9
|
+
@container = Docker::Container.all.select do |c|
|
10
|
+
c.info["Names"] == [ "/" + @config[:container_name] ]
|
11
|
+
end.first
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should be available' do
|
15
|
+
expect(@image).to_not be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should have state running' do
|
19
|
+
expect(@container.json['State']['Running']).to be true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'Should stay running' do
|
23
|
+
expect(@container.json['State']['Running']).to be true
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'Should not have exit processes' do
|
27
|
+
expect(@container.logs(stdout: true)).to_not match(/exit/)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'Services supervisor should be running' do
|
31
|
+
expect(process('supervisord')).to be_running
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/docker/spec/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docker-spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juan Breinlinger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-02-
|
11
|
+
date: 2016-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,132 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: serverspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: docker-api
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: timeout
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: highline
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: popen4
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: colorize
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: logger
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: moneta
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
41
167
|
description: A docker spec library to build and test docker containers
|
42
168
|
email:
|
43
169
|
- "<juan.brein@breins.net>"
|
@@ -55,6 +181,7 @@ files:
|
|
55
181
|
- bin/setup
|
56
182
|
- docker-spec.gemspec
|
57
183
|
- lib/docker/spec.rb
|
184
|
+
- lib/docker/spec/docker.rb
|
58
185
|
- lib/docker/spec/version.rb
|
59
186
|
homepage: https://github.com/BreinsNet/docker-spec
|
60
187
|
licenses:
|