dip 7.3.1 → 7.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 60d7a15f7de7909f0e61a3e3f9ca8112cf2a94cf21bccfb813be9a209f83e2db
4
- data.tar.gz: d9dd72eff516119adb097147dd566ae1688fed731153617e81d16ed8eb9c54a1
3
+ metadata.gz: be7ef96533ac533734f04b61b49864b8db104269813c5dd00d8192d968c0c1dd
4
+ data.tar.gz: 74d31efceda6300bd5f93023f5a108c3a9972d2b4416d0e4433e98f7ec76f61e
5
5
  SHA512:
6
- metadata.gz: 5e7d3fb075dea8f3be052cbcc8bde8083fd9c967dbce8ab852aefc5ba21bc885f787794dbaf81b68bf5a5e282d7272b6a4495ab567df305e70845e1b5dd14d00
7
- data.tar.gz: 07e3051d76cd9a7af8a51422024c6865feb2b2c7cf59f1865a1d162a133d513565c9a4214cfa8441291694ba85a9e8562bb98a95cd392839d5d69a7a90f70982
6
+ metadata.gz: aafe6a31332d687c065c29e34d3c8fdc69bdc6c0507aa4a4c1d3fc1c68d5ded516c4f52e2b7092b34cf585a3ceb9f69ad4a6b764a41863ea090323d5b0a5b2c2
7
+ data.tar.gz: 6d801682b927567b84f07a0f7df75535d35ac1f11a953f286cc9785a8d415d55d5940b72a68365d2cafaa13e02b9aafa01f6f58282a41e2c37546274553fbf74
data/README.md CHANGED
@@ -30,14 +30,15 @@ Dip can be injected into the current shell (ZSH or Bash).
30
30
  eval "$(dip console)"
31
31
  ```
32
32
 
33
+ **IMPORTANT**: Beware of possible collisions with local tools. One particular example is supporting both local and Docker frontend build tools, such as Yarn. If you want some developer to run `yarn` locally and other to use Docker for that, you should either avoid adding the `yarn` command to the `dip.yml` or avoid using the shell integration for hybrid development.
34
+
33
35
  After that we can type commands without `dip` prefix. For example:
34
36
 
35
37
  ```sh
36
38
  <run-command> *any-args
37
39
  compose *any-compose-arg
38
40
  up <service>
39
- build
40
- down
41
+ ktl *any-kubectl-arg
41
42
  provision
42
43
  ```
43
44
 
@@ -79,10 +80,11 @@ Also, you can check out examples at the top.
79
80
 
80
81
  ```yml
81
82
  # Required minimum dip version
82
- version: '7.1'
83
+ version: '7.5'
83
84
 
84
85
  environment:
85
86
  COMPOSE_EXT: development
87
+ STAGE: "staging"
86
88
 
87
89
  compose:
88
90
  files:
@@ -91,6 +93,9 @@ compose:
91
93
  - docker/docker-compose.$DIP_OS.yml
92
94
  project_name: bear
93
95
 
96
+ kubectl:
97
+ namespace: rocket-$STAGE
98
+
94
99
  interaction:
95
100
  shell:
96
101
  description: Open the Bash shell in app's container
@@ -140,6 +145,22 @@ interaction:
140
145
  default_args: db_dev
141
146
  command: psql -h pg -U postgres
142
147
 
148
+ k:
149
+ description: Run commands in Kubernetes cluster
150
+ pod: svc/rocket-app:app-container
151
+ entrypoint: /env-entrypoint
152
+ subcommands:
153
+ bash:
154
+ description: Get a shell to the running container
155
+ command: /bin/bash
156
+ rails:
157
+ description: Run Rails commands
158
+ command: bundle exec rails
159
+ kafka-topics:
160
+ description: Manage Kafka topics
161
+ pod: svc/rocket-kafka
162
+ command: kafka-topics.sh --zookeeper zookeeper:2181
163
+
143
164
  setup_key:
144
165
  description: Copy key
145
166
  service: app
@@ -199,7 +220,13 @@ returned is `/app/sub-project-dir`.
199
220
 
200
221
  Run commands defined within the `interaction` section of dip.yml
201
222
 
202
- By default, a command will be executed using [`docker compose`](https://docs.docker.com/compose/install/) command. If you are still using `docker-compose` binary (i.e., prior to Compose V2 changes), a command would be run through it. You can disable using of Compose V2 by passing an environment variable `DIP_COMPOSE_V2=false dip run`.
223
+ A command will be executed by specified runner. Dip has three types of them:
224
+
225
+ - `docker-compose` runner — used when the `service` option is defined.
226
+ - `kubectl` runner — used when the `pod` option is defined.
227
+ - `local` runner — used when the previous ones are not defined.
228
+
229
+ If you are still using `docker-compose` binary (i.e., prior to Compose V2 changes), a command would be run through it. You can disable using of Compose V2 by passing an environment variable `DIP_COMPOSE_V2=false dip run`.
203
230
 
204
231
  ```sh
205
232
  dip run rails c
@@ -252,7 +279,7 @@ Run commands each by each from `provision` section of dip.yml
252
279
 
253
280
  ### dip compose
254
281
 
255
- Run docker-compose commands that are configured according to the application's dip.yml :
282
+ Run docker-compose commands that are configured according to the application's dip.yml:
256
283
 
257
284
  ```sh
258
285
  dip compose COMMAND [OPTIONS]
@@ -260,6 +287,16 @@ dip compose COMMAND [OPTIONS]
260
287
  dip compose up -d redis
261
288
  ```
262
289
 
290
+ ### dip ktl
291
+
292
+ Run kubectl commands that are configured according to the application's dip.yml:
293
+
294
+ ```sh
295
+ dip ktl COMMAND [OPTIONS]
296
+
297
+ STAGE=some dip ktl get pods
298
+ ```
299
+
263
300
  ### dip ssh
264
301
 
265
302
  Runs ssh-agent container based on https://github.com/whilp/ssh-agent with your ~/.ssh/id_rsa.
data/lib/dip/cli.rb CHANGED
@@ -32,7 +32,7 @@ module Dip
32
32
  end
33
33
  end
34
34
 
35
- stop_on_unknown_option! :run
35
+ stop_on_unknown_option! :run, :ktl
36
36
 
37
37
  desc "version", "dip version"
38
38
  def version
@@ -69,11 +69,26 @@ module Dip
69
69
  end
70
70
 
71
71
  desc "down [OPTIONS]", "Run `docker-compose down` command"
72
+ method_option :help, aliases: "-h", type: :boolean, desc: "Display usage information"
73
+ method_option :all, aliases: "-A", type: :boolean, desc: "Shutdown all running docker-compose projects"
72
74
  def down(*argv)
73
- compose("down", *argv)
75
+ if options[:help]
76
+ invoke :help, ["down"]
77
+ elsif options[:all]
78
+ require_relative "commands/down_all"
79
+ Dip::Commands::DownAll.new.execute
80
+ else
81
+ compose("down", *argv)
82
+ end
74
83
  end
75
84
 
76
- desc "run [OPTIONS] CMD [ARGS]", "Run configured command in a docker-compose service. `run` prefix may be omitted"
85
+ desc "ktl CMD [OPTIONS]", "Run kubectl commands"
86
+ def ktl(*argv)
87
+ require_relative "commands/kubectl"
88
+ Dip::Commands::Kubectl.new(*argv).execute
89
+ end
90
+
91
+ desc "run [OPTIONS] CMD [ARGS]", "Run configured command (`run` prefix may be omitted)"
77
92
  method_option :publish, aliases: "-p", type: :string, repeatable: true,
78
93
  desc: "Publish a container's port(s) to the host"
79
94
  method_option :help, aliases: "-h", type: :boolean, desc: "Display usage information"
@@ -82,7 +97,11 @@ module Dip
82
97
  invoke :help, ["run"]
83
98
  else
84
99
  require_relative "commands/run"
85
- Dip::Commands::Run.new(*argv, publish: options[:publish]).execute
100
+
101
+ Dip::Commands::Run.new(
102
+ *argv,
103
+ **options.to_h.transform_keys!(&:to_sym)
104
+ ).execute
86
105
  end
87
106
  end
88
107
 
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+
5
+ module Dip
6
+ module Commands
7
+ class DownAll < Dip::Command
8
+ def execute
9
+ exec_subprocess(
10
+ "docker rm --volumes $(docker stop $(docker ps --filter 'label=com.docker.compose.project' -q))"
11
+ )
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../command"
4
+
5
+ module Dip
6
+ module Commands
7
+ class Kubectl < Dip::Command
8
+ attr_reader :argv, :config
9
+
10
+ def initialize(*argv)
11
+ @argv = argv
12
+ @config = ::Dip.config.kubectl || {}
13
+ end
14
+
15
+ def execute
16
+ k_argv = cli_options + argv
17
+
18
+ exec_program("kubectl", k_argv)
19
+ end
20
+
21
+ private
22
+
23
+ def cli_options
24
+ %i[namespace].flat_map do |name|
25
+ next unless (value = config[name])
26
+ next unless value.is_a?(String)
27
+
28
+ value = ::Dip.env.interpolate(value).delete_suffix("-")
29
+ ["--#{name.to_s.tr("_", "-")}", value]
30
+ end.compact
31
+ end
32
+ end
33
+ end
34
+ end
@@ -4,13 +4,17 @@ require "shellwords"
4
4
  require_relative "../../../lib/dip/run_vars"
5
5
  require_relative "../command"
6
6
  require_relative "../interaction_tree"
7
- require_relative "compose"
7
+ require_relative "runners/local_runner"
8
+ require_relative "runners/docker_compose_runner"
9
+ require_relative "runners/kubectl_runner"
10
+
11
+ require_relative "kubectl"
8
12
 
9
13
  module Dip
10
14
  module Commands
11
15
  class Run < Dip::Command
12
- def initialize(cmd, *argv, publish: nil)
13
- @publish = publish
16
+ def initialize(cmd, *argv, **options)
17
+ @options = options
14
18
 
15
19
  @command, @argv = InteractionTree
16
20
  .new(Dip.config.interaction)
@@ -22,75 +26,25 @@ module Dip
22
26
  end
23
27
 
24
28
  def execute
25
- if command[:service].nil?
26
- exec_program(command[:command], get_args, shell: command[:shell])
27
- else
28
- Dip::Commands::Compose.new(
29
- command[:compose][:method],
30
- *compose_arguments,
31
- shell: command[:shell]
32
- ).execute
33
- end
29
+ lookup_runner
30
+ .new(command, argv, **options)
31
+ .execute
34
32
  end
35
33
 
36
34
  private
37
35
 
38
- attr_reader :command, :argv, :publish
39
-
40
- def compose_arguments
41
- compose_argv = command[:compose][:run_options].dup
42
-
43
- if command[:compose][:method] == "run"
44
- compose_argv.concat(run_vars)
45
- compose_argv.concat(published_ports)
46
- compose_argv << "--rm"
47
- end
48
-
49
- compose_argv << command.fetch(:service)
50
-
51
- unless (cmd = command[:command]).empty?
52
- if command[:shell]
53
- compose_argv << cmd
54
- else
55
- compose_argv.concat(cmd.shellsplit)
56
- end
57
- end
58
-
59
- compose_argv.concat(get_args)
60
-
61
- compose_argv
62
- end
63
-
64
- def run_vars
65
- run_vars = Dip::RunVars.env
66
- return [] unless run_vars
67
-
68
- run_vars.map { |k, v| ["-e", "#{k}=#{Shellwords.escape(v)}"] }.flatten
69
- end
70
-
71
- def published_ports
72
- if publish.respond_to?(:each)
73
- publish.map { |p| "--publish=#{p}" }
74
- else
75
- []
76
- end
77
- end
36
+ attr_reader :command, :argv, :options
78
37
 
79
- def get_args
80
- if argv.any?
81
- if command[:shell]
82
- [argv.shelljoin]
83
- else
84
- Array(argv)
85
- end
86
- elsif !(default_args = command[:default_args]).empty?
87
- if command[:shell]
88
- default_args.shellsplit
89
- else
90
- Array(default_args)
91
- end
38
+ def lookup_runner
39
+ if (runner = command[:runner])
40
+ camelized_runner = runner.split("_").collect(&:capitalize).join
41
+ Runners.const_get("#{camelized_runner}Runner")
42
+ elsif command[:service]
43
+ Runners::DockerComposeRunner
44
+ elsif command[:pod]
45
+ Runners::KubectlRunner
92
46
  else
93
- []
47
+ Runners::LocalRunner
94
48
  end
95
49
  end
96
50
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dip
4
+ module Commands
5
+ module Runners
6
+ class Base
7
+ def initialize(command, argv, **options)
8
+ @command = command
9
+ @argv = argv
10
+ @options = options
11
+ end
12
+
13
+ def execute
14
+ raise NotImplementedError
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :command, :argv, :options
20
+
21
+ def command_args
22
+ if argv.any?
23
+ if command[:shell]
24
+ [argv.shelljoin]
25
+ else
26
+ Array(argv)
27
+ end
28
+ elsif !(default_args = command[:default_args]).empty?
29
+ if command[:shell]
30
+ default_args.shellsplit
31
+ else
32
+ Array(default_args)
33
+ end
34
+ else
35
+ []
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "../compose"
5
+
6
+ module Dip
7
+ module Commands
8
+ module Runners
9
+ class DockerComposeRunner < Base
10
+ def execute
11
+ Commands::Compose.new(
12
+ command[:compose][:method],
13
+ *compose_arguments,
14
+ shell: command[:shell]
15
+ ).execute
16
+ end
17
+
18
+ private
19
+
20
+ def compose_arguments
21
+ compose_argv = command[:compose][:run_options].dup
22
+
23
+ if command[:compose][:method] == "run"
24
+ compose_argv.concat(run_vars)
25
+ compose_argv.concat(published_ports)
26
+ compose_argv << "--rm"
27
+ end
28
+
29
+ compose_argv << command.fetch(:service)
30
+
31
+ unless (cmd = command[:command]).empty?
32
+ if command[:shell]
33
+ compose_argv << cmd
34
+ else
35
+ compose_argv.concat(cmd.shellsplit)
36
+ end
37
+ end
38
+
39
+ compose_argv.concat(command_args)
40
+
41
+ compose_argv
42
+ end
43
+
44
+ def run_vars
45
+ run_vars = Dip::RunVars.env
46
+ return [] unless run_vars
47
+
48
+ run_vars.map { |k, v| ["-e", "#{k}=#{Shellwords.escape(v)}"] }.flatten
49
+ end
50
+
51
+ def published_ports
52
+ publish = options[:publish]
53
+
54
+ if publish.respond_to?(:each)
55
+ publish.map { |p| "--publish=#{p}" }
56
+ else
57
+ []
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "../kubectl"
5
+
6
+ module Dip
7
+ module Commands
8
+ module Runners
9
+ class KubectlRunner < Base
10
+ def execute
11
+ Commands::Kubectl.new(*kubectl_arguments).execute
12
+ end
13
+
14
+ private
15
+
16
+ def kubectl_arguments
17
+ argv = ["exec", "--tty", "--stdin"]
18
+
19
+ pod, container = command.fetch(:pod).split(":")
20
+ argv.push("--container", container) unless container.nil?
21
+ argv.push(pod, "--")
22
+
23
+ unless (entrypoint = command[:entrypoint]).nil?
24
+ argv << entrypoint
25
+ end
26
+ argv << command.fetch(:command)
27
+ argv.concat(command_args)
28
+
29
+ argv
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+ require_relative "../../command"
5
+
6
+ module Dip
7
+ module Commands
8
+ module Runners
9
+ class LocalRunner < Base
10
+ def execute
11
+ Dip::Command.exec_program(
12
+ command[:command],
13
+ command_args,
14
+ shell: command[:shell]
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/dip/config.rb CHANGED
@@ -16,6 +16,7 @@ module Dip
16
16
  CONFIG_DEFAULTS = {
17
17
  environment: {},
18
18
  compose: {},
19
+ kubectl: {},
19
20
  interation: {},
20
21
  provision: []
21
22
  }.freeze
@@ -94,7 +95,7 @@ module Dip
94
95
  config
95
96
  end
96
97
 
97
- %i[environment compose interaction provision].each do |key|
98
+ %i[environment compose kubectl interaction provision].each do |key|
98
99
  define_method(key) do
99
100
  config[key] || (raise config_missing_error(key))
100
101
  end
@@ -58,7 +58,10 @@ module Dip
58
58
  def build_command(entry)
59
59
  {
60
60
  description: entry[:description],
61
+ runner: entry[:runner],
61
62
  service: entry[:service],
63
+ pod: entry[:pod],
64
+ entrypoint: entry[:entrypoint],
62
65
  command: entry[:command].to_s.strip,
63
66
  shell: entry.fetch(:shell, true),
64
67
  default_args: entry[:default_args].to_s.strip,
data/lib/dip/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dip
4
- VERSION = "7.3.1"
4
+ VERSION = "7.5.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dip
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.1
4
+ version: 7.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - bibendi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-07 00:00:00.000000000 Z
11
+ date: 2022-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -179,10 +179,16 @@ files:
179
179
  - lib/dip/commands/compose.rb
180
180
  - lib/dip/commands/console.rb
181
181
  - lib/dip/commands/dns.rb
182
+ - lib/dip/commands/down_all.rb
183
+ - lib/dip/commands/kubectl.rb
182
184
  - lib/dip/commands/list.rb
183
185
  - lib/dip/commands/nginx.rb
184
186
  - lib/dip/commands/provision.rb
185
187
  - lib/dip/commands/run.rb
188
+ - lib/dip/commands/runners/base.rb
189
+ - lib/dip/commands/runners/docker_compose_runner.rb
190
+ - lib/dip/commands/runners/kubectl_runner.rb
191
+ - lib/dip/commands/runners/local_runner.rb
186
192
  - lib/dip/commands/ssh.rb
187
193
  - lib/dip/config.rb
188
194
  - lib/dip/environment.rb