cide 0.0.8 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30a2f95075fe4906e536539c360fddaffdf271ba
4
- data.tar.gz: f0f615e78197b0a54391b3812b74aff2c26e8a32
3
+ metadata.gz: 420cafd5b8230af243adaadab1b4a5ff19b2c6e0
4
+ data.tar.gz: 423c2ec82b3220defe4dd1a065c6f07b37247336
5
5
  SHA512:
6
- metadata.gz: ee97b84d524086f7a8b7adc129811696f95ab1401c1b06940d6f5aef3bb1d475ac4219203ddc96caa5df7b5d325838fc1f1be1b019d3a31c311d14cdfd8b14e7
7
- data.tar.gz: c487bcdd7b5650ca4c31f2fdc3876156adb82af50fa01473b0954216b8788cc07a9a4e44d94805b8bdf88ebbd55203f3d629b65c6245cda37277df1cae474b61
6
+ metadata.gz: 6d229414e56f23a7fa6cc0c4a2d14039c4fe80aee1b4ba1b2dfb703d0b1f02e903ccc1815961b3e641d32bd66b93b52026bc0d5b644a49ed7185eefb4d1d9373
7
+ data.tar.gz: f1d25af0be10c7d39223b961f8c8299acd14b93cf0d31864c835e163947d4669697fdc898168d0619c23b4186d280ddd4bfa75d1e8e571d3b2a23c782b890b77
data/.cide.yml ADDED
@@ -0,0 +1,12 @@
1
+ ---
2
+ from: ruby:2.1
3
+ as_root:
4
+ - chown -R cide:cide /usr/local/bundle
5
+ before:
6
+ add:
7
+ - Gemfile
8
+ - Gemfile.lock
9
+ - cide.gemspec
10
+ run: bundle
11
+ use_ssh: false
12
+ run: rake
data/.travis.yml CHANGED
@@ -2,4 +2,3 @@ language: ruby
2
2
  rvm:
3
3
  - 2.1.0
4
4
  - 2.0.0
5
- - 1.9.3
data/CHANGELOG.md CHANGED
@@ -1,4 +1,11 @@
1
1
 
2
+ 0.1.0 / 2015-01-19
3
+ ==================
4
+
5
+ * cide is not compatible with ruby 1.9.3
6
+ * misc cleanup
7
+ * NEW: runtime options
8
+
2
9
  0.0.8 / 2014-12-18
3
10
  ==================
4
11
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cide (0.0.7)
4
+ cide (0.1.0)
5
5
  thor
6
6
 
7
7
  GEM
data/cide.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'cide'
5
- s.version = '0.0.8'
5
+ s.version = '0.1.0'
6
6
  s.authors = ['zimbatm']
7
7
  s.email = ['zimbatm@zimbatm.com']
8
8
  s.summary = 'CI docker runner'
data/lib/cide.rb CHANGED
@@ -1,36 +1,29 @@
1
1
  require 'erb'
2
2
  require 'json'
3
3
  require 'optparse'
4
- require 'shellwords'
5
4
  require 'time'
6
5
  require 'yaml'
7
6
 
8
7
  require 'thor'
9
8
 
9
+ require 'cide/docker'
10
+
10
11
  # CIDE is a Continuous Integration Docker Environment runner
11
12
  #
12
13
  # The juicy bits are defined in CIDE::CLI
13
14
  module CIDE
15
+ DIR = File.expand_path('..', __FILE__)
14
16
  DOCKERFILE = 'Dockerfile'
15
- SSH_CONFIG_FILE = 'ssh_config'
16
17
  TEMP_SSH_KEY = 'id_rsa.tmp'
17
- DOCKERFILE_TEMPLATE = File.read(
18
- File.expand_path('../cide_template.erb', __FILE__),
19
- )
20
- SSH_CONFIG_CONTENTS = File.read(File.expand_path('../ssh_config', __FILE__))
18
+ DOCKERFILE_TEMPLATE = File.join(DIR, 'cide_template.erb')
19
+ SSH_CONFIG_FILE = 'ssh_config'
20
+ SSH_CONFIG_PATH = File.join(DIR, SSH_CONFIG_FILE)
21
21
  CONFIG_FILE = '.cide.yml'
22
22
 
23
23
  CIDE_DIR = '/cide'
24
24
  CIDE_SRC_DIR = File.join(CIDE_DIR, '/src')
25
25
  CIDE_SSH_DIR = File.join(CIDE_DIR, '/.ssh')
26
26
 
27
- module_function
28
-
29
- def docker_id(str)
30
- # Replaces invalid docker tag characters by underscores
31
- "#{str}".downcase.gsub(/[^a-z0-9\-_.]/, '_')
32
- end
33
-
34
27
  def self.struct(opts = {}, &block)
35
28
  Class.new(Struct.new(*opts.keys), &block).new(*opts.values)
36
29
  end
@@ -45,18 +38,23 @@ module CIDE
45
38
  export_dir: './artifacts',
46
39
  host_export_dir: nil,
47
40
  run: 'script/ci',
48
- ssh_key: nil,
41
+ use_ssh: false,
42
+ ssh_key: '~/.ssh/id_rsa',
49
43
  ) do
50
44
 
51
45
  alias_method :image=, :from=
52
46
  alias_method :command=, :run=
53
47
 
54
48
  def name=(str)
55
- super CIDE.docker_id(str)
49
+ super CIDE::Docker.id(str)
50
+ end
51
+
52
+ def ssh_key_path
53
+ File.expand_path(ssh_key)
56
54
  end
57
55
 
58
56
  def to_dockerfile
59
- ERB.new(DOCKERFILE_TEMPLATE, nil, '<>-').result(binding)
57
+ ERB.new(File.read(DOCKERFILE_TEMPLATE), nil, '<>-').result(binding)
60
58
  end
61
59
 
62
60
  def merge!(opts = {})
@@ -78,8 +76,9 @@ module CIDE
78
76
 
79
77
  # Command-line option-parsing and execution for cide
80
78
  class CLI < Thor
81
- include CIDE
79
+ include CIDE::Docker
82
80
  include Thor::Actions
81
+ add_runtime_options!
83
82
 
84
83
  default_command 'build'
85
84
 
@@ -106,9 +105,9 @@ module CIDE
106
105
  default: nil
107
106
 
108
107
  method_option 'ssh_key',
109
- desc: 'The ssh key to put into the docker image',
108
+ desc: 'Path to a ssh key to import into the docker image',
110
109
  aliases: ['s'],
111
- default: nil
110
+ default: '~/.ssh/id_rsa'
112
111
 
113
112
  def build
114
113
  setup_docker
@@ -122,40 +121,18 @@ module CIDE
122
121
 
123
122
  tag = "cide/#{config.name}"
124
123
 
125
- if config.ssh_key && File.exist?(config.ssh_key)
126
- say_status :SSHkey, 'Creating temp ssh key file within directory'
127
- ssh_key_contents = File.read(config.ssh_key)
128
- File.write(TEMP_SSH_KEY, ssh_key_contents)
129
- config.ssh_key = TEMP_SSH_KEY
130
- at_exit do
131
- File.unlink(TEMP_SSH_KEY)
124
+ if config.use_ssh
125
+ unless File.exist?(config.ssh_key_path)
126
+ fail MalformattedArgumentError, "SSH key #{config.ssh_key} not found"
132
127
  end
133
- else
134
- say_status :SSHKey, 'No SSH key specified'
128
+
129
+ create_tmp_file SSH_CONFIG_FILE, File.read(SSH_CONFIG_PATH)
130
+ create_tmp_file TEMP_SSH_KEY, File.read(config.ssh_key_path)
135
131
  end
136
132
 
137
133
  say_status :config, config.to_h
138
134
 
139
- # FIXME: Move Dockerfile out of the way if it exists
140
- if !File.exist?(DOCKERFILE)
141
- say_status :Dockerfile, 'Creating temporary Dockerfile'
142
- File.write(DOCKERFILE, config.to_dockerfile)
143
- at_exit do
144
- File.unlink(DOCKERFILE)
145
- end
146
- else
147
- say_status :Dockerfile, 'Using existing Dockerfile'
148
- end
149
-
150
- if !File.exist?(SSH_CONFIG_FILE)
151
- say_status :ssh_config, 'Creating temporary ssh config'
152
- File.write(SSH_CONFIG_FILE, SSH_CONFIG_CONTENTS)
153
- at_exit do
154
- File.unlink(SSH_CONFIG_FILE)
155
- end
156
- else
157
- say_status :ssh_config, 'Using existing ssh config'
158
- end
135
+ create_tmp_file DOCKERFILE, config.to_dockerfile
159
136
 
160
137
  docker :build, '-t', tag, '.'
161
138
 
@@ -171,13 +148,16 @@ module CIDE
171
148
 
172
149
  host_export_dir = File.expand_path(
173
150
  config.host_export_dir || config.export_dir,
174
- Dir.pwd)
151
+ Dir.pwd,
152
+ )
175
153
 
176
154
  docker :cp, [id, guest_export_dir].join(':'), host_export_dir
177
155
 
178
156
  ensure
179
157
  docker :rm, '-f', id
180
158
  end
159
+ rescue Docker::Error => ex
160
+ exit ex.exitstatus
181
161
  end
182
162
 
183
163
  desc 'clean', 'Removes old containers'
@@ -195,7 +175,7 @@ module CIDE
195
175
  days_to_keep = options[:days]
196
176
  max_images = options[:count]
197
177
 
198
- x = run('docker images --no-trunc', capture: true)
178
+ x = docker('images', '--no-trunc', capture: true)
199
179
  iter = x.lines.each
200
180
  iter.next
201
181
  cide_image_ids = iter
@@ -208,7 +188,7 @@ module CIDE
208
188
  return
209
189
  end
210
190
 
211
- x = run("docker inspect #{cide_image_ids.join(' ')}", capture: true)
191
+ x = docker('inspect', *cide_image_ids, capture: true)
212
192
  cide_images = JSON.parse(x.strip)
213
193
  .each { |image| image['Created'] = Time.iso8601(image['Created']) }
214
194
  .sort { |a, b| a['Created'] <=> b['Created'] }
@@ -228,44 +208,22 @@ module CIDE
228
208
  return
229
209
  end
230
210
 
231
- run("docker rmi #{old_cide_images.join(' ')}")
211
+ docker('rmi', *old_cide_images)
232
212
  end
233
213
 
234
214
  desc 'init', "Creates a blank #{CONFIG_FILE} into the project"
235
215
  def init
236
- if File.exist?(CONFIG_FILE)
237
- puts "#{CONFIG_FILE} already exists"
238
- return
239
- end
240
216
  puts "Creating #{CONFIG_FILE} with default values"
241
217
  create_file CONFIG_FILE, DefaultConfig.to_yaml
242
218
  end
243
219
 
244
- protected
245
-
246
- def setup_docker
247
- @setup_docker ||= (
248
- if `uname`.strip == 'Darwin' && !ENV['DOCKER_HOST']
249
- unless system('which boot2docker >/dev/null 2>&1')
250
- puts 'make sure boot2docker is installed and running'
251
- puts
252
- puts '> brew install boot2docker'
253
- exit 1
254
- end
255
-
256
- `boot2docker shellinit 2>/dev/null`
257
- .lines
258
- .grep(/export (\w+)=(.*)/) { ENV[$1] = $2.strip }
259
- end
260
- true
261
- )
262
- end
220
+ private
263
221
 
264
- def docker(*args)
265
- opts = args.last.is_a?(Hash) ? args.pop : {}
266
- ret = run Shellwords.join(['docker'] + args), opts
267
- fail 'Command failed' if $?.exitstatus > 0
268
- ret
222
+ def create_tmp_file(destination, *args, &block)
223
+ create_file(destination, *args, &block)
224
+ at_exit do
225
+ remove_file(destination, verbose: false)
226
+ end
269
227
  end
270
228
  end
271
229
  end
@@ -0,0 +1,49 @@
1
+ require 'shellwords'
2
+
3
+ module CIDE
4
+ # Simple docker client helper
5
+ module Docker
6
+ # Generates a valid id for docker from any string
7
+ def self.id(str)
8
+ "#{str}".downcase.gsub(/[^a-z0-9\-_.]/, '_')
9
+ end
10
+
11
+ # Raised when a docker command exits with a status higher than zero
12
+ class Error < StandardError
13
+ attr_reader :exitstatus
14
+ def initialize(exitstatus)
15
+ @exitstatus = exitstatus
16
+ super("Failed with exitstatus #{exitstatus}")
17
+ end
18
+ end
19
+
20
+ def docker(*args, **opts)
21
+ setup_docker
22
+
23
+ ret = run Shellwords.join(['docker'] + args), opts
24
+ exitstatus = $?.exitstatus
25
+ fail Error, exitstatus if exitstatus > 0
26
+ ret
27
+ end
28
+
29
+ protected
30
+
31
+ def setup_docker
32
+ @setup_docker ||= (
33
+ if `uname`.strip == 'Darwin' && !ENV['DOCKER_HOST']
34
+ unless system('which boot2docker >/dev/null 2>&1')
35
+ puts 'make sure boot2docker is installed and running'
36
+ puts
37
+ puts '> brew install boot2docker'
38
+ exit 1
39
+ end
40
+
41
+ `boot2docker shellinit 2>/dev/null`
42
+ .lines
43
+ .grep(/export (\w+)=(.*)/) { ENV[$1] = $2.strip }
44
+ end
45
+ true
46
+ )
47
+ end
48
+ end
49
+ end
@@ -14,11 +14,11 @@ ENV HOME <%= CIDE_DIR %>
14
14
  WORKDIR <%= CIDE_SRC_DIR %>
15
15
 
16
16
  # SSH config
17
- <% if ssh_key -%>
17
+ <% if use_ssh -%>
18
18
  ADD ssh_config <%= File.expand_path('config', CIDE_SSH_DIR) %>
19
19
  RUN chmod 400 <%= File.expand_path('config', CIDE_SSH_DIR) %>
20
20
 
21
- ADD <%= ssh_key %> <%= File.expand_path('id_rsa', CIDE_SSH_DIR) %>
21
+ ADD <%= TEMP_SSH_KEY %> <%= File.expand_path('id_rsa', CIDE_SSH_DIR) %>
22
22
  RUN chmod 400 <%= File.expand_path('id_rsa', CIDE_SSH_DIR) %>
23
23
  RUN chmod 755 <%= CIDE_SSH_DIR %>
24
24
  RUN chown -R cide:cide <%= CIDE_DIR %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cide
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zimbatm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-18 00:00:00.000000000 Z
11
+ date: 2015-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -62,6 +62,7 @@ executables:
62
62
  extensions: []
63
63
  extra_rdoc_files: []
64
64
  files:
65
+ - ".cide.yml"
65
66
  - ".gitignore"
66
67
  - ".rubocop.yml"
67
68
  - ".travis.yml"
@@ -75,6 +76,7 @@ files:
75
76
  - cide
76
77
  - cide.gemspec
77
78
  - lib/cide.rb
79
+ - lib/cide/docker.rb
78
80
  - lib/cide_template.erb
79
81
  - lib/ssh_config
80
82
  homepage: https://github.com/zimbatm/cide