dctl_rb 0.12.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -2
- data/Gemfile.lock +4 -4
- data/README.md +14 -1
- data/exe/dctl +54 -36
- data/lib/dctl/main.rb +17 -5
- data/lib/dctl/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 891e4ebdd5366c0525f1e5d50fddf2fb5351594a1b284580e782b1ab5865d7a1
|
4
|
+
data.tar.gz: 6555744900318c5e7b881c34e0ec09702f3980ffa81865ec1801e713293474f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38501937b88ebeb904280fed31f5abbf58856212a538e8695d13c503c528d77a933aeaa10cb5edd7704413ee26d8165997e777afc28d7c7eeaca3eaf411b94cb
|
7
|
+
data.tar.gz: c0f7f9419517cea03fe5a4d9357c176952b8580869d826dccd5335901e563048debd2d51494065b577d46d8e014b6dfaf014bcb64b64aa3daa315b0392b3103a
|
data/.travis.yml
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 2.4
|
5
|
-
|
4
|
+
- 2.4
|
5
|
+
- 2.5
|
6
|
+
before_install:
|
7
|
+
- gem install bundler -v 1.16.0
|
8
|
+
- bundle config mirror.https://rubygems.org https://gems.jutonz.com
|
6
9
|
deploy:
|
7
10
|
provider: rubygems
|
8
11
|
api_key:
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dctl_rb (0.
|
4
|
+
dctl_rb (0.13.0)
|
5
5
|
config (>= 1, < 2)
|
6
6
|
rainbow (>= 2.2, < 3)
|
7
7
|
rake (~> 12)
|
@@ -10,7 +10,7 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
activesupport (5.2.
|
13
|
+
activesupport (5.2.1)
|
14
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
15
|
i18n (>= 0.7, < 2)
|
16
16
|
minitest (~> 5.1)
|
@@ -43,14 +43,14 @@ GEM
|
|
43
43
|
dry-equalizer (~> 0.2)
|
44
44
|
dry-inflector (~> 0.1, >= 0.1.2)
|
45
45
|
dry-logic (~> 0.4, >= 0.4.2)
|
46
|
-
dry-validation (0.12.
|
46
|
+
dry-validation (0.12.2)
|
47
47
|
concurrent-ruby (~> 1.0)
|
48
48
|
dry-configurable (~> 0.1, >= 0.1.3)
|
49
49
|
dry-core (~> 0.2, >= 0.2.1)
|
50
50
|
dry-equalizer (~> 0.2)
|
51
51
|
dry-logic (~> 0.4, >= 0.4.0)
|
52
52
|
dry-types (~> 0.13.1)
|
53
|
-
i18n (1.0
|
53
|
+
i18n (1.1.0)
|
54
54
|
concurrent-ruby (~> 1.0)
|
55
55
|
minitest (5.11.3)
|
56
56
|
rainbow (2.2.2)
|
data/README.md
CHANGED
@@ -127,7 +127,20 @@ docker
|
|
127
127
|
* `project` (required)
|
128
128
|
|
129
129
|
### Optional keys
|
130
|
-
*
|
130
|
+
* `custom_commands`
|
131
|
+
* This is basically a set of aliases you can add if you happen to be running the same commands again and again
|
132
|
+
|
133
|
+
For instance, if initially creating your database requires two commands, you can add an alias to make it just one:
|
134
|
+
```yaml
|
135
|
+
custom_commands:
|
136
|
+
migrate:
|
137
|
+
- dctl run --rm psql initdb
|
138
|
+
- dctl run --rm app mix ecto.setup
|
139
|
+
```
|
140
|
+
|
141
|
+
Now you can just run `dctl migrate` and it will run the commands in the order you specified.
|
142
|
+
|
143
|
+
This just shells out, so you can also add any stuff you'd normally do in bash.
|
131
144
|
|
132
145
|
## Development
|
133
146
|
|
data/exe/dctl
CHANGED
@@ -21,7 +21,6 @@ module Dctl
|
|
21
21
|
class_option :host, type: :string
|
22
22
|
|
23
23
|
desc "build", "Build images. Pass image name to build a specific one; otherwise builds all"
|
24
|
-
option :pull, type: :boolean, desc: "Pull before building (same as docker build --pull)"
|
25
24
|
option :cache_from, type: :string
|
26
25
|
option :cache_from_self, type: :boolean, desc: "Uses the tag being built " \
|
27
26
|
"as the cache source. Useful for rebuilding images where the cache is " \
|
@@ -48,7 +47,6 @@ module Dctl
|
|
48
47
|
dockerfile = dctl.image_dockerfile(image)
|
49
48
|
|
50
49
|
build_opts = %W(-f=#{dockerfile} -t=#{tag})
|
51
|
-
build_opts << "--pull=true" if options[:pull]
|
52
50
|
build_opts << "--cache-from=#{tag}" if options[:cache_from_self]
|
53
51
|
build_opts << extra_args
|
54
52
|
if options[:cache_from]
|
@@ -61,7 +59,7 @@ module Dctl
|
|
61
59
|
build_opts << "--cache-from=#{options[:cache_from]}"
|
62
60
|
end
|
63
61
|
|
64
|
-
commands << "
|
62
|
+
commands << docker_command("build", *build_opts, ".")
|
65
63
|
end
|
66
64
|
|
67
65
|
stream_output commands.join(" && "), exec: true
|
@@ -75,7 +73,7 @@ module Dctl
|
|
75
73
|
|
76
74
|
images.each do |image|
|
77
75
|
tag = dctl.image_tag(image)
|
78
|
-
push_cmds << "
|
76
|
+
push_cmds << docker_command("push", tag)
|
79
77
|
end
|
80
78
|
|
81
79
|
push_cmd = push_cmds.join " && "
|
@@ -87,17 +85,17 @@ module Dctl
|
|
87
85
|
def pull(*images)
|
88
86
|
dctl = Dctl::Main.new env: dctl_env
|
89
87
|
images = dctl.expand_images *images
|
90
|
-
|
88
|
+
pull_commands = []
|
91
89
|
|
92
90
|
images.each do |image|
|
93
91
|
opts = {}
|
94
92
|
opts[:version] = options[:version] if options[:version]
|
95
93
|
tag = dctl.image_tag(image, opts)
|
96
|
-
|
94
|
+
pull_commands << docker_command("pull", tag)
|
97
95
|
end
|
98
96
|
|
99
|
-
|
100
|
-
stream_output
|
97
|
+
pull_command = pull_commands.join " && "
|
98
|
+
stream_output pull_command, exec: true
|
101
99
|
end
|
102
100
|
|
103
101
|
desc "up", "Start your dockerized app server"
|
@@ -108,13 +106,13 @@ module Dctl
|
|
108
106
|
FileUtils.rm pidfile if File.exist? pidfile
|
109
107
|
|
110
108
|
compose_opts = %w(--remove-orphans)
|
111
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} up #{compose_opts.join(" ")}", exec: true
|
109
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} up #{compose_opts.join(" ")}", exec: true
|
112
110
|
end
|
113
111
|
|
114
112
|
desc "down", "Stop one or many containers"
|
115
113
|
def down(*images)
|
116
114
|
dctl = Dctl::Main.new env: dctl_env
|
117
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} down #{images.join(" ")}", exec: true
|
115
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} down #{images.join(" ")}", exec: true
|
118
116
|
end
|
119
117
|
|
120
118
|
desc "rm", "Remove one or many containers"
|
@@ -122,44 +120,44 @@ module Dctl
|
|
122
120
|
def rm(*images)
|
123
121
|
dctl = Dctl::Main.new env: dctl_env
|
124
122
|
opts = " --force" if options[:force]
|
125
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} rm#{opts} #{images.join(" ")}", exec: true
|
123
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} rm#{opts} #{images.join(" ")}", exec: true
|
126
124
|
end
|
127
125
|
|
128
126
|
desc "start", "Start one or many containers"
|
129
127
|
def start(*images)
|
130
128
|
dctl = Dctl::Main.new env: dctl_env
|
131
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} start #{images.join(" ")}", exec: true
|
129
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} start #{images.join(" ")}", exec: true
|
132
130
|
end
|
133
131
|
|
134
132
|
desc "stop", "Stop one or many containers"
|
135
133
|
def stop(*images)
|
136
134
|
dctl = Dctl::Main.new env: dctl_env
|
137
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} stop #{images.join(" ")}", exec: true
|
135
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} stop #{images.join(" ")}", exec: true
|
138
136
|
end
|
139
137
|
|
140
138
|
desc "restart", "Restart one or many containers"
|
141
139
|
def restart(*images)
|
142
140
|
dctl = Dctl::Main.new env: dctl_env
|
143
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} restart #{images.join(" ")}", exec: true
|
141
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} restart #{images.join(" ")}", exec: true
|
144
142
|
end
|
145
143
|
|
146
144
|
desc "create", "Bring an image up without starting it"
|
147
145
|
def create(*images)
|
148
146
|
dctl = Dctl::Main.new env: dctl_env
|
149
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} up --no-start #{images.join(" ")}", exec: true
|
147
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} up --no-start #{images.join(" ")}", exec: true
|
150
148
|
end
|
151
149
|
|
152
150
|
desc "run [IMAGE] [COMMAND]", "Run a command on the given image"
|
153
151
|
def runcmd(image, *commands)
|
154
152
|
dctl = Dctl::Main.new env: dctl_env
|
155
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} run #{image} #{commands.join(" ")}", exec: true
|
153
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} run #{image} #{commands.join(" ")}", exec: true
|
156
154
|
end
|
157
155
|
|
158
156
|
desc "exec [IMAGE] [COMMAND]", "Execute a command on the given _running_ image"
|
159
157
|
map exec: :_exec # avoid overwriting Kernel#exec
|
160
158
|
def _exec(image, *commands)
|
161
159
|
dctl = Dctl::Main.new env: dctl_env
|
162
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} #{commands.join(" ")}", exec: true
|
160
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} #{commands.join(" ")}", exec: true
|
163
161
|
end
|
164
162
|
|
165
163
|
desc "recreate", "Stop, remove, build, create, and start a container"
|
@@ -176,13 +174,13 @@ module Dctl
|
|
176
174
|
desc "ps", "List running containers for this environment"
|
177
175
|
def ps
|
178
176
|
dctl = Dctl::Main.new env: dctl_env
|
179
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} ps", exec: true
|
177
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} ps", exec: true
|
180
178
|
end
|
181
179
|
|
182
|
-
desc "
|
183
|
-
def
|
180
|
+
desc "bump IMAGE", "Increase the version number for the given image"
|
181
|
+
def bump(image)
|
184
182
|
dctl = Dctl::Main.new env: dctl_env
|
185
|
-
dctl.
|
183
|
+
dctl.bump(image)
|
186
184
|
end
|
187
185
|
|
188
186
|
desc "initdb", "Setup initial postgres database"
|
@@ -190,9 +188,9 @@ module Dctl
|
|
190
188
|
dctl = Dctl::Main.new env: dctl_env
|
191
189
|
env = dctl_env
|
192
190
|
local_data_dir = File.expand_path "../tmp/psql-#{env}", __FILE__
|
193
|
-
`#{sudo}rm -r #{local_data_dir}` if File.exists? local_data_dir # todo prompt
|
191
|
+
`#{sudo} rm -r #{local_data_dir}` if File.exists? local_data_dir # todo prompt
|
194
192
|
|
195
|
-
cmd = "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm psql /bin/bash -c /etc/initdb.sh"
|
193
|
+
cmd = "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm psql /bin/bash -c /etc/initdb.sh"
|
196
194
|
|
197
195
|
stream_output cmd, exec: true
|
198
196
|
end
|
@@ -201,7 +199,7 @@ module Dctl
|
|
201
199
|
option :keep, type: :numeric, default: -1, desc: "How many old images to keep around, e.g. \"3\" will keep the current version plus the three next most recent. Use -1 to keep all."
|
202
200
|
def cleanup
|
203
201
|
to_remove = []
|
204
|
-
to_remove += `#{
|
202
|
+
to_remove += `#{docker_command("images", "--filter dangling=true", "-q")}`.split("\n")
|
205
203
|
|
206
204
|
if options[:keep] != -1
|
207
205
|
keep_last = options[:keep]
|
@@ -211,8 +209,14 @@ module Dctl
|
|
211
209
|
keep_after_tag = current_version - keep_last
|
212
210
|
|
213
211
|
next if keep_after_tag < 0
|
214
|
-
|
215
|
-
|
212
|
+
cmd = docker_command()
|
213
|
+
|
214
|
+
cmd = docker_command(
|
215
|
+
"images",
|
216
|
+
dctl.image_tag(image, version: nil),
|
217
|
+
"--filter before=#{dctl.image_tag(image, version: keep_after_tag)}",
|
218
|
+
"-q"
|
219
|
+
)
|
216
220
|
puts Rainbow(cmd).fg CMD_COLOR
|
217
221
|
stdout, stderr, status = Open3.capture3(cmd)
|
218
222
|
if status.success?
|
@@ -221,9 +225,13 @@ module Dctl
|
|
221
225
|
# Specified before filter did not exist on current machine. Loop
|
222
226
|
# through all old images to manually reconstruct.
|
223
227
|
Array(0..keep_after_tag).each do |version|
|
224
|
-
|
225
|
-
|
226
|
-
|
228
|
+
command = docker_command(
|
229
|
+
"images",
|
230
|
+
dctl.image_tag(image, version: version),
|
231
|
+
"-q"
|
232
|
+
)
|
233
|
+
puts Rainbow(command).fg CMD_COLOR
|
234
|
+
image_id = `#{command}`.strip
|
227
235
|
to_remove << image_id unless image_id.empty?
|
228
236
|
end
|
229
237
|
end
|
@@ -235,13 +243,13 @@ module Dctl
|
|
235
243
|
exit 0
|
236
244
|
end
|
237
245
|
|
238
|
-
stream_output "#{sudo}docker rmi -f #{to_remove.join(" ")}", exec: true
|
246
|
+
stream_output "#{sudo} docker rmi -f #{to_remove.join(" ")}", exec: true
|
239
247
|
end
|
240
248
|
|
241
249
|
desc "bash CONTAINER", "Create a new instance of the given image with a bash prompt"
|
242
250
|
def bash(container = "app")
|
243
251
|
dctl = Dctl::Main.new env: dctl_env
|
244
|
-
cmd = "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm #{container} /bin/bash"
|
252
|
+
cmd = "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} run --rm #{container} /bin/bash"
|
245
253
|
|
246
254
|
stream_output cmd, exec: true
|
247
255
|
end
|
@@ -249,7 +257,7 @@ module Dctl
|
|
249
257
|
desc "connect CONTAINER", "Connect to a running container."
|
250
258
|
def connect(image = "app")
|
251
259
|
dctl = Dctl::Main.new env: dctl_env
|
252
|
-
stream_output "#{sudo}docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} /bin/bash", exec: true
|
260
|
+
stream_output "#{sudo} docker-compose #{docker_opts} -f #{dctl.compose_file_path} exec #{image} /bin/bash", exec: true
|
253
261
|
end
|
254
262
|
|
255
263
|
desc "attach CONTAINER", "Connect to a running container."
|
@@ -258,7 +266,7 @@ module Dctl
|
|
258
266
|
dctl = Dctl::Main.new env: dctl_env
|
259
267
|
tag = dctl.image_tag(image)
|
260
268
|
|
261
|
-
cmd = "#{sudo}docker #{docker_opts} ps --filter ancestor=#{image} -aq | head -n1"
|
269
|
+
cmd = "#{sudo} docker #{docker_opts} ps --filter ancestor=#{image} -aq | head -n1"
|
262
270
|
puts cmd
|
263
271
|
container = `#{cmd}`.chomp
|
264
272
|
|
@@ -267,7 +275,7 @@ module Dctl
|
|
267
275
|
exit 1
|
268
276
|
end
|
269
277
|
|
270
|
-
stream_output "#{sudo}docker attach #{container}", exec: true
|
278
|
+
stream_output "#{sudo} docker attach #{container}", exec: true
|
271
279
|
end
|
272
280
|
|
273
281
|
desc "version", "Print version"
|
@@ -298,7 +306,7 @@ module Dctl
|
|
298
306
|
|
299
307
|
def sudo
|
300
308
|
return "" if !ENV["DCTL_NOSUDO"].nil?
|
301
|
-
`uname`.chomp == "Darwin" ? "" : "sudo
|
309
|
+
`uname`.chomp == "Darwin" ? "" : "sudo" # use sudo on linux hosts
|
302
310
|
end
|
303
311
|
|
304
312
|
# Support both --env and DCTL_ENV, but prefer --env if both are present
|
@@ -306,6 +314,14 @@ module Dctl
|
|
306
314
|
options[:env] || ENV["DCTL_ENV"] || "dev"
|
307
315
|
end
|
308
316
|
|
317
|
+
def docker_command(*args)
|
318
|
+
build_command(sudo, "docker", docker_opts, *args)
|
319
|
+
end
|
320
|
+
|
321
|
+
def build_command(*args)
|
322
|
+
args.reject(&:nil?).reject(&:empty?).join(" ")
|
323
|
+
end
|
324
|
+
|
309
325
|
# Allow passsing additional docker args without us having to implement
|
310
326
|
# each one manually, e.g. `dctl build app -- --pull`
|
311
327
|
def extract_extra_args(images)
|
@@ -326,10 +342,12 @@ module Dctl
|
|
326
342
|
host ||= !ENV["DOCKER_HOST"].nil? ? ENV["DOCKER_HOST"] : nil
|
327
343
|
opts << "--host #{host}" if host
|
328
344
|
|
329
|
-
opts.join
|
345
|
+
opts.join(" ")
|
330
346
|
end
|
331
347
|
end
|
332
348
|
end
|
333
349
|
end
|
334
350
|
|
351
|
+
dctl = Dctl::Main.new
|
352
|
+
dctl.define_custom_commands(Dctl::Cli)
|
335
353
|
Dctl::Cli.start ARGV
|
data/lib/dctl/main.rb
CHANGED
@@ -2,9 +2,9 @@ module Dctl
|
|
2
2
|
class Main
|
3
3
|
attr_reader :env, :settings
|
4
4
|
|
5
|
-
def initialize(env: "dev")
|
5
|
+
def initialize(env: "dev", config: nil)
|
6
6
|
@env = env
|
7
|
-
load_config!
|
7
|
+
load_config!(config)
|
8
8
|
end
|
9
9
|
|
10
10
|
##
|
@@ -51,7 +51,7 @@ module Dctl
|
|
51
51
|
images
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def bump(image)
|
55
55
|
check_image(image)
|
56
56
|
|
57
57
|
parsed = parsed_compose_file
|
@@ -149,6 +149,18 @@ module Dctl
|
|
149
149
|
@parsed_compose_file ||= YAML.load_file compose_file_path
|
150
150
|
end
|
151
151
|
|
152
|
+
##
|
153
|
+
# If there are user defined commands in .dctl.yml, dynamically add them to
|
154
|
+
# the passed thor CLI so they may be executed.
|
155
|
+
def define_custom_commands(klass)
|
156
|
+
Array(settings.custom_commands).each do |command, args|
|
157
|
+
klass.send(:desc, command, "[Custom Command] #{command}")
|
158
|
+
klass.send(:define_method, command, -> do
|
159
|
+
Array(args).each { |a| stream_output(a) }
|
160
|
+
end)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
152
164
|
##
|
153
165
|
# Ensure the current project's .dctl.yml contains all the requisite keys.
|
154
166
|
def check_settings!
|
@@ -171,8 +183,8 @@ module Dctl
|
|
171
183
|
##
|
172
184
|
# Load the current project's config file, complaining if it does not exist
|
173
185
|
# or is malformed.
|
174
|
-
def load_config!
|
175
|
-
Config.load_and_set_settings(config_path)
|
186
|
+
def load_config!(custom_config_path = nil)
|
187
|
+
Config.load_and_set_settings(custom_config_path || config_path)
|
176
188
|
check_settings!
|
177
189
|
|
178
190
|
@settings = Settings
|
data/lib/dctl/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dctl_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.13.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Toniazzo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|