conjur-debify 3.0.0.pre.1043 → 3.0.0.pre.1118

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. metadata +5 -78
  4. data/.dockerignore +0 -1
  5. data/.gitignore +0 -22
  6. data/.project +0 -18
  7. data/.rvmrc +0 -60
  8. data/CHANGELOG.md +0 -246
  9. data/CONTRIBUTING.md +0 -16
  10. data/Dockerfile +0 -33
  11. data/Gemfile +0 -2
  12. data/Jenkinsfile +0 -116
  13. data/LICENSE.txt +0 -22
  14. data/README.md +0 -303
  15. data/Rakefile +0 -75
  16. data/bin/debify +0 -5
  17. data/build.sh +0 -8
  18. data/ci/test.sh +0 -8
  19. data/debify.gemspec +0 -36
  20. data/distrib/conjur_creds.rb +0 -7
  21. data/distrib/docker-debify +0 -50
  22. data/distrib/entrypoint.sh +0 -19
  23. data/distrib/script +0 -1
  24. data/distrib/secrets +0 -1
  25. data/distrib/secrets.yml +0 -2
  26. data/example/Gemfile +0 -9
  27. data/example/Gemfile.lock +0 -32
  28. data/example/debify.sh +0 -3
  29. data/example/distrib/postinstall.sh +0 -8
  30. data/example/docker-compose.yml +0 -11
  31. data/example/net-test.sh +0 -7
  32. data/example/test.sh +0 -4
  33. data/features/detect_version.feature +0 -12
  34. data/features/package.feature +0 -23
  35. data/features/sandbox.feature +0 -23
  36. data/features/step_definitions/debify_steps.rb +0 -29
  37. data/features/support/env.rb +0 -12
  38. data/features/support/hooks.rb +0 -29
  39. data/features/support/world.rb +0 -10
  40. data/features/test.feature +0 -24
  41. data/image-tags +0 -23
  42. data/lib/conjur/debify/Dockerfile.fpm +0 -13
  43. data/lib/conjur/debify/action/publish.rb +0 -136
  44. data/lib/conjur/debify/utils.rb +0 -16
  45. data/lib/conjur/debify/version.rb +0 -5
  46. data/lib/conjur/debify.rb +0 -850
  47. data/lib/conjur/fpm/Dockerfile +0 -26
  48. data/lib/conjur/fpm/debify_utils.sh +0 -32
  49. data/lib/conjur/fpm/package.sh +0 -107
  50. data/lib/conjur/publish/Dockerfile +0 -5
  51. data/publish-rubygem.sh +0 -10
  52. data/push-image.sh +0 -6
  53. data/secrets.yml +0 -3
  54. data/spec/action/publish_spec.rb +0 -54
  55. data/spec/data/Makefile +0 -5
  56. data/spec/data/test.tar +0 -0
  57. data/spec/debify_utils_spec.rb +0 -55
  58. data/spec/spec_helper.rb +0 -1
  59. data/spec/utils_spec.rb +0 -22
  60. data/tag-image.sh +0 -6
  61. data/test.sh +0 -6
data/lib/conjur/debify.rb DELETED
@@ -1,850 +0,0 @@
1
- require "conjur/debify/version"
2
- require 'docker'
3
- require 'fileutils'
4
- require 'gli'
5
- require 'json'
6
- require 'base64'
7
- require 'tmpdir'
8
-
9
- require 'conjur/debify/utils'
10
-
11
- require 'active_support'
12
- require 'active_support/core_ext'
13
-
14
- include GLI::App
15
-
16
- DEFAULT_FILE_TYPE = "deb"
17
-
18
- config_file '.debifyrc'
19
-
20
- desc 'Set an environment variable (e.g. TERM=xterm) when starting a container'
21
- flag [:env], :multiple => true
22
-
23
- desc 'Mount local bundle to reuse gems from previous installation'
24
- default_value true
25
- switch [:'local-bundle']
26
-
27
-
28
- Docker.options[:read_timeout] = 300
29
-
30
- # This is used to turn on DEBUG notices.
31
- module DebugMixin
32
- DEBUG = ENV['DEBUG'].nil? ? true : ENV['DEBUG'].downcase == 'true'
33
-
34
- def debug *a
35
- DebugMixin.debug *a
36
- end
37
-
38
- def self.debug *a
39
- $stderr.puts *a if DEBUG
40
- end
41
-
42
- def debug_write *a
43
- DebugMixin.debug_write *a
44
- end
45
-
46
- def self.debug_write *a
47
- $stderr.write *a if DEBUG
48
- end
49
-
50
- # you can give this to various docker methods to print output if debug is on
51
- def self.docker_debug *a
52
- if a.length == 2 && a[0].is_a?(Symbol)
53
- debug a.last
54
- else
55
- a.each do |line|
56
- begin
57
- line = JSON.parse(line)
58
- line.keys.each do |k|
59
- debug line[k]
60
- end
61
- rescue JSON::ParserError
62
- # Docker For Mac is spitting out invalid JSON, so just print
63
- # out the line if parsing fails.
64
- debug line
65
- end
66
- end
67
- end
68
- end
69
-
70
- DOCKER = method :docker_debug
71
- end
72
-
73
- program_desc 'Utility commands for building and testing Conjur appliance Debian packages'
74
-
75
- version Conjur::Debify::VERSION
76
-
77
- subcommand_option_handling :normal
78
- arguments :strict
79
-
80
- def detect_version
81
- if File.exists?("VERSION") && !(base_commit = `git log --pretty='%h' VERSION | head -n 1`.strip).empty?
82
- base_version = File.read("VERSION").strip
83
- commits_since = `git log #{base_commit}..HEAD --pretty='%h'`.split("\n").size
84
- hash = `git rev-parse --short HEAD`.strip
85
- [[base_version, commits_since].join('.'), hash].join("-")
86
- else
87
- `git describe --long --tags --abbrev=7 --match 'v*.*.*' | sed -e 's/^v//'`.strip.tap do |version|
88
- raise "No Git version (tag) for project" if version.empty?
89
- end
90
- end
91
- end
92
-
93
- def git_files
94
- files = (`git ls-files -z`.split("\x0") + ['Gemfile.lock', 'VERSION']).uniq
95
- # Since submodule directories are listed, but are not files, we remove them.
96
- # Currently, `conjur-project-config` is the only submodule in Conjur, and it
97
- # can safely be removed because it's a developer-only tool. If we add another
98
- # submodule in the future needed for production, we'll need to update this
99
- # code. But YAGNI for now.
100
- files.select { |f| File.file?(f) }
101
- end
102
-
103
- def login_to_registry(appliance_image_id)
104
- config_file = File.expand_path('~/.docker/config.json')
105
- if File.exist? config_file
106
- json_config = JSON.parse(File.read(config_file))
107
- registry = appliance_image_id.split('/')[0]
108
-
109
- json_auth = json_config['auths'][registry]['auth']
110
- if json_auth
111
- username, password = Base64.decode64(json_auth).split(':')
112
- Docker.authenticate! username: username, password: password, serveraddress: registry
113
- end
114
- end
115
- end
116
-
117
- desc "Clean current working directory of non-Git-managed files"
118
- long_desc <<DESC
119
- Reliable builds depend on having a clean working directory.
120
-
121
- Because debify runs some commands in volume-mounted Docker containers,
122
- it is capable of creating root-owned files.
123
-
124
- This command will delete all files in the working directory that are not
125
- git-managed. The command is designed to run in Jenkins. Therefore, it will
126
- only perform file deletion if:
127
-
128
- * The current user, as provided by Etc.getlogin, is 'jenkins'
129
- * The BUILD_NUMBER environment variable is set
130
-
131
- File deletion can be compelled using the "force" option.
132
- DESC
133
- arg_name "project-name -- <fpm-arguments>"
134
- command "clean" do |c|
135
- c.desc "Set the current working directory"
136
- c.flag [:d, "dir"]
137
-
138
- c.desc "Ignore (don't delete) a file or directory"
139
- c.flag [:i, :ignore]
140
-
141
- c.desc "Force file deletion even if if this doesn't look like a Jenkins environment"
142
- c.switch [:force]
143
-
144
- c.action do |global_options, cmd_options, args|
145
- def looks_like_jenkins?
146
- require 'etc'
147
- Etc.getlogin == 'jenkins' && ENV['BUILD_NUMBER']
148
- end
149
-
150
- require 'set'
151
- perform_deletion = cmd_options[:force] || looks_like_jenkins?
152
- if !perform_deletion
153
- $stderr.puts "No --force, and this doesn't look like Jenkins. I won't actually delete anything"
154
- end
155
- @ignore_list = Array(cmd_options[:ignore]) + ['.', '..', '.git']
156
-
157
- def ignore_file? f
158
- @ignore_list.find { |ignore| f.index(ignore) == 0 }
159
- end
160
-
161
- dir = cmd_options[:dir] || '.'
162
- dir = File.expand_path(dir)
163
- Dir.chdir dir do
164
- require 'find'
165
- find_files = []
166
- Find.find('.').each do |p|
167
- find_files.push p[2..-1]
168
- end
169
- find_files.compact!
170
- delete_files = (find_files - git_files)
171
- delete_files.delete_if { |file|
172
- File.directory?(file) || ignore_file?(file)
173
- }
174
- if perform_deletion
175
- image = Docker::Image.create 'fromImage' => "alpine:3.3"
176
- options = {
177
- 'Cmd' => ["sh", "-c", "while true; do sleep 1; done"],
178
- 'Image' => image.id,
179
- 'Binds' => [
180
- [dir, "/src"].join(':'),
181
- ]
182
- }
183
- options['Privileged'] = true if Docker.version['Version'] >= '1.10.0'
184
- container = Docker::Container.create options
185
- begin
186
- container.start!
187
- delete_files.each do |file|
188
- puts file
189
-
190
- file = "/src/#{file}"
191
- cmd = ["rm", "-f", file]
192
-
193
- stdout, stderr, status = container.exec cmd, &DebugMixin::DOCKER
194
- $stderr.puts "Failed to delete #{file}" unless status == 0
195
- end
196
- ensure
197
- container.delete force: true
198
- end
199
- else
200
- delete_files.each do |file|
201
- puts file
202
- end
203
- end
204
- end
205
- end
206
- end
207
-
208
- def copy_packages_from_container(container, package_name, dev_package_name)
209
- Conjur::Debify::Utils.copy_from_container container, "/src/#{package_name}"
210
- puts "#{package_name}"
211
- begin
212
- Conjur::Debify::Utils.copy_from_container container, "/dev-pkg/#{dev_package_name}"
213
- puts "#{dev_package_name}"
214
- rescue Docker::Error::NotFoundError
215
- warn "#{dev_package_name} not found. The package might not have any development dependencies."
216
- end
217
- end
218
-
219
- desc "Build a debian package for a project"
220
- long_desc <<DESC
221
- The package is built using fpm (https://github.com/jordansissel/fpm).
222
-
223
- The project directory is required to contain:
224
-
225
- * A Gemfile and Gemfile.lock
226
- * A shell script called debify.sh
227
-
228
- debify.sh is invoked by the package build process to create any custom
229
- files, other than the project source tree. For example, config files can be
230
- created in /opt/conjur/etc.
231
-
232
- The distrib folder in the project source tree is intended to create scripts
233
- for package pre-install, post-install etc. The distrib folder is not included
234
- in the deb package, so its contents should be copied to the file system or
235
- packaged using fpm arguments.
236
-
237
- All arguments to this command which follow the double-dash are propagated to
238
- the fpm command.
239
- DESC
240
- arg_name "project-name -- <fpm-arguments>"
241
- command "package" do |c|
242
- c.desc "Set the current working directory"
243
- c.flag [:d, "dir"]
244
-
245
- c.desc "Set the output file type of the fpm command (e.g rpm)"
246
- c.flag [:o, :output]
247
-
248
- c.desc "Specify the deb version; by default, it's read from the VERSION file"
249
- c.flag [:v, :version]
250
-
251
- c.desc "Specify a custom Dockerfile.fpm"
252
- c.flag [:dockerfile]
253
-
254
- c.desc "Specify files to add to the FPM image that are not included from the git repo"
255
- c.flag [:'additional-files']
256
-
257
- c.action do |global_options, cmd_options, args|
258
- raise "project-name is required" unless project_name = args.shift
259
-
260
- fpm_args = []
261
- if (delimeter = args.shift) == '--'
262
- fpm_args = args.dup
263
- else
264
- raise "Unexpected argument '#{delimeter}'"
265
- end
266
-
267
- dir = cmd_options[:dir] || '.'
268
- pwd = File.dirname(__FILE__)
269
-
270
- additional_files = []
271
- if cmd_options[:'additional-files']
272
- additional_files = cmd_options[:'additional-files'].split(',').map(&:strip)
273
- end
274
-
275
- begin
276
- tries ||= 2
277
- fpm_image = Docker::Image.build_from_dir File.expand_path('fpm', File.dirname(__FILE__)), tag: "debify-fpm", &DebugMixin::DOCKER
278
- rescue
279
- image_id = File.readlines(File.expand_path('fpm/Dockerfile', File.dirname(__FILE__)))
280
- .find { | line | line =~ /^FROM/ }
281
- .split(' ')
282
- .last
283
- login_to_registry image_id
284
- retry unless (tries -= 1).zero?
285
- end
286
- DebugMixin.debug_write "Built base fpm image '#{fpm_image.id}'\n"
287
- dir = File.expand_path(dir)
288
-
289
- Dir.chdir dir do
290
- version = cmd_options[:version] || detect_version
291
-
292
- # move git files and Dockerfile to temp dir to make deb from
293
- # we do this to avoid adding "non-git" files
294
- # that aren't mentioned in the dockerignore to the deb
295
- temp_dir = Dir.mktmpdir
296
- DebugMixin.debug_write "Copying git files to tmp dir '#{temp_dir}'\n"
297
- (git_files + additional_files).each do |fname|
298
- original_file = File.join(dir, fname)
299
- destination_path = File.join(temp_dir, fname)
300
- FileUtils.mkdir_p(File.dirname(destination_path))
301
- FileUtils.cp(original_file, destination_path)
302
- end
303
-
304
- # rename specified dockerfile to 'Dockerfile' during copy, incase name is different
305
- dockerfile_path = cmd_options[:dockerfile] || File.expand_path("debify/Dockerfile.fpm", pwd)
306
- temp_dockerfile = File.join(temp_dir, "Dockerfile")
307
-
308
- # change image variable in specified Dockerfile
309
- dockerfile = File.read(dockerfile_path)
310
- replace_image = dockerfile.gsub("@@image@@", fpm_image.id)
311
- File.open(temp_dockerfile, "w") { |file| file.puts replace_image }
312
-
313
- # build image from project being debified dir
314
- image = Docker::Image.build_from_dir temp_dir, &DebugMixin::DOCKER
315
-
316
- DebugMixin.debug_write "Built fpm image '#{image.id}' for project #{project_name}\n"
317
-
318
- container_cmd_options = [project_name, version]
319
-
320
- # Set the output file type if present
321
- file_type = cmd_options[:output] || DEFAULT_FILE_TYPE
322
- container_cmd_options << "--file-type=#{file_type}"
323
-
324
- options = {
325
- 'Cmd' => container_cmd_options + fpm_args,
326
- 'Image' => image.id
327
- }
328
- options['Privileged'] = true if Docker.version['Version'] >= '1.10.0'
329
-
330
- container = Docker::Container.create options
331
- begin
332
- DebugMixin.debug_write "Packaging #{project_name} in container #{container.id}\n"
333
- container.tap(&:start!).streaming_logs(follow: true, stdout: true, stderr: true) { |stream, chunk| $stderr.puts "#{chunk}" }
334
- status = container.wait
335
- raise "Failed to package #{project_name}" unless status['StatusCode'] == 0
336
-
337
- if file_type == "deb"
338
- # Copy deb packages
339
- copy_packages_from_container(
340
- container,
341
- "conjur-#{project_name}_#{version}_amd64.deb",
342
- "conjur-#{project_name}-dev_#{version}_amd64.deb"
343
- )
344
- elsif file_type == "rpm"
345
- # Copy rpm packages
346
- # The rpm builder replaces dashes with underscores in the version
347
- rpm_version = version.tr('-', '_')
348
- copy_packages_from_container(
349
- container,
350
- "conjur-#{project_name}-#{rpm_version}-1.x86_64.rpm",
351
- "conjur-#{project_name}-dev-#{rpm_version}-1.x86_64.rpm"
352
- )
353
- end
354
- ensure
355
- container.delete(force: true)
356
- end
357
- end
358
- end
359
- end
360
-
361
- def container_command container, *args
362
- stdout, stderr, exitcode = container.exec args, &DebugMixin::DOCKER
363
- exit_now! "Command failed : #{args.join(' ')}", exitcode unless exitcode == 0
364
- stdout
365
- end
366
-
367
- def wait_for_conjur appliance_image, container
368
- container_command container, '/opt/conjur/evoke/bin/wait_for_conjur'
369
- rescue
370
- $stderr.puts container.logs
371
- raise
372
- end
373
-
374
- def network_options(cmd)
375
- cmd.desc "Specify link for test container"
376
- cmd.flag [:l, :link], :multiple => true
377
-
378
- cmd.desc 'Attach to the specified network'
379
- cmd.flag [:n, :net]
380
- end
381
-
382
- def short_id(id)
383
- if id =~ /\A[0-9a-f]{64}\z/ # 64 hex digits, docker only allows lower case letters in ids
384
- $stderr.puts "Warning: found full container id, using short id instead (#{id[0..11]} for #{id})"
385
- id[0..11]
386
- else
387
- id
388
- end
389
- end
390
-
391
- # If the source of the link is a full container id, use the short id
392
- # instead. (Docker doesn't add full container ids as network aliases,
393
- # only short ids).
394
- def shorten_source_id(link)
395
- src, dest = link.split(':')
396
- src && dest ? "#{short_id(src)}:#{dest}" : link
397
- end
398
-
399
- def add_network_config(container_config, cmd_options)
400
- host_config = container_config['HostConfig']
401
- has_links = cmd_options[:link] && !cmd_options[:link].empty?
402
- net_name = cmd_options[:net]
403
- if net_name
404
- host_config['NetworkMode'] = net_name
405
- if has_links
406
- container_config['NetworkingConfig'] ||= {}
407
- container_config['NetworkingConfig'].deep_merge!(
408
- 'EndpointsConfig' => {
409
- net_name => {
410
- 'Links' => cmd_options[:link].collect(&method(:shorten_source_id))
411
- }
412
- }
413
- )
414
- end
415
- elsif has_links
416
- # Don't shorten source ids here
417
- host_config['Links'] = cmd_options[:link]
418
- end
419
- end
420
-
421
- desc "Test a Conjur debian package in a Conjur appliance container"
422
- long_desc <<DESC
423
- First, a Conjur appliance container is created and started. By default, the
424
- container image is registry.tld/conjur-appliance-cuke-master. An image tag
425
- MUST be supplied. This image is configured with all the CONJUR_ environment
426
- variables setup for the local environment (appliance URL, cert path, admin username and
427
- password, etc). The project source tree is also mounted into the container, at
428
- /src/<project-name>.
429
-
430
- This command then waits for Conjur to initialize and be healthy. It proceeds by
431
- installing the conjur-<project-name>_<version>_amd64.deb from the project working directory.
432
-
433
- Then the evoke "test-install" command is used to install the test code in the
434
- /src/<project-name>. Basically, the development bundle is installed and the database
435
- configuration (if any) is setup.
436
-
437
- Finally, a test script from the project source tree is run, again with the container
438
- id as the program argument.
439
-
440
- Then the Conjur container is deleted (use --keep to leave it running).
441
- DESC
442
- arg_name "project-name test-script"
443
- command "test" do |c|
444
- c.desc "Set the current working directory"
445
- c.flag [:d, :dir]
446
-
447
- c.desc "Keep the Conjur appliance container after the command finishes"
448
- c.default_value false
449
- c.switch [:k, :keep]
450
-
451
- c.desc "Image name"
452
- c.default_value "registry.tld/conjur-appliance-cuke-master"
453
- c.flag [:i, :image]
454
-
455
- c.desc "Image tag, e.g. 4.5-stable, 4.6-stable"
456
- c.flag [:t, "image-tag"]
457
-
458
- c.desc "'docker pull' the Conjur container image"
459
- c.default_value true
460
- c.switch [:pull]
461
-
462
- c.desc "Specify the deb version; by default, it's read from the VERSION file"
463
- c.flag [:v, :version]
464
-
465
- c.desc "Specify volume for test container"
466
- c.flag [:'volumes-from'], :multiple => true
467
-
468
- network_options(c)
469
-
470
- c.action do |global_options, cmd_options, args|
471
- raise "project-name is required" unless project_name = args.shift
472
- raise "test-script is required" unless test_script = args.shift
473
- raise "Received extra command-line arguments" if args.shift
474
-
475
- dir = cmd_options[:dir] || '.'
476
- dir = File.expand_path(dir)
477
-
478
- raise "Directory #{dir} does not exist or is not a directory" unless File.directory?(dir)
479
- raise "Directory #{dir} does not contain a .deb file" unless Dir["#{dir}/*.deb"].length >= 1
480
-
481
- Dir.chdir dir do
482
- image_tag = cmd_options["image-tag"] or raise "image-tag is required"
483
- appliance_image_id = [cmd_options[:image], image_tag].join(":")
484
- version = cmd_options[:version] || detect_version
485
- package_name = "conjur-#{project_name}_#{version}_amd64.deb"
486
- dev_package_name = "conjur-#{project_name}-dev_#{version}_amd64.deb"
487
-
488
- raise "#{test_script} does not exist or is not a file" unless File.file?(test_script)
489
-
490
- begin
491
- tries ||= 2
492
- Docker::Image.create 'fromImage' => appliance_image_id, &DebugMixin::DOCKER if cmd_options[:pull]
493
- rescue
494
- login_to_registry appliance_image_id
495
- retry unless (tries -= 1).zero?
496
- end
497
-
498
-
499
- def build_test_image(appliance_image_id, project_name, packages)
500
- packages = packages.join " "
501
- dockerfile = <<-DOCKERFILE
502
- FROM #{appliance_image_id}
503
-
504
- COPY #{packages} /tmp/
505
-
506
- RUN if dpkg --list | grep conjur-#{project_name}; then dpkg --force all --purge conjur-#{project_name}; fi
507
- RUN if [ -f /opt/conjur/etc/#{project_name}.conf ]; then rm /opt/conjur/etc/#{project_name}.conf; fi
508
- RUN cd /tmp; dpkg --install #{packages}
509
-
510
- RUN touch /etc/service/conjur/down
511
- DOCKERFILE
512
- Dir.mktmpdir do |tmpdir|
513
- tmpfile = Tempfile.new('Dockerfile', tmpdir)
514
- File.write(tmpfile, dockerfile)
515
- dockerfile_name = File.basename(tmpfile.path)
516
- tar_cmd = "tar -cvzh -C #{tmpdir} #{dockerfile_name} -C #{Dir.pwd} #{packages}"
517
- tar = open("| #{tar_cmd}")
518
- begin
519
- Docker::Image.build_from_tar(tar, :dockerfile => dockerfile_name, &DebugMixin::DOCKER)
520
- ensure
521
- tar.close
522
- end
523
- end
524
- end
525
-
526
- packages = [package_name]
527
- packages << dev_package_name if File.exist? dev_package_name
528
-
529
- begin
530
- tries ||= 2
531
- appliance_image = build_test_image(appliance_image_id, project_name, packages)
532
- rescue
533
- login_to_registry appliance_image_id
534
- retry unless (tries -= 1).zero?
535
- end
536
-
537
- vendor_dir = File.expand_path("tmp/debify/#{project_name}/vendor", ENV['HOME'])
538
- dot_bundle_dir = File.expand_path("tmp/debify/#{project_name}/.bundle", ENV['HOME'])
539
- FileUtils.mkdir_p vendor_dir
540
- FileUtils.mkdir_p dot_bundle_dir
541
- options = {
542
- 'Image' => appliance_image.id,
543
- 'Env' => [
544
- "CONJUR_AUTHN_LOGIN=admin",
545
- "CONJUR_ENV=appliance",
546
- "CONJUR_AUTHN_API_KEY=SEcret12!!!!",
547
- "CONJUR_ADMIN_PASSWORD=SEcret12!!!!",
548
- ] + global_options[:env],
549
- 'HostConfig' => {
550
- 'Binds' => [
551
- [dir, "/src/#{project_name}"].join(':')
552
- ]
553
- }
554
- }
555
- host_config = options['HostConfig']
556
-
557
- host_config['Privileged'] = true if Docker.version['Version'] >= '1.10.0'
558
- host_config['VolumesFrom'] = cmd_options[:'volumes-from'] if cmd_options[:'volumes-from'] && !cmd_options[:'volumes-from'].empty?
559
-
560
- add_network_config(options, cmd_options)
561
-
562
- if global_options[:'local-bundle']
563
- host_config['Binds']
564
- .push([vendor_dir, "/src/#{project_name}/vendor"].join(':'))
565
- .push([dot_bundle_dir, "/src/#{project_name}/.bundle"].join(':'))
566
- end
567
-
568
- container = Docker::Container.create(options.tap { |o| DebugMixin.debug_write "creating container with options #{o.inspect}" })
569
-
570
- begin
571
- DebugMixin.debug_write "Testing #{project_name} in container #{container.id}\n"
572
-
573
- spawn("docker logs -f #{container.id}", [:out, :err] => $stderr).tap do |pid|
574
- Process.detach pid
575
- end
576
- container.start!
577
-
578
- # Wait for pg/main so that migrations can run
579
- 30.times do
580
- stdout, stderr, exitcode = container.exec %w(sv status pg/main), &DebugMixin::DOCKER
581
- status = stdout.join
582
- break if exitcode == 0 && status =~ /^run\:/
583
- sleep 1
584
- end
585
-
586
- # If we're not using shared gems, run dev-install instead of
587
- # test-install. Even having to reinstall all the gems is
588
- # better than dealing with Docker For Mac's current file
589
- # sharing performance.
590
- install_cmd = global_options[:'local-bundle'] ? 'test-install' : 'dev-install'
591
- container_command container, "/opt/conjur/evoke/bin/#{install_cmd}", project_name
592
-
593
- DebugMixin.debug_write "Starting conjur\n"
594
-
595
- container_command container, "rm", "/etc/service/conjur/down"
596
- container_command container, "sv", "start", "conjur"
597
- wait_for_conjur appliance_image, container
598
-
599
- system "./#{test_script} #{container.id}"
600
- exit_now! "#{test_script} failed with exit code #{$?.exitstatus}", $?.exitstatus unless $?.exitstatus == 0
601
- ensure
602
- unless cmd_options[:keep] || ENV['KEEP_CONTAINERS']
603
- DebugMixin.debug_write "deleting container"
604
- container.delete(force: true)
605
- end
606
- end
607
- end
608
- end
609
- end
610
-
611
- desc "Setup a development sandbox for a Conjur debian package in a Conjur appliance container"
612
- long_desc <<DESC
613
- First, a Conjur appliance container is created and started. By default, the
614
- container image is registry.tld/conjur-appliance-cuke-master. An image tag
615
- MUST be supplied. This image is configured with all the CONJUR_ environment
616
- variables setup for the local environment (appliance URL, cert path, admin username and
617
- password, etc). The project source tree is also mounted into the container, at
618
- /src/<project-name>, where <project-name> is taken from the name of the current working directory.
619
-
620
- Once in the container, use "/opt/conjur/evoke/bin/dev-install" to install the development bundle of your project.
621
- DESC
622
- command "sandbox" do |c|
623
- c.desc "Set the current working directory"
624
- c.flag [:d, :dir]
625
-
626
- c.desc "Image name"
627
- c.default_value "registry.tld/conjur-appliance-cuke-master"
628
- c.flag [:i, :image]
629
-
630
- c.desc "Image tag, e.g. 4.5-stable, 4.6-stable"
631
- c.flag [:t, "image-tag"]
632
-
633
- c.desc "Bind another source directory into the container. Use <src>:<dest>, where both are full paths."
634
- c.flag [:"bind"], :multiple => true
635
-
636
- c.desc "'docker pull' the Conjur container image"
637
- c.default_value false
638
- c.switch [:pull]
639
-
640
- network_options(c)
641
-
642
- c.desc "Specify volume for container"
643
- c.flag [:'volumes-from'], :multiple => true
644
-
645
- c.desc "Expose a port from the container to host. Use <host>:<container>."
646
- c.flag [:p, :port], :multiple => true
647
-
648
- c.desc 'Run dev-install in /src/<project-name>'
649
- c.default_value false
650
- c.switch [:'dev-install']
651
-
652
- c.desc 'Kill previous sandbox container'
653
- c.default_value false
654
- c.switch [:kill]
655
-
656
- c.desc 'A command to run in the sandbox'
657
- c.flag [:c, :command]
658
-
659
- c.action do |global_options, cmd_options, args|
660
- raise "Received extra command-line arguments" if args.shift
661
-
662
- dir = cmd_options[:dir] || '.'
663
- dir = File.expand_path(dir)
664
-
665
- raise "Directory #{dir} does not exist or is not a directory" unless File.directory?(dir)
666
-
667
- Dir.chdir dir do
668
- image_tag = cmd_options["image-tag"] or raise "image-tag is required"
669
- appliance_image_id = [cmd_options[:image], image_tag].join(":")
670
-
671
- appliance_image = if cmd_options[:pull]
672
- begin
673
- tries ||= 2
674
- Docker::Image.create 'fromImage' => appliance_image_id, &DebugMixin::DOCKER if cmd_options[:pull]
675
- rescue
676
- login_to_registry appliance_image_id
677
- retry unless (tries -= 1).zero?
678
- end
679
- else
680
- Docker::Image.get appliance_image_id
681
- end
682
-
683
- project_name = File.basename(Dir.getwd)
684
- vendor_dir = File.expand_path("tmp/debify/#{project_name}/vendor", ENV['HOME'])
685
- dot_bundle_dir = File.expand_path("tmp/debify/#{project_name}/.bundle", ENV['HOME'])
686
- FileUtils.mkdir_p vendor_dir
687
- FileUtils.mkdir_p dot_bundle_dir
688
-
689
- options = {
690
- 'name' => "#{project_name}-sandbox",
691
- 'Image' => appliance_image.id,
692
- 'WorkingDir' => "/src/#{project_name}",
693
- 'Env' => [
694
- "CONJUR_AUTHN_LOGIN=admin",
695
- "CONJUR_ENV=appliance",
696
- "CONJUR_AUTHN_API_KEY=SEcret12!!!!",
697
- "CONJUR_ADMIN_PASSWORD=SEcret12!!!!",
698
- ] + global_options[:env]
699
- }
700
-
701
- options['HostConfig'] = host_config = {}
702
- host_config['Binds'] = [
703
- [File.expand_path(".ssh/id_rsa", ENV['HOME']), "/root/.ssh/id_rsa", 'ro'].join(':'),
704
- [dir, "/src/#{project_name}"].join(':'),
705
- ] + Array(cmd_options[:bind])
706
-
707
- if global_options[:'local-bundle']
708
- host_config['Binds']
709
- .push([vendor_dir, "/src/#{project_name}/vendor"].join(':'))
710
- .push([dot_bundle_dir, "/src/#{project_name}/.bundle"].join(':'))
711
- end
712
-
713
- host_config['Privileged'] = true if Docker.version['Version'] >= '1.10.0'
714
- host_config['VolumesFrom'] = cmd_options[:'volumes-from'] unless cmd_options[:'volumes-from'].empty?
715
-
716
- add_network_config(options, cmd_options)
717
-
718
- unless cmd_options[:port].empty?
719
- port_bindings = Hash.new({})
720
- cmd_options[:port].each do |mapping|
721
- hport, cport = mapping.split(':')
722
- port_bindings["#{cport}/tcp"] = [{'HostPort' => hport}]
723
- end
724
- host_config['PortBindings'] = port_bindings
725
- end
726
-
727
- if cmd_options[:kill]
728
- previous = Docker::Container.get(options['name']) rescue nil
729
- previous.delete(:force => true) if previous
730
- end
731
-
732
- container = Docker::Container.create(options.tap { |o| DebugMixin.debug_write "creating container with options #{o.inspect}" })
733
- $stdout.puts container.id
734
- container.start!
735
-
736
- wait_for_conjur appliance_image, container
737
-
738
- if cmd_options[:'dev-install']
739
- container_command(container, "/opt/conjur/evoke/bin/dev-install", project_name)
740
- container_command(container, 'sv', 'restart', "conjur/#{project_name}")
741
- end
742
-
743
- if cmd_options[:command]
744
- container_command(container, '/bin/bash', '-c', cmd_options[:command])
745
- end
746
- end
747
- end
748
- end
749
-
750
- desc "Publish a debian package to apt repository"
751
- long_desc <<DESC
752
- Publishes a deb created with `debify package` to our private apt repository.
753
-
754
- "distribution" should match the major/minor version of the Conjur appliance you want to install to.
755
-
756
- The package name is a required option. The package version can be specified as a CLI option, or it will
757
- be auto-detected from Git.
758
-
759
- --component should be 'stable' if run after package tests pass or 'testing' if the package is not yet ready for release.
760
- If you don't specify the component, it will be set to 'testing' unless the current git branch is 'master' or 'origin/master'.
761
- The git branch is first detected from the env var GIT_BRANCH or BRANCH_NAME, and then by checking `git rev-parse --abbrev-ref HEAD`
762
- (which won't give you the answer you want when detached).
763
-
764
- DESC
765
- arg_name "distribution project-name"
766
- command "publish" do |c|
767
- c.desc "Set the current working directory"
768
- c.flag [:d, :dir]
769
-
770
- c.desc "Specify the deb package version; by default, it's computed automatically"
771
- c.flag [:v, :version]
772
-
773
- c.desc "Component to publish to, either 'stable' or the name of the git branch"
774
- c.flag [:c, :component]
775
-
776
- c.desc "Artifactory URL to publish to"
777
- c.default_value "https://conjurinc.jfrog.io/conjurinc"
778
- c.flag [:u, :url]
779
-
780
- c.desc "Artifactory Debian repo to publish package to"
781
- c.default_value "debian-private"
782
- c.flag [:r, :repo]
783
-
784
- c.desc "Artifactory RPM repo to publish package to"
785
- c.default_value "redhat-private"
786
- c.flag ['rpm-repo']
787
-
788
- c.action do |global_options, cmd_options, args|
789
- require 'conjur/debify/action/publish'
790
- raise "distribution is required" unless distribution = args.shift
791
- raise "project-name is required" unless project_name = args.shift
792
- raise "Received extra command-line arguments" if args.shift
793
-
794
- Conjur::Debify::Action::Publish.new(distribution, project_name, cmd_options).run
795
- end
796
- end
797
-
798
- desc "Auto-detect and print the repository version"
799
- command "detect-version" do |c|
800
- c.desc "Set the current working directory"
801
- c.flag [:d, :dir]
802
- c.action do |global_options, cmd_options, args|
803
- raise "Received extra command-line arguments" if args.shift
804
-
805
- dir = cmd_options[:dir] || '.'
806
- dir = File.expand_path(dir)
807
-
808
- raise "Directory #{dir} does not exist or is not a directory" unless File.directory?(dir)
809
-
810
- Dir.chdir dir do
811
- puts detect_version
812
- end
813
- end
814
- end
815
-
816
- desc 'Show the given configuration'
817
- arg_name 'configuration'
818
- command 'config' do |c|
819
- c.action do |_, _, args|
820
- raise 'no configuration provided' unless config = args.shift
821
- raise "Received extra command-line arguments" if args.shift
822
-
823
- File.open(File.join('distrib', config)).each do |line|
824
- puts line.gsub(/@@DEBIFY_VERSION@@/, Conjur::Debify::VERSION)
825
- end
826
- end
827
- end
828
-
829
-
830
- pre do |global, command, options, args|
831
- # Pre logic here
832
- # Return true to proceed; false to abort and not call the
833
- # chosen command
834
- # Use skips_pre before a command to skip this block
835
- # on that command only
836
- true
837
- end
838
-
839
- post do |global, command, options, args|
840
- # Post logic here
841
- # Use skips_post before a command to skip this
842
- # block on that command only
843
- end
844
-
845
- on_error do |exception|
846
- # Error logic here
847
- # return false to skip default error handling
848
- true
849
- end
850
-