dctl_rb 0.12.0 → 0.13.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 +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
|