cide 0.7.0 → 0.8.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/.dockerignore +3 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +10 -2
- data/cide.gemspec +1 -1
- data/cide.yml +2 -4
- data/docs/cide.yml.md +1 -1
- data/lib/cide/builder.rb +54 -0
- data/lib/cide/cli.rb +161 -140
- data/lib/cide/config_file.rb +101 -0
- data/lib/cide/config_file_loader.rb +305 -0
- data/lib/cide/docker.rb +16 -18
- data/lib/cide/runner.rb +110 -0
- data/man/{cide-build.1.md → cide-exec.1.md} +19 -11
- data/man/cide-package.1.md +56 -0
- data/man/cide.1.md +28 -2
- data/man/cide.yml.1.md +1 -1
- data/script/build +29 -0
- data/script/ci +2 -0
- data/spec/build_config_loader_spec.rb +4 -4
- metadata +11 -6
- data/lib/cide/build.rb +0 -2
- data/lib/cide/build/config.rb +0 -103
- data/lib/cide/build/config_loader.rb +0 -307
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 929d1f4d583f4b694999c35c0f3ff12c56164c39
|
4
|
+
data.tar.gz: a83fdc09070c59410043c8d2670d051d321bc1fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b18d7c3a787a3c09de24e4b5168eebbbc440e512b5250ecb6374730872aebdb80b65d480af0a6950ec87f3cce6ed2ba66985718d85ee3ec70ce18ca8261bbd42
|
7
|
+
data.tar.gz: ea4ca7f133d9c877f06ba76056d3ddeeccf80bc1e947da6e4986f7db3abe91c473a63ff8f28a3a77132663982f1aba2686d476acd402e100dbae4878f579d797
|
data/.dockerignore
ADDED
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cide (0.
|
4
|
+
cide (0.8.0)
|
5
5
|
thor (~> 0.19)
|
6
6
|
virtus (~> 1.0)
|
7
7
|
|
@@ -17,6 +17,12 @@ GEM
|
|
17
17
|
ast (2.0.0)
|
18
18
|
astrolabe (1.3.0)
|
19
19
|
parser (>= 2.2.0.pre.3, < 3.0)
|
20
|
+
aws-sdk (2.2.16)
|
21
|
+
aws-sdk-resources (= 2.2.16)
|
22
|
+
aws-sdk-core (2.2.16)
|
23
|
+
jmespath (~> 1.0)
|
24
|
+
aws-sdk-resources (2.2.16)
|
25
|
+
aws-sdk-core (= 2.2.16)
|
20
26
|
axiom-types (0.1.1)
|
21
27
|
descendants_tracker (~> 0.0.4)
|
22
28
|
ice_nine (~> 0.11.0)
|
@@ -30,7 +36,8 @@ GEM
|
|
30
36
|
diff-lcs (1.2.5)
|
31
37
|
equalizer (0.0.11)
|
32
38
|
i18n (0.7.0)
|
33
|
-
ice_nine (0.11.
|
39
|
+
ice_nine (0.11.2)
|
40
|
+
jmespath (1.1.3)
|
34
41
|
json (1.8.1)
|
35
42
|
md2man (4.0.0)
|
36
43
|
binman (~> 4.0)
|
@@ -78,6 +85,7 @@ PLATFORMS
|
|
78
85
|
|
79
86
|
DEPENDENCIES
|
80
87
|
activesupport
|
88
|
+
aws-sdk (~> 2)
|
81
89
|
cide!
|
82
90
|
md2man
|
83
91
|
rake
|
data/cide.gemspec
CHANGED
data/cide.yml
CHANGED
data/docs/cide.yml.md
CHANGED
data/lib/cide/builder.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
require 'cide/docker'
|
4
|
+
|
5
|
+
module CIDE
|
6
|
+
class Builder
|
7
|
+
include CIDE::Docker
|
8
|
+
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
@tmp_files = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def build(tag: nil, pull: nil, ssh_key: nil)
|
17
|
+
fail ArgumentError, 'tag missing' unless tag
|
18
|
+
|
19
|
+
if config.use_ssh
|
20
|
+
fail ArgumentError, 'ssh_key missing' unless ssh_key
|
21
|
+
unless File.exist?(ssh_key)
|
22
|
+
fail ArgumentError, "ssh_key #{ssh_key} not found"
|
23
|
+
end
|
24
|
+
create_tmp_file! TEMP_SSH_KEY, File.read(ssh_key)
|
25
|
+
end
|
26
|
+
create_tmp_file! DOCKERFILE, config.to_dockerfile
|
27
|
+
|
28
|
+
build_options = ['--force-rm']
|
29
|
+
build_options << '--pull' if pull
|
30
|
+
build_options.push '-f', DOCKERFILE
|
31
|
+
build_options.push '-t', tag
|
32
|
+
build_options << '.'
|
33
|
+
docker :build, *build_options
|
34
|
+
ensure
|
35
|
+
release_tmp_files!
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def create_tmp_file!(destination, content)
|
41
|
+
FileUtils.mkdir_p(File.dirname(destination))
|
42
|
+
@tmp_files << destination
|
43
|
+
File.write(destination, content)
|
44
|
+
# Dockerfile ADD compares content and mtime, we don't want that
|
45
|
+
File.utime(1_286_701_800, 1_286_701_800, destination)
|
46
|
+
end
|
47
|
+
|
48
|
+
def release_tmp_files!
|
49
|
+
@tmp_files.each do |file|
|
50
|
+
FileUtils.rm_f(file)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/cide/cli.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'cide/builder'
|
2
|
+
require 'cide/config_file'
|
1
3
|
require 'cide/constants'
|
2
4
|
require 'cide/docker'
|
3
|
-
require 'cide/
|
5
|
+
require 'cide/runner'
|
4
6
|
|
5
7
|
require 'thor'
|
6
8
|
|
@@ -14,12 +16,12 @@ module CIDE
|
|
14
16
|
include CIDE::Docker
|
15
17
|
include Thor::Actions
|
16
18
|
|
17
|
-
default_command '
|
19
|
+
default_command 'exec'
|
18
20
|
|
19
|
-
desc '
|
21
|
+
desc 'exec', 'Builds an image and executes the run script'
|
20
22
|
|
21
23
|
method_option 'name',
|
22
|
-
desc: 'Name of the
|
24
|
+
desc: 'Name of the image',
|
23
25
|
aliases: %w(-n -t),
|
24
26
|
default: File.basename(Dir.pwd)
|
25
27
|
|
@@ -42,7 +44,7 @@ module CIDE
|
|
42
44
|
desc: 'Override the script to run',
|
43
45
|
type: :string,
|
44
46
|
aliases: ['-r'],
|
45
|
-
default:
|
47
|
+
default: nil
|
46
48
|
|
47
49
|
method_option 'pull',
|
48
50
|
desc: 'Whenever to pull for new images on build',
|
@@ -54,117 +56,161 @@ module CIDE
|
|
54
56
|
aliases: ['-s'],
|
55
57
|
default: '~/.ssh/id_rsa'
|
56
58
|
|
57
|
-
def
|
58
|
-
containers = []
|
59
|
-
|
59
|
+
def exec
|
60
60
|
setup_docker
|
61
61
|
|
62
|
-
|
62
|
+
tag = name_to_tag options.name
|
63
|
+
|
63
64
|
banner 'Config'
|
64
|
-
|
65
|
-
|
66
|
-
ssh_key = File.expand_path(options.ssh_key)
|
67
|
-
build.run = ['sh', '-e', '-c', options.run] unless options.run.empty?
|
68
|
-
name = CIDE::Docker.id options.name
|
69
|
-
tag = "cide/#{name}"
|
70
|
-
say_status :config, build.inspect
|
65
|
+
config = ConfigFile.load(Dir.pwd)
|
66
|
+
say_status :config, config.inspect
|
71
67
|
|
72
68
|
## Build ##
|
73
69
|
banner 'Build'
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
build_options << '--pull' if options.pull
|
83
|
-
build_options.push '-f', DOCKERFILE
|
84
|
-
build_options.push '-t', tag
|
85
|
-
build_options << '.'
|
86
|
-
docker :build, *build_options
|
87
|
-
|
88
|
-
## CI ##
|
70
|
+
builder = Builder.new(config)
|
71
|
+
builder.build(
|
72
|
+
pull: options.pull,
|
73
|
+
ssh_key: File.expand_path(options.ssh_key),
|
74
|
+
tag: tag,
|
75
|
+
)
|
76
|
+
|
77
|
+
## Run ##
|
89
78
|
banner 'Run'
|
90
|
-
build.links.each do |link|
|
91
|
-
args = ['--detach']
|
92
|
-
link.env.each_pair do |key, value|
|
93
|
-
args.push('--env', [key, value].join('='))
|
94
|
-
end
|
95
|
-
args << link.image
|
96
|
-
args << link.run if link.run
|
97
|
-
link.id = docker(:run, *args, capture: true).strip
|
98
|
-
containers << link.id
|
99
|
-
end
|
100
79
|
|
101
|
-
|
80
|
+
command = options.run ? ['sh', '-e', '-c', options.run] : config.run
|
102
81
|
|
103
|
-
|
104
|
-
|
105
|
-
|
82
|
+
runner = Runner.new(
|
83
|
+
command: command,
|
84
|
+
env: config.env,
|
85
|
+
links: config.links,
|
86
|
+
tag: tag,
|
87
|
+
)
|
88
|
+
runner.run!
|
106
89
|
|
107
|
-
|
108
|
-
|
109
|
-
|
90
|
+
## Export ##
|
91
|
+
return unless options.export
|
92
|
+
banner 'Export'
|
93
|
+
runner.export!(
|
94
|
+
guest_dir: options.guest_export_dir || config.export_dir,
|
95
|
+
host_dir: options.export_dir || config.export_dir,
|
96
|
+
)
|
97
|
+
rescue Docker::Error => ex
|
98
|
+
exit ex.exitstatus
|
99
|
+
rescue RuntimeError => ex
|
100
|
+
$stderr.puts ex.to_s
|
101
|
+
exit 1
|
102
|
+
ensure
|
103
|
+
runner.cleanup! if runner
|
104
|
+
end
|
105
|
+
|
106
|
+
desc 'package', 'Builds a package from the container script/build'
|
107
|
+
method_option 'name',
|
108
|
+
desc: 'Name of the image',
|
109
|
+
aliases: %w(-n -t),
|
110
|
+
default: File.basename(Dir.pwd)
|
111
|
+
|
112
|
+
method_option 'ssh_key',
|
113
|
+
desc: 'Path to a ssh key to import into the docker image',
|
114
|
+
aliases: ['-s'],
|
115
|
+
default: '~/.ssh/id_rsa'
|
110
116
|
|
111
|
-
|
112
|
-
|
117
|
+
method_option 'package',
|
118
|
+
desc: 'Name of the package',
|
119
|
+
default: File.basename(Dir.pwd)
|
113
120
|
|
114
|
-
|
115
|
-
|
121
|
+
method_option 'upload',
|
122
|
+
desc: 'Whenever to upload the result to S3',
|
123
|
+
type: :boolean,
|
124
|
+
default: true
|
116
125
|
|
117
|
-
|
118
|
-
|
119
|
-
|
126
|
+
method_option 'set-version',
|
127
|
+
desc: 'Tells cide the package version, otherwise extracted from git',
|
128
|
+
default: nil
|
120
129
|
|
121
|
-
|
130
|
+
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION need to be passed
|
131
|
+
# either trough the env or ~/.aws/credentials file
|
132
|
+
method_option 'aws_bucket',
|
133
|
+
desc: 'AWS_BUCKET',
|
134
|
+
default: ENV['AWS_BUCKET']
|
135
|
+
|
136
|
+
def package
|
137
|
+
fail 'missing AWS_BUCKET' if options.upload && !options.aws_bucket
|
138
|
+
|
139
|
+
tag = name_to_tag options.name
|
140
|
+
|
141
|
+
build_root = File.expand_path('.package')
|
142
|
+
guest_export_dir = '/cide/package'
|
143
|
+
host_export_dir = File.join(build_root, 'package')
|
144
|
+
|
145
|
+
version = options.version || (
|
146
|
+
git_branch = `git symbolic-ref --short -q HEAD || echo unknown`.strip
|
147
|
+
git_rev = `git rev-parse --short HEAD`.strip
|
148
|
+
"#{git_branch}-#{git_rev}"
|
149
|
+
)
|
150
|
+
|
151
|
+
timestamp = Time.now.strftime('%Y-%m-%d_%H%M%S')
|
152
|
+
tar_name = "#{options.package}.#{timestamp}.#{version}.tar.gz"
|
153
|
+
tar_path = File.join(build_root, tar_name)
|
154
|
+
|
155
|
+
banner 'Config'
|
156
|
+
config = ConfigFile.load(Dir.pwd)
|
157
|
+
say_status :config, config.inspect
|
158
|
+
|
159
|
+
## Build ##
|
160
|
+
banner 'Build'
|
161
|
+
builder = Builder.new(config)
|
162
|
+
builder.build(
|
163
|
+
pull: options.pull,
|
164
|
+
ssh_key: File.expand_path(options.ssh_key),
|
165
|
+
tag: tag,
|
166
|
+
)
|
167
|
+
|
168
|
+
## Run ##
|
169
|
+
banner 'Run'
|
170
|
+
runner = Runner.new(
|
171
|
+
command: ['script/build', guest_export_dir],
|
172
|
+
env: config.env,
|
173
|
+
links: config.links,
|
174
|
+
tag: tag,
|
175
|
+
)
|
176
|
+
runner.run!
|
122
177
|
|
123
178
|
## Export ##
|
124
|
-
return unless options.export
|
125
179
|
banner 'Export'
|
126
180
|
|
127
|
-
|
128
|
-
|
181
|
+
FileUtils.rm_rf(build_root)
|
182
|
+
|
183
|
+
runner.export!(
|
184
|
+
guest_dir: guest_export_dir,
|
185
|
+
host_dir: host_export_dir,
|
186
|
+
)
|
129
187
|
|
130
|
-
|
188
|
+
# Create archive
|
189
|
+
puts "Package: #{tar_name}"
|
190
|
+
system('tar', '-czf', tar_path, '-C', host_export_dir, '.')
|
131
191
|
|
132
|
-
|
192
|
+
## Upload ##
|
133
193
|
|
134
|
-
|
135
|
-
|
194
|
+
return unless options.upload
|
195
|
+
banner 'Upload'
|
136
196
|
|
137
|
-
|
197
|
+
require 'aws-sdk'
|
198
|
+
s3 = Aws::S3::Client.new
|
199
|
+
resp = s3.put_object(
|
200
|
+
bucket: options.aws_bucket,
|
201
|
+
key: tar_name,
|
202
|
+
body: File.open(tar_path),
|
203
|
+
)
|
204
|
+
p resp
|
138
205
|
rescue Docker::Error => ex
|
139
|
-
say_status :status, 'ERROR', :red
|
140
206
|
exit ex.exitstatus
|
207
|
+
rescue RuntimeError => ex
|
208
|
+
$stderr.puts ex.to_s
|
209
|
+
exit 1
|
141
210
|
ensure
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
:inspect,
|
146
|
-
*linked_containers,
|
147
|
-
capture: true,
|
148
|
-
verbose: false,
|
149
|
-
)
|
150
|
-
JSON.parse(infos).each do |info|
|
151
|
-
config = info['Config']
|
152
|
-
state = info['State']
|
153
|
-
|
154
|
-
next unless state['Dead'] || state['ExitCode'] > 0
|
155
|
-
|
156
|
-
$stderr.puts "=== Failed linked container #{info['Id']} ==="
|
157
|
-
$stderr.puts "Image: #{config['Image']}"
|
158
|
-
$stderr.puts "State: #{state.inspect}"
|
159
|
-
docker(:logs, '--tail', 20, info['Id'])
|
160
|
-
end
|
161
|
-
end
|
162
|
-
# Shutdown old containers
|
163
|
-
unless containers.empty?
|
164
|
-
docker :rm, '--force', '--volumes', *containers.reverse,
|
165
|
-
verbose: false,
|
166
|
-
capture: true
|
167
|
-
end
|
211
|
+
FileUtils.rm_rf(build_root) if options.upload
|
212
|
+
|
213
|
+
runner.cleanup! if runner
|
168
214
|
end
|
169
215
|
|
170
216
|
desc 'debug', 'Opens a debug console in the last project image'
|
@@ -176,56 +222,33 @@ module CIDE
|
|
176
222
|
desc: 'User to run under',
|
177
223
|
default: 'cide'
|
178
224
|
def debug
|
179
|
-
containers = []
|
180
|
-
|
181
225
|
setup_docker
|
182
226
|
|
227
|
+
tag = name_to_tag options.name
|
228
|
+
|
183
229
|
## Config ##
|
184
230
|
banner 'Config'
|
185
|
-
|
186
|
-
|
187
|
-
name = CIDE::Docker.id options.name
|
188
|
-
tag = "cide/#{name}"
|
189
|
-
say_status :config, build.inspect
|
231
|
+
config = ConfigFile.load(Dir.pwd)
|
232
|
+
say_status :config, config.inspect
|
190
233
|
|
191
|
-
##
|
234
|
+
## Run ##
|
192
235
|
banner 'Run'
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
containers << link.id
|
202
|
-
end
|
203
|
-
|
204
|
-
run_options = ['--rm', '-t', '-i']
|
205
|
-
|
206
|
-
run_options.push '--user', options.user
|
236
|
+
runner = Runner.new(
|
237
|
+
command: ['bash'],
|
238
|
+
env: config.env,
|
239
|
+
links: config.links,
|
240
|
+
tag: tag,
|
241
|
+
user: options.user,
|
242
|
+
)
|
243
|
+
runner.run!(interactive: true)
|
207
244
|
|
208
|
-
build.env.each_pair do |key, value|
|
209
|
-
run_options.push '--env', [key, value].join('=')
|
210
|
-
end
|
211
|
-
|
212
|
-
build.links.each do |link|
|
213
|
-
run_options.push '--link', [link.id, link.name].join(':')
|
214
|
-
end
|
215
|
-
|
216
|
-
run_options.push tag
|
217
|
-
run_options.push 'bash'
|
218
|
-
|
219
|
-
docker(:run, *run_options)
|
220
245
|
rescue Docker::Error => ex
|
221
246
|
exit ex.exitstatus
|
247
|
+
rescue RuntimeError => ex
|
248
|
+
$stderr.puts ex.to_s
|
249
|
+
exit 1
|
222
250
|
ensure
|
223
|
-
|
224
|
-
unless containers.empty?
|
225
|
-
docker :rm, '--force', '--volumes', *containers.reverse,
|
226
|
-
verbose: false,
|
227
|
-
capture: true
|
228
|
-
end
|
251
|
+
runner.cleanup! if runner
|
229
252
|
end
|
230
253
|
|
231
254
|
desc 'clean', 'Removes old containers'
|
@@ -287,18 +310,16 @@ module CIDE
|
|
287
310
|
|
288
311
|
private
|
289
312
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
at_exit do
|
295
|
-
remove_file(destination, verbose: false)
|
296
|
-
end
|
313
|
+
# Prefixes the tag to make it recognizable by the cleaner
|
314
|
+
# Makes sure it's a valid tag
|
315
|
+
def name_to_tag(name)
|
316
|
+
"cide/#{CIDE::Docker.id name}"
|
297
317
|
end
|
298
318
|
|
299
|
-
|
319
|
+
LINE_WIDTH = 78.0
|
300
320
|
def banner(text)
|
301
|
-
pad = (
|
321
|
+
pad = (LINE_WIDTH - text.size - 4) / 2
|
322
|
+
pad = 0 if pad < 0
|
302
323
|
puts '=' * pad.floor + "[ #{text} ]" + '=' * pad.ceil
|
303
324
|
end
|
304
325
|
end
|