dockit 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Dockerfile +17 -0
- data/Gemfile +4 -0
- data/README.md +124 -0
- data/Rakefile +28 -0
- data/VERSION +1 -0
- data/bin/console +10 -0
- data/bin/dockit +8 -0
- data/bin/setup +7 -0
- data/dockit.gemspec +32 -0
- data/lib/dockit.rb +84 -0
- data/lib/dockit/cli.rb +249 -0
- data/lib/dockit/config.rb +63 -0
- data/lib/dockit/container.rb +81 -0
- data/lib/dockit/digitalocean.rb +148 -0
- data/lib/dockit/image.rb +47 -0
- data/lib/dockit/service.rb +90 -0
- data/spec/deploy/Dockit.rb +7 -0
- data/spec/deploy/mod/Dockit.rb +6 -0
- data/spec/deploy/mod/Dockit.yaml +0 -0
- data/spec/deploy/svc/Dockit.yaml +2 -0
- data/spec/dockit/bad.yaml +2 -0
- data/spec/dockit/config_spec.rb +52 -0
- data/spec/dockit/locals.yaml +3 -0
- data/spec/dockit/simple.yaml +2 -0
- data/spec/dockit_spec.rb +80 -0
- data/spec/spec_helper.rb +8 -0
- metadata +209 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e774509e3e1c4afab5a44bce1fc3eee91d7d25cf
|
4
|
+
data.tar.gz: daeda4ab4b09f3f9bc7b706fefb77271930ab4fb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d80feb61549460b39bdaa99adc5617ba09bbd75aed6e9bbe63cd20b682215d178a792682a2d202638030251595dbaf5152405b11469523b1db6f0ab3df6e7e2
|
7
|
+
data.tar.gz: 0867cb20ca447aec30f45524d2af9962c8639021a1282e45b7ac94bbc5ed4f1f3fd915aded2498ae38849f96c330e7049fb95066124f98c96c9d3a2503d663cf
|
data/.gitignore
ADDED
data/Dockerfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
FROM cybercode/alpine-ruby:2.2
|
2
|
+
ENV DOCKER_VERSION=1.8.2 BIN=/usr/local/bin/docker
|
3
|
+
|
4
|
+
RUN apk add -u curl ruby-json && curl -sSL -o $BIN \
|
5
|
+
https://get.docker.com/builds/Linux/x86_64/docker-$DOCKER_VERSION \
|
6
|
+
&& chmod +x $BIN && apk del curl
|
7
|
+
|
8
|
+
WORKDIR /app
|
9
|
+
COPY . .
|
10
|
+
RUN apk --update add --virtual build_deps \
|
11
|
+
build-base ruby-dev libc-dev linux-headers git \
|
12
|
+
&& gem build dockit.gemspec \
|
13
|
+
&& gem install --no-rdoc --no-ri dockit*.gem \
|
14
|
+
&& apk del build_deps && rm -rf /app
|
15
|
+
|
16
|
+
WORKDIR /
|
17
|
+
ENTRYPOINT ["dockit"]
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
[docker-api]: https://github.com/swipely/docker-api
|
2
|
+
|
3
|
+
# Dockit
|
4
|
+
|
5
|
+
`Dockit` is an alternative composer for docker projects. Its (IMHO) advantage is that it is scriptable, and rather than a single yaml configuration file, each service has it's own configuration file (`Dockit.yaml`), as well as an optional `Dockit.rb` which can provide scriptable configuration (as `Thor` subcommands) for any phase of the build and deploy process.
|
6
|
+
|
7
|
+
`Dockit` is built on the [Thor](https://github.com/erikhuda/thor) cli and the [docker-api] libraries.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```sh
|
12
|
+
$ gem install dockit
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
1. Create a top level deployment directory
|
18
|
+
2. Create a sub-directory for each service
|
19
|
+
3. Create a `Dockit.yaml` for each service (and optionally a `Docit.rb`.)
|
20
|
+
4. Optionally, create a top level `Dockit.rb` subcommand file to orchestrate the build and deployment of the services.
|
21
|
+
5. Run `dockit` in the root directory for help.
|
22
|
+
|
23
|
+
## `Dockit.yaml`
|
24
|
+
|
25
|
+
The sections of the config file map directly to the argument sent by the
|
26
|
+
[docker-api] to the corresponding api endpoints (see [docker api](http://docs.docker.com/reference/api/docker_remote_api_v1.9/).)
|
27
|
+
|
28
|
+
The top level sections are:
|
29
|
+
|
30
|
+
- `build`
|
31
|
+
- `create`
|
32
|
+
- `run`
|
33
|
+
|
34
|
+
At least one of the sections `build` or `create` are required. If their is no `build` section, the `create` section must specify an `Image` value. Note that most (all?) of the values specified in the `run` section can be specified in the `create: HostConfig:` instead.
|
35
|
+
|
36
|
+
### Examples
|
37
|
+
|
38
|
+
#### Simple build
|
39
|
+
|
40
|
+
```yaml
|
41
|
+
build:
|
42
|
+
t: my-image
|
43
|
+
```
|
44
|
+
|
45
|
+
Executing `dockit build` in the directory containing the file above, will create an image from the `Dockerfile` in the same directory named my-image.
|
46
|
+
|
47
|
+
Then executing `dockit start` will create and run a container named `my-image`
|
48
|
+
|
49
|
+
[docker hub]: https://registry.hub.docker.com/search?q=library
|
50
|
+
|
51
|
+
#### Pre-generated (or [docker hub]) image
|
52
|
+
```yaml
|
53
|
+
create:
|
54
|
+
Image: postgres
|
55
|
+
name: db
|
56
|
+
```
|
57
|
+
|
58
|
+
Executing `dockit build` will do nothing. Executing `dockit start` will start run a container named `db` from the local (or [docker hub] postgresql image.
|
59
|
+
|
60
|
+
#### Using locals and environment variables
|
61
|
+
|
62
|
+
The yaml file is first processed by the `ERB` template library. The "bindings" passed to the template processor can be specified on the command line with the `--locals` (alias `-l`) option. Also, the command line option `--env` (alias `-e`) is passed as `-<env>` For example, given:
|
63
|
+
|
64
|
+
```yaml
|
65
|
+
create:
|
66
|
+
Image: postgres
|
67
|
+
name: db<%= env %>
|
68
|
+
Env:
|
69
|
+
- MYVAR=<%= myval %>
|
70
|
+
```
|
71
|
+
|
72
|
+
- `dockit start` will generate an error (myval not defined)
|
73
|
+
- `dockit start -l myval:foo` will start a container named `db` with the environment variable `MVAR` set to `foo`.
|
74
|
+
- `dockt start -l myval:foo -e test` will start a container named `db-test`
|
75
|
+
|
76
|
+
## `Dockit.rb`
|
77
|
+
|
78
|
+
The `dockit.rb` file can be used to add new subcommands to the cli on a project-wide or per-service basis. For per-service subcommands, the defined class name should be the "classified" directory name, for the project-wide, it should be named `All`. If the class inherits from `SubCommand` instead of `Thor`, it will inherit two useful methods:
|
79
|
+
|
80
|
+
- `invoke_default(service)` will run the same-named (or specified) dockit command on the specified service.
|
81
|
+
- `invoke_service(service)` will run the same-named (or specifed) subcommand from the `Dockit.rb` for the specified service.
|
82
|
+
- `invoke_git(service, gem=false)` will run the same-name (or specifed) subcommand from the `Dockit.rb` for the specified service after checking out the git repository for the service as a gzip archive to `repos.tar.tz`. By default it used the `master` branch. If `gem` is true, it will checkout the gemfiles as a separate archive (`gemfiles.tar.gz`). Note that the `repos` key must be set in the services yaml file.
|
83
|
+
|
84
|
+
For example:
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
class All < SubCommand
|
88
|
+
desc 'build', 'build all images'
|
89
|
+
def build
|
90
|
+
invoke_service 'app'
|
91
|
+
invoke_default 'db'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
Would run the `build` method from the file `app/Dockit.rb` and then create a second image using the options from `db/Dockit.yaml`.
|
97
|
+
|
98
|
+
## DigitalOcean integration
|
99
|
+
|
100
|
+
If the `droplet_kit` gem is found at runtime, the `do` service be implemented. see `dockit help do` for available commands.
|
101
|
+
|
102
|
+
## Running as a docker image
|
103
|
+
|
104
|
+
If you don't want to install ruby, etc., the docker image is also available rom docker hub as `cybercode/dockit`. You can create your own version of the docker image from the source code with `docker build -t dockit .` (or `rake docker`). The `Dockerfile` has `dockit` as the entrypoint, so you can pass dockit arguments on the command-line. e.g.:
|
105
|
+
|
106
|
+
```sh
|
107
|
+
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $PWD:/app dockit help
|
108
|
+
```
|
109
|
+
|
110
|
+
## The Github boilerplate
|
111
|
+
|
112
|
+
### Development
|
113
|
+
|
114
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
115
|
+
|
116
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
117
|
+
|
118
|
+
### Contributing
|
119
|
+
|
120
|
+
1. Fork it ( https://github.com/cybercode/dockit/fork )
|
121
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
122
|
+
3. Commit your changes (`git commit -am [comment]`)
|
123
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
124
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rake/version_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
|
6
|
+
Rake::VersionTask.new
|
7
|
+
|
8
|
+
desc 'Run all specs'
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
|
11
|
+
task default: :spec
|
12
|
+
task test: :spec
|
13
|
+
|
14
|
+
Rake::RDocTask.new do |rdoc|
|
15
|
+
rdoc.rdoc_dir = 'doc'
|
16
|
+
rdoc.main = 'README'
|
17
|
+
rdoc.title = " dockit #{Version.current}"
|
18
|
+
rdoc.rdoc_files.include('README*')
|
19
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Generate Documentation"
|
23
|
+
task doc: :rdoc
|
24
|
+
|
25
|
+
desc "Build docker image"
|
26
|
+
task :docker do
|
27
|
+
system 'docker build -t dockit .'
|
28
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0
|
data/bin/console
ADDED
data/bin/dockit
ADDED
data/bin/setup
ADDED
data/dockit.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dockit"
|
7
|
+
s.version = File.read("VERSION").chomp # file managed by version gem...
|
8
|
+
s.authors = ["Rick Frankel"]
|
9
|
+
s.email = ["dockitk@rickster.com"]
|
10
|
+
|
11
|
+
s.summary = %q{A configuration manager and builder for docker projects.}
|
12
|
+
s.description = %q{Dockit is a builder for complex docker projects. Think scriptable docker-composer.}
|
13
|
+
s.homepage = "https://github.com/cybercode/dockit"
|
14
|
+
s.licenses = ["MIT"]
|
15
|
+
|
16
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
s.test_files = `git ls-files -z -- spec/*`.split("\x0")
|
18
|
+
s.bindir = "bin"
|
19
|
+
s.executables = %w[dockit]
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_development_dependency "bundler" , "~> 1.9"
|
23
|
+
s.add_development_dependency "rake" , "~> 10.4"
|
24
|
+
s.add_development_dependency "rspec" , "~> 3.2"
|
25
|
+
s.add_development_dependency "simplecov" , "~> 0.10"
|
26
|
+
s.add_development_dependency "pry" , "~> 0.10"
|
27
|
+
|
28
|
+
s.add_dependency "thor", "~> 0.19"
|
29
|
+
s.add_dependency "dotenv", "~> 2.0"
|
30
|
+
s.add_dependency "docker-api", "~> 1.21"
|
31
|
+
s.add_dependency "version", "~> 1.0"
|
32
|
+
end
|
data/lib/dockit.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'docker'
|
2
|
+
require 'yaml'
|
3
|
+
require 'pathname'
|
4
|
+
require 'version'
|
5
|
+
|
6
|
+
require 'dockit/config'
|
7
|
+
require 'dockit/service'
|
8
|
+
require 'dockit/image'
|
9
|
+
require 'dockit/container'
|
10
|
+
|
11
|
+
module Dockit
|
12
|
+
is_versioned
|
13
|
+
|
14
|
+
class Log
|
15
|
+
def debug(msg)
|
16
|
+
$stderr.puts "DEBUG: " + msg.join(' ')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# This class encapsulates the environment used in the Dockit cli.
|
21
|
+
# The class has three main attributes:
|
22
|
+
#
|
23
|
+
# root ::
|
24
|
+
# The (cached) root of the project.
|
25
|
+
# modules ::
|
26
|
+
# The "modules", a map of +Dockit.rb+ files by directory name
|
27
|
+
# services ::
|
28
|
+
# The "services", a map of +Dockit.yaml+ files, by directory name
|
29
|
+
class Env
|
30
|
+
BASENAME = 'Dockit'.freeze
|
31
|
+
attr_reader :services
|
32
|
+
attr_reader :modules
|
33
|
+
|
34
|
+
##
|
35
|
+
# Initialize services and modules in the project.
|
36
|
+
# depth [Integer] :: How deep to recurse looking for modules/services
|
37
|
+
# debug [Boolean] :: Log +docker-api+ calls.
|
38
|
+
def initialize(depth: 2, debug: false)
|
39
|
+
@root = nil
|
40
|
+
@modules = find_subcommands(depth)
|
41
|
+
@services = find_services(depth)
|
42
|
+
|
43
|
+
Docker.logger = Dockit::Log.new if debug
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# The (cached) root of the project
|
48
|
+
# Returns [String] :: The absolute path of the project root.
|
49
|
+
def root
|
50
|
+
return @root if @root
|
51
|
+
@root = dir = Dir.pwd
|
52
|
+
begin
|
53
|
+
dir = File.dirname(dir)
|
54
|
+
return @root = dir if File.exist?(File.join(dir, "#{BASENAME}.rb"))
|
55
|
+
end while dir != '/'
|
56
|
+
|
57
|
+
@root
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def find_services(depth)
|
62
|
+
find_relative(depth, 'yaml')
|
63
|
+
end
|
64
|
+
|
65
|
+
def find_subcommands(depth)
|
66
|
+
find_relative(depth, 'rb')
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_relative(depth, ext)
|
70
|
+
result = {}
|
71
|
+
(0..depth).each do |i|
|
72
|
+
pat = File.join(root, ['*'] * i, "#{BASENAME}.#{ext}")
|
73
|
+
Pathname.glob(pat).inject(result) do |memo, path|
|
74
|
+
name = path.dirname.relative_path_from(Pathname.new(root)).to_s
|
75
|
+
name = 'all' if name == '.'
|
76
|
+
memo[name] = path.to_s
|
77
|
+
|
78
|
+
memo
|
79
|
+
end
|
80
|
+
end
|
81
|
+
result
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/dockit/cli.rb
ADDED
@@ -0,0 +1,249 @@
|
|
1
|
+
require 'io/console'
|
2
|
+
require 'thor'
|
3
|
+
require 'dockit'
|
4
|
+
|
5
|
+
class SubCommand < Thor
|
6
|
+
no_commands do
|
7
|
+
# invoke command against the Dockit.yaml for the given service.
|
8
|
+
def invoke_default(service=nil, cmd: nil, opts: {})
|
9
|
+
service ||= self.class.to_s.downcase
|
10
|
+
cmd ||= current_command_chain[-1]
|
11
|
+
cmd = "default:#{cmd}"
|
12
|
+
invoke cmd, [service], options.merge(opts)
|
13
|
+
instance_variable_get('@_invocations')[Default].slice!(-1)
|
14
|
+
end
|
15
|
+
|
16
|
+
# invoke the method in the Dockit.rb for the given service.
|
17
|
+
def invoke_service(service, cmd: nil, opts: {})
|
18
|
+
cmd ||= current_command_chain[-1]
|
19
|
+
cmd = "#{service}:#{cmd}"
|
20
|
+
|
21
|
+
say "Invoking #{cmd}"
|
22
|
+
invoke cmd, [], options.merge(opts)
|
23
|
+
instance_variable_get('@_invocations')[Default].slice!(-1)
|
24
|
+
end
|
25
|
+
|
26
|
+
# export git repository before running default command
|
27
|
+
def invoke_git(service, gem=false)
|
28
|
+
invoke_default service, cmd: 'git-build', opts: { gem: gem || options.gem }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Default < Thor
|
34
|
+
DOCKIT_FILE = './Dockit.yaml'.freeze
|
35
|
+
@@root_echoed = false
|
36
|
+
|
37
|
+
class_option :host, type: :string, desc: 'override DOCKER_HOST env variable',
|
38
|
+
default: ENV['DOCKER_HOST'], aliases: ['H']
|
39
|
+
class_option :debug, type: :boolean, desc: "Log docker-api calls"
|
40
|
+
class_option :verbose, type: :boolean, aliases: ['v']
|
41
|
+
class_option :env, type: :string, desc: 'e.g., "test", "staging"', aliases: ['e']
|
42
|
+
class_option :locals, type: :hash, aliases: ['l'],
|
43
|
+
banner: "key:value [key:value ...]",
|
44
|
+
desc: "variables to pass to yaml file."
|
45
|
+
|
46
|
+
def initialize(*args)
|
47
|
+
super
|
48
|
+
ENV['DOCKER_HOST'] = options.host
|
49
|
+
unless @@root_echoed
|
50
|
+
puts "Project root: #{dockit.root}"
|
51
|
+
@@root_echoed=true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
no_commands do
|
56
|
+
def _list(what)
|
57
|
+
puts what.to_s.capitalize, dockit.send(what).keys.collect {|s| " #{s}"}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def help(*args)
|
62
|
+
super
|
63
|
+
if args.count < 1
|
64
|
+
say "Run 'dockit list' to see the complete list of SERVICEs."
|
65
|
+
say "Run 'dockit help COMMAND' to see command specific options."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "version", "Print version"
|
70
|
+
def version
|
71
|
+
say "Dockit version #{Dockit::VERSION}"
|
72
|
+
end
|
73
|
+
map %w[--version -V] => :version
|
74
|
+
|
75
|
+
desc "list", "List available services"
|
76
|
+
def list
|
77
|
+
_list :modules
|
78
|
+
_list :services
|
79
|
+
end
|
80
|
+
|
81
|
+
# "run" is a reserved word in thor...
|
82
|
+
desc 'start [SERVICE] [CMD]', 'run a service, optionally override "Cmd"'
|
83
|
+
option :transient, type: :boolean, desc: 'remove container after run'
|
84
|
+
def start(service=nil, *cmd)
|
85
|
+
opts = cmd.length > 0 ? options.merge(create: {Cmd: cmd}) : options
|
86
|
+
exec(service) do |s|
|
87
|
+
s.start(opts)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
desc 'sh [SERVICE] [CMD]', 'run an interactive command (default "bash -l")'
|
92
|
+
def sh(service=nil, *cmd)
|
93
|
+
exec(service) do |s|
|
94
|
+
cmd = %w[bash -l] if cmd.length < 1
|
95
|
+
|
96
|
+
# in case image has an entrypoint, use the cmd as the entrypoint
|
97
|
+
(entrypoint, *cmd) = cmd
|
98
|
+
s.start(
|
99
|
+
transient: true,
|
100
|
+
verbose: options.verbose,
|
101
|
+
create: {
|
102
|
+
Entrypoint: [entrypoint],
|
103
|
+
Cmd: cmd,
|
104
|
+
name: 'sh',
|
105
|
+
Tty: true,
|
106
|
+
AttachStdin: true,
|
107
|
+
AttachStdout: true,
|
108
|
+
AttachStderr: true,
|
109
|
+
OpenStdin: true,
|
110
|
+
StdinOnce: true,
|
111
|
+
})
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "cleanup", "Remove unused containers and images"
|
116
|
+
option :images , type: :boolean, default: true, desc: "remove danging images"
|
117
|
+
option :containers , type: :boolean, default: true, desc: "remove exited containers"
|
118
|
+
option :force, type: :boolean, default: false, desc: "stop and remove all"
|
119
|
+
def cleanup
|
120
|
+
if options[:containers]
|
121
|
+
Dockit::Container.clean(force: options[:force]) if ask_force('containers')
|
122
|
+
end
|
123
|
+
if options[:images]
|
124
|
+
Dockit::Image.clean(force: options[:force]) if ask_force('images')
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
desc 'config [SERVICE]', 'show parsed Dockit.yaml config file'
|
129
|
+
def config(service=nil)
|
130
|
+
exec(service) do |s|
|
131
|
+
say s.config.instance_variable_get('@config').to_yaml
|
132
|
+
end
|
133
|
+
end
|
134
|
+
desc 'push REGISTRY [SERVICE]', 'push image for SERVICE to REGSITRY'
|
135
|
+
option :force, type: :boolean, desc: 'overwrite current lastest version'
|
136
|
+
option :tag, desc: 'repos tag (defaults to "latest")', aliases: ['t']
|
137
|
+
def push(registry, service=nil)
|
138
|
+
exec(service) do |s|
|
139
|
+
s.push(registry, options[:tag], options[:force])
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
desc 'pull REGISTRY [SERVICE]', 'pull image for SERVICE from REGSITRY'
|
144
|
+
option :force, type: :boolean, desc: 'overwrite current tagged version'
|
145
|
+
option :tag, desc: 'repos tag (defaults to "latest")', aliases: ['t']
|
146
|
+
def pull(registry, service=nil)
|
147
|
+
exec(service) do |s|
|
148
|
+
s.pull(registry, options[:tag], options[:force])
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
desc 'build [SERVICE]', "Build image from current directory or service name"
|
153
|
+
def build(service=nil)
|
154
|
+
exec(service) do |s|
|
155
|
+
s.build()
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
desc 'git-build', 'build from git (gem) repository'
|
160
|
+
option :branch, desc: '<tree-ish> git reference', default: 'master'
|
161
|
+
option :gem, type: :boolean, desc: "update Gemfiles export"
|
162
|
+
def git_build(service=nil)
|
163
|
+
exec(service) do |s|
|
164
|
+
unless repos = s.config.get(:repos)
|
165
|
+
say "'repos' not defined in config file. Exiting",:red
|
166
|
+
exit 1
|
167
|
+
end
|
168
|
+
|
169
|
+
say "Exporting in #{Dir.pwd}", :green
|
170
|
+
say "<- #{repos} #{options.branch}", :green
|
171
|
+
if options.gem
|
172
|
+
# grab the Gemfiles separately for the bundler Dockerfile hack
|
173
|
+
say "-> Gemfiles", :green
|
174
|
+
export(repos, 'gemfile.tar.gz', 'Gemfile*')
|
175
|
+
end
|
176
|
+
|
177
|
+
say "-> repos.tar.gz", :green
|
178
|
+
export(repos, 'repos.tar.gz')
|
179
|
+
|
180
|
+
s.build
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
private
|
185
|
+
GIT_CMD = 'git archive -o %s --format tar.gz --remote %s %s %s'.freeze
|
186
|
+
def export(repos, archive, args='')
|
187
|
+
cmd = GIT_CMD % [archive, repos, options.branch, args]
|
188
|
+
say "#{cmd}\n", :blue if options.debug
|
189
|
+
|
190
|
+
unless system(cmd)
|
191
|
+
say "Export error", :red
|
192
|
+
exit 1
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def ask_force(type)
|
197
|
+
force = options[:force]
|
198
|
+
say "Removing #{force ? 'ALL' : ''} #{type}...", force ? :red : nil
|
199
|
+
|
200
|
+
return true ### DISABLED# unless force
|
201
|
+
yes? '... Are you sure?'
|
202
|
+
end
|
203
|
+
|
204
|
+
def dockit
|
205
|
+
@@dockit ||= Dockit::Env.new(debug: options[:debug])
|
206
|
+
end
|
207
|
+
|
208
|
+
def exec(service)
|
209
|
+
file = _file(service)
|
210
|
+
if file != DOCKIT_FILE
|
211
|
+
say "Processing #{service}"
|
212
|
+
# problem w/ path length for docker build, so change to local directory
|
213
|
+
Dir.chdir(File.dirname(file))
|
214
|
+
end
|
215
|
+
|
216
|
+
locals = options[:locals]||{}
|
217
|
+
env = options[:env]
|
218
|
+
locals[:env] = env ? "-#{env}" : ""
|
219
|
+
yield Dockit::Service.new(locals: locals)
|
220
|
+
end
|
221
|
+
|
222
|
+
def _file(service)
|
223
|
+
return dockit.services[service] if service && dockit.services[service]
|
224
|
+
return DOCKIT_FILE if File.exist?(DOCKIT_FILE)
|
225
|
+
say "No config file in current directory", :red
|
226
|
+
help
|
227
|
+
exit
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# Add digital ocean support if droplet_kit is installed
|
232
|
+
begin
|
233
|
+
require 'dockit/digitalocean'
|
234
|
+
Default.desc 'do', 'manage docker server'
|
235
|
+
Default.subcommand 'do', DO
|
236
|
+
rescue LoadError
|
237
|
+
end
|
238
|
+
|
239
|
+
# it would be nice to do this in the initialization method of the Default
|
240
|
+
# class above, but it hasn't been instantiated yet when invoking a subcommand.
|
241
|
+
Dockit::Env.new.modules.each do |k, v|
|
242
|
+
begin
|
243
|
+
require v
|
244
|
+
Default.desc k, "#{k} submodule, see 'help #{k}'"
|
245
|
+
Default.subcommand k, Module.const_get(k.capitalize)
|
246
|
+
rescue NameError => e
|
247
|
+
STDERR.puts "Can't load #{v}: #{e}"
|
248
|
+
end
|
249
|
+
end
|