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.
@@ -0,0 +1,110 @@
1
+ require 'json'
2
+
3
+ require 'cide/docker'
4
+
5
+ module CIDE
6
+ class Runner
7
+ include CIDE::Docker
8
+
9
+ def initialize(
10
+ command: [],
11
+ env: {},
12
+ links: [],
13
+ tag: nil,
14
+ user: nil
15
+ )
16
+ fail ArgumentError, 'tag missing' unless tag
17
+
18
+ @containers = []
19
+ @id = SecureRandom.hex
20
+
21
+ @tag = tag
22
+ @env = env
23
+ @links = links
24
+ @command = command
25
+ @user = user
26
+ end
27
+
28
+ # !!!! Don't call run twice !!!!
29
+ def run!(interactive: false)
30
+ start_links!
31
+
32
+ run_options = ['--detach']
33
+
34
+ @env.each_pair do |key, value|
35
+ run_options.push '--env', [key, value].join('=')
36
+ end
37
+
38
+ @links.each do |link|
39
+ run_options.push '--link', [link.id, link.name].join(':')
40
+ end
41
+
42
+ run_options.push '--name', @id
43
+
44
+ run_options.push '--user', @user if @user
45
+
46
+ run_options.push('--interactive', '--tty') if interactive
47
+
48
+ run_options.push @tag
49
+ run_options.push(*@command)
50
+
51
+ id = docker(:run, *run_options, capture: true).strip
52
+ @containers << id
53
+ docker(:attach, id)
54
+ end
55
+
56
+ def export!(guest_dir: nil, host_dir: nil)
57
+ fail ArgumentError, 'guest export_dir missing' unless guest_dir
58
+ fail ArgumentError, 'host export_dir missing' unless host_dir
59
+
60
+ # FIXME: strip trailing slashes ?
61
+ guest_dir = File.expand_path(guest_dir, CIDE_SRC_DIR)
62
+ host_dir = File.expand_path(host_dir, Dir.pwd)
63
+
64
+ FileUtils.mkdir_p(File.dirname(host_dir))
65
+
66
+ docker :cp, [@id, guest_dir].join(':'), host_dir
67
+ end
68
+
69
+ def cleanup!(output: $stderr)
70
+ return if @containers.empty?
71
+ begin
72
+ report_containers!(output)
73
+ ensure
74
+ # Shutdown old containers
75
+ docker :rm, '--force', '--volumes', *@containers.reverse, capture: true
76
+ end
77
+ end
78
+
79
+ protected
80
+
81
+ def start_links!
82
+ @links.each do |link|
83
+ args = ['--detach']
84
+ link.env.each_pair do |key, value|
85
+ args.push('--env', [key, value].join('='))
86
+ end
87
+ args << link.image
88
+ args << link.run if link.run
89
+ link.id = docker(:run, *args, capture: true).strip
90
+ @containers << link.id
91
+ end
92
+ end
93
+
94
+ def report_containers!(output)
95
+ infos = docker(:inspect, *@containers, capture: true)
96
+
97
+ JSON.parse(infos).each do |info|
98
+ config = info['Config']
99
+ state = info['State']
100
+
101
+ next unless state['Dead'] || state['ExitCode'] > 0
102
+
103
+ output.puts "=== Failed container #{info['Id']} ==="
104
+ output.puts "Image: #{config['Image']}"
105
+ output.puts "State: #{state.inspect}"
106
+ docker(:logs, '--tail', 20, info['Id'])
107
+ end
108
+ end
109
+ end
110
+ end
@@ -1,16 +1,16 @@
1
- CIDE-BUILD 1 "JUNE 2015" cide-build "Cide Manual"
2
- =================================================
1
+ CIDE-EXEC 1 "FEBRUARY 2016" cide-exec "Cide Manual"
2
+ ===================================================
3
3
 
4
4
  NAME
5
5
  ----
6
6
 
7
- cide-build - Builds an image and executes the run script
7
+ cide-exec - Builds an image and executes the run script
8
8
 
9
9
  SYNOPSIS
10
10
  --------
11
11
 
12
- *cide build* [`-n`|`--name`=<*name*>] [`--export`|`--no-export`]
13
- [`-o`|`--export-dir`=<*path*>] [`-r`|`--run`=<*command*>]
12
+ *cide exec* [`--export`|`--no-export`] [`-o`|`--export-dir`=<*path*>]
13
+ [`--guest_export_dir`=<*path*>] [`-r`|`--run`=<*command*>]
14
14
  [`--pull`|`--no-pull`] [`-s`|`--ssh-key`=<*path*>]
15
15
 
16
16
  DESCRIPTION
@@ -28,21 +28,29 @@ CI run with isolated dependencies.
28
28
  OPTIONS
29
29
  -------
30
30
 
31
- `-n`, `--name`=<*name*>
31
+ `-n`, `-t`, `--name`=<*name*>
32
32
  Name of the built image. This can be used to differentiate between branches
33
33
  or others in a CI environment. By default the name is the basename(1) of the
34
34
  current directory.
35
35
 
36
36
  `--export`, `--no-export`
37
- Whenever to export artifacts. If `--export` is passed and the `export:`
38
- directive is set in the `cide.yml` file, artifacts from that directory are
39
- transfered back outside of the container and into the current directory.
37
+ Whether to export artifacts. If `--export` is passed and the directory to
38
+ be exported is set (either with `export_dir:` in the `cide.yml` file, or by
39
+ specifying `--guest-export-dir` on the command line) artifacts from that
40
+ directory are transfered back outside of the container (see `--export-dir`
41
+ and `--guest-export-dir`)
40
42
 
41
43
  `-o`, `--export-dir`=<*path*>
42
- By default the export directory is the same as the one given in the
43
- `export:` directive in the `cide.yml` file. It is possible to change that
44
+ Where the directory extracted from the container should be placed on the
45
+ host. By default the export directory is the same as the one given in the
46
+ `export_dir:` directive in the `cide.yml` file. It is possible to change that
44
47
  target folder outside of the container.
45
48
 
49
+ `--guest-export-dir`=<*path*>
50
+ Which directory from the container should be extracted. By default the
51
+ export directory is the same as the one specified with `--export-dir` if any,
52
+ or in the `export_dir:` directive in the `cide.yml` file otherwise.
53
+
46
54
  `-r`, `--run`=<*command*>
47
55
  Override the script to run. Usually the `run:` directive in the `cide.yml`
48
56
  is defining what to run but this could be used for a quick one-off.
@@ -0,0 +1,56 @@
1
+ CIDE-PACKAGE "FEBRUARY 2016" cide-package "Cide Manual"
2
+ =======================================================
3
+
4
+ NAME
5
+ ----
6
+
7
+ cide-package - Builds a package from the run script
8
+
9
+ SYNOPSIS
10
+ --------
11
+
12
+ *cide package* [`-n`|`-t`|`--name`=<*name*>] [`-s`|`--ssh-key`=<*path*>]
13
+ [`--package`=<*package*>] [`--upload`]
14
+ [`--set-version`]
15
+
16
+ DESCRIPTION
17
+ -----------
18
+
19
+ This tells `cide` to package a built package for you, and possibly upload it to
20
+ s3.
21
+
22
+ When invoke, cide will retrieve a previously created container (see `--name`),
23
+ perform a `cide` run, and package a given directory. The behavior is the same
24
+ as `exec` but will always export a directory, which it will upload to Amazon
25
+ s3.
26
+
27
+ OPTIONS
28
+ -------
29
+
30
+ `-n`, `-t`, `--name`
31
+ The name (tag) of the container from which to retrieve the build.
32
+
33
+ `-s`, `--ssh-key`=<*path*>
34
+ When the `use_ssh:` directive is set to true, where to get the ssh key to
35
+ inject into the container. Defaults to `~/.ssh/id_rsa`.
36
+
37
+ `--package`=<*package*>
38
+ The name of the package. The final archive will have the name
39
+ `<package>.<timestamp>.<version>.tar.gz`, where timestamp is the time at
40
+ which the packaging occured (in format `YYYY-mm-dd_HHMMSS`) and `<version>`
41
+ is the package version (see `--set-version`).
42
+
43
+ `--upload`
44
+ Whether the archive should be uploaded to Amazon s3. If the archive should be
45
+ uploaded to s3 by the packager, the s3 credentials must be provided to
46
+ `cide`. The s3 credentials must be exported as environment variables.
47
+
48
+ `--set-version`
49
+ Sets a package version. Is is solely used when naming the archive (see
50
+ `--package`). If no version is provided on the command line, a default
51
+ version name will be extracted from git (short sha).
52
+
53
+ SEE ALSO
54
+ --------
55
+
56
+ cide(1)
@@ -25,6 +25,9 @@ of the current directory's structure, builds an image with it and then runs a
25
25
  container from it that executes the specified tests. See the cide.yml(1) man
26
26
  page for the structure of that file.
27
27
 
28
+ Cide can also be used to package and upload projects after they have been
29
+ built. See cide-package(1) for more information.
30
+
28
31
  OPTIONS
29
32
  -------
30
33
 
@@ -45,11 +48,18 @@ These are global options that set the behavior of all commands.
45
48
  COMMANDS
46
49
  --------
47
50
 
48
- *cide build* [<*options*>]
51
+ *cide exec* [<*options*>]
49
52
  Builds an image and executes the run script. This is the default command
50
53
  when none is provided.
51
54
 
52
- See cide-build(1)
55
+ See cide-package(1)
56
+
57
+ *cide package* [<*options*>]
58
+ Packages a directory that resulting from a run script. Can also upload the
59
+ package to Amazon s3.
60
+
61
+ See cide-package(1)
62
+
53
63
 
54
64
  *cide clean* [<*options*>]
55
65
  Removes old containers.
@@ -91,6 +101,22 @@ https://docs.docker.com/docker/reference/commandline/cli/#environment-variables:
91
101
  *DOCKER_TLS_VERIFY*
92
102
  When set Docker uses TLS and verifies the remote.
93
103
 
104
+
105
+ The following environment variables are used by the Amazon `s3` SDK to
106
+ authenticate, and should be set by the user. See also
107
+ http://docs.aws.amazon.com/sdkforruby/api/index.html.
108
+
109
+ *AWS_ACCESS_KEY_ID*
110
+ *AWS_SECRET_ACCESS_KEY*
111
+ The Amazon key id and access key (see
112
+ http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSGettingStartedGuide/AWSCredentials.html)
113
+
114
+ *AWS_REGION*
115
+ The Amazon region (e.g. `us-east-1`)
116
+
117
+ *AWS_BUCKET*
118
+ Your bucket's name
119
+
94
120
  CONTRIBUTE
95
121
  ----------
96
122
 
@@ -4,7 +4,7 @@ CIDE.YML 1 "JUNE 2015" cide.yml "Cide Manual"
4
4
  NAME
5
5
  ----
6
6
 
7
- cide.yml - file format that directs the `cide build` execution
7
+ cide.yml - file format that directs the `cide exec` execution
8
8
 
9
9
  DESCRIPTION
10
10
  -----------
@@ -0,0 +1,29 @@
1
+ #!/bin/bash -e
2
+
3
+ if [[ -z $1 ]]; then
4
+ echo "Missing <TARGET>" >&2
5
+ exit 1
6
+ fi
7
+
8
+ packager_bin() {
9
+ local bin=$1
10
+ local name=$(basename "$1")
11
+ mkdir -p .packager/bin
12
+ cat <<BIN > ".packager/bin/${name}"
13
+ #!/bin/sh -e
14
+ here=\$(dirname "\$(readlink -f "\$0")")
15
+ target=\$(readlink -f "\$here/../../${bin}")
16
+ exec "\$target" "\$@"
17
+ BIN
18
+ chmod +x ".packager/bin/${name}"
19
+ }
20
+
21
+ TARGET=$1
22
+
23
+ cp -r "$PWD" "$TARGET"
24
+ cd "$TARGET"
25
+ bundle install --standalone --binstubs=binstubs --without=development test
26
+
27
+ rm -rf vendor/bundle/ruby/*/{bin,build_info,cache,doc,extensions,specifications}
28
+
29
+ packager_bin binstubs/cide
@@ -0,0 +1,2 @@
1
+ #!/bin/sh -e
2
+ bundle exec rake
@@ -1,12 +1,12 @@
1
- require "cide/build"
1
+ require "cide/config_file"
2
2
  require "stringio"
3
3
  require "ostruct"
4
4
  require "active_support/json"
5
5
 
6
- describe "CIDE::Build::Config::Loader" do
6
+ describe "CIDE::ConfigFile::Loader" do
7
7
  before do
8
- @config = CIDE::Build::Config.new
9
- @loader = CIDE::Build::ConfigLoader.new(@config)
8
+ @config = CIDE::ConfigFile.new
9
+ @loader = CIDE::ConfigFileLoader.new(@config)
10
10
  ENV['TEST1'] = 'test1'
11
11
  ENV['TEST2'] = 'test2'
12
12
  end
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.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zimbatm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-10 00:00:00.000000000 Z
11
+ date: 2016-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -119,6 +119,7 @@ executables:
119
119
  extensions: []
120
120
  extra_rdoc_files: []
121
121
  files:
122
+ - ".dockerignore"
122
123
  - ".editorconfig"
123
124
  - ".gitignore"
124
125
  - ".nojekyll"
@@ -138,20 +139,24 @@ files:
138
139
  - docs/cide.yml.md
139
140
  - docs/sidebar.md
140
141
  - index.html
141
- - lib/cide/build.rb
142
- - lib/cide/build/config.rb
143
- - lib/cide/build/config_loader.rb
142
+ - lib/cide/builder.rb
144
143
  - lib/cide/cli.rb
144
+ - lib/cide/config_file.rb
145
+ - lib/cide/config_file_loader.rb
145
146
  - lib/cide/constants.rb
146
147
  - lib/cide/default_cide.yml
147
148
  - lib/cide/docker.rb
148
149
  - lib/cide/dockerfile_template.erb
149
- - man/cide-build.1.md
150
+ - lib/cide/runner.rb
150
151
  - man/cide-clean.1.md
151
152
  - man/cide-debug.1.md
153
+ - man/cide-exec.1.md
152
154
  - man/cide-init.1.md
155
+ - man/cide-package.1.md
153
156
  - man/cide.1.md
154
157
  - man/cide.yml.1.md
158
+ - script/build
159
+ - script/ci
155
160
  - spec/build_config_loader_spec.rb
156
161
  - spec/spec_helper.rb
157
162
  homepage: https://zimbatm.github.io/cide
@@ -1,2 +0,0 @@
1
- require 'cide/build/config'
2
- require 'cide/build/config_loader'
@@ -1,103 +0,0 @@
1
- require 'virtus'
2
-
3
- require 'erb'
4
- require 'yaml'
5
-
6
- require 'cide/build/config_loader'
7
-
8
- module CIDE
9
- module Build
10
- class Config
11
- DOCKERFILE_TEMPLATE =
12
- File.expand_path('../../dockerfile_template.erb', __FILE__)
13
-
14
- module NiceInspect
15
- def inspect
16
- out = []
17
- attributes.each_pair do |key, value|
18
- out << "#{key}=#{value.inspect}"
19
- end
20
- "<#{out.join(' ')}>"
21
- end
22
- end
23
-
24
- class FileAdd
25
- include Virtus.model(strict: true)
26
- include NiceInspect
27
- attribute :src, Array[String], default: []
28
- attribute :dest, String
29
- end
30
-
31
- class Step
32
- include Virtus.model(strict: true)
33
- include NiceInspect
34
- attribute :add, Array[FileAdd], default: []
35
- attribute :env, Hash[String, String], default: {}
36
- attribute :run, Array[String], default: []
37
- end
38
-
39
- class Link
40
- include Virtus.model
41
- include NiceInspect
42
- attribute :name, String
43
- attribute :image, String
44
- attribute :env, Hash[String, String], default: {}
45
- attribute :run, String
46
- # Container ID added after the fact
47
- attr_accessor :id
48
- end
49
-
50
- include Virtus.model(strict: true)
51
- include NiceInspect
52
- attribute :from, String, default: 'ubuntu'
53
- attribute :as_root, Step, required: false
54
- attribute :use_ssh, Boolean, default: false
55
- attribute :before, Step, required: false
56
- attribute :env, Hash[String, String], default: {}
57
- attribute :export_dir, String, required: false
58
- attribute :links, Array[Link], default: []
59
- attribute :run, Array[String], default: ['script/ci']
60
-
61
- attr_reader :warnings, :errors
62
-
63
- def initialize(*)
64
- super
65
- @warnings = []
66
- @errors = []
67
- end
68
-
69
- def to_dockerfile
70
- ERB.new(File.read(DOCKERFILE_TEMPLATE), nil, '<>-').result(binding)
71
- end
72
-
73
- def self.load(dir = Dir.pwd, output = $stderr)
74
- file_path = find_config(dir)
75
- load_file(file_path, output)
76
- end
77
-
78
- def self.load_file(file_path, output = $stderr)
79
- obj = new
80
- loader = ConfigLoader.new(obj)
81
- loader.load YAML.load_file(file_path)
82
-
83
- obj.warnings.each do |warn|
84
- output.puts "WARN: #{warn}"
85
- end
86
-
87
- obj.errors.each do |error|
88
- output.puts "ERROR: #{error}"
89
- end
90
-
91
- return obj if obj.errors.empty?
92
- nil
93
- end
94
-
95
- def self.find_config(dir)
96
- paths = CONFIG_FILES.map { |name| File.expand_path(name, dir) }
97
- paths
98
- .find { |path| File.exist?(path) } ||
99
- fail("Config not found among these paths: #{paths.inspect}")
100
- end
101
- end
102
- end
103
- end