cpl 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/docs/commands.md +39 -19
- data/lib/command/{setup.rb → apply_template.rb} +89 -15
- data/lib/command/base.rb +13 -2
- data/lib/command/run.rb +33 -12
- data/lib/command/run_detached.rb +17 -12
- data/lib/command/setup_app.rb +29 -0
- data/lib/core/controlplane.rb +6 -0
- data/lib/cpl/version.rb +1 -1
- data/lib/cpl.rb +6 -1
- data/lib/deprecated_commands.json +2 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfd7383099c36f633d327424fcb36561e2b925120e63f1b814158a43bd55103f
|
4
|
+
data.tar.gz: eafdf0607fe28d3c24f8132e3a116085020c94639d5b05a5accec4d4de651ca5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b443d26a3fa91400dbb6d2e71b730a26bd1405df2f03e7f9446179323e2becb532ec69d81d93f22578fe8793dbabec9a2283efc16a107decdb5aaa9e4a615281
|
7
|
+
data.tar.gz: 34ab7670bc372af9b8991678de9d99a9c60429b3caebeeeb2775046a9be3d4a7fb7335d9cbeb3a6c2ba06bb29ef40ab7c2cffbcd20737cfb62eb4048b07a8926
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cpl (0.
|
4
|
+
cpl (0.6.0)
|
5
5
|
debug (~> 1.7.1)
|
6
6
|
dotenv (~> 2.8.1)
|
7
7
|
psych (~> 5.1.0)
|
@@ -20,7 +20,7 @@ GEM
|
|
20
20
|
dotenv (2.8.1)
|
21
21
|
iniparse (1.5.0)
|
22
22
|
io-console (0.6.0)
|
23
|
-
irb (1.6.
|
23
|
+
irb (1.6.4)
|
24
24
|
reline (>= 0.3.0)
|
25
25
|
json (2.6.3)
|
26
26
|
overcommit (0.60.0)
|
@@ -77,7 +77,7 @@ GEM
|
|
77
77
|
simplecov_json_formatter (~> 0.1)
|
78
78
|
simplecov-html (0.12.3)
|
79
79
|
simplecov_json_formatter (0.1.4)
|
80
|
-
stringio (3.0.
|
80
|
+
stringio (3.0.6)
|
81
81
|
thor (1.2.1)
|
82
82
|
unicode-display_width (2.4.2)
|
83
83
|
|
data/docs/commands.md
CHANGED
@@ -11,6 +11,30 @@ This `-a` option is used in most of the commands and will pick all other app con
|
|
11
11
|
|
12
12
|
### Commands
|
13
13
|
|
14
|
+
### `apply-template`
|
15
|
+
|
16
|
+
- Applies application-specific configs from templates (e.g., for every review-app)
|
17
|
+
- Publishes (creates or updates) those at Control Plane infrastructure
|
18
|
+
- Picks templates from the `.controlplane/templates` directory
|
19
|
+
- Templates are ordinary Control Plane templates but with variable preprocessing
|
20
|
+
|
21
|
+
**Preprocessed template variables:**
|
22
|
+
|
23
|
+
```
|
24
|
+
APP_GVC - basically GVC or app name
|
25
|
+
APP_LOCATION - default location
|
26
|
+
APP_ORG - organization
|
27
|
+
APP_IMAGE - will use latest app image
|
28
|
+
```
|
29
|
+
|
30
|
+
```sh
|
31
|
+
# Applies single template.
|
32
|
+
cpl apply-template redis -a $APP_NAME
|
33
|
+
|
34
|
+
# Applies several templates (practically creating full app).
|
35
|
+
cpl apply-template gvc postgres redis rails -a $APP_NAME
|
36
|
+
```
|
37
|
+
|
14
38
|
### `build-image`
|
15
39
|
|
16
40
|
- Builds and pushes the image to Control Plane
|
@@ -238,6 +262,13 @@ cpl run rails c -a $APP_NAME
|
|
238
262
|
# Uses a different image (which may not be promoted yet).
|
239
263
|
cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
|
240
264
|
cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
|
265
|
+
|
266
|
+
# Uses a different workload
|
267
|
+
cpl run bash -a $APP_NAME -w other-workload
|
268
|
+
|
269
|
+
# Overrides remote CPLN_TOKEN env variable with local token.
|
270
|
+
# Useful when need superuser rights in remote container
|
271
|
+
cpl run bash -a $APP_NAME --use-local-token
|
241
272
|
```
|
242
273
|
|
243
274
|
### `run:detached`
|
@@ -263,30 +294,19 @@ cpl run:detached rails db:migrate -a $APP_NAME --image latest
|
|
263
294
|
# Uses a different image (which may not be promoted yet).
|
264
295
|
cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
|
265
296
|
cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
|
266
|
-
```
|
267
|
-
|
268
|
-
### `setup`
|
269
297
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
- Templates are ordinary Control Plane templates but with variable preprocessing
|
298
|
+
# Uses a different workload
|
299
|
+
cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
|
300
|
+
```
|
274
301
|
|
275
|
-
|
302
|
+
### `setup-app`
|
276
303
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
APP_ORG - organization
|
281
|
-
APP_IMAGE - will use latest app image
|
282
|
-
```
|
304
|
+
- Creates an app and all its workloads
|
305
|
+
- Specify the templates for the app and workloads through `setup` in the `.controlplane/controlplane.yml` file
|
306
|
+
- This should should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
|
283
307
|
|
284
308
|
```sh
|
285
|
-
|
286
|
-
cpl setup redis -a $APP_NAME
|
287
|
-
|
288
|
-
# Applies several templates (practically creating full app).
|
289
|
-
cpl setup gvc postgres redis rails -a $APP_NAME
|
309
|
+
cpl setup-app -a $APP_NAME
|
290
310
|
```
|
291
311
|
|
292
312
|
### `version`
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Command
|
4
|
-
class
|
5
|
-
NAME = "
|
6
|
-
USAGE = "
|
4
|
+
class ApplyTemplate < Base # rubocop:disable Metrics/ClassLength
|
5
|
+
NAME = "apply-template"
|
6
|
+
USAGE = "apply-template TEMPLATE [TEMPLATE] ... [TEMPLATE]"
|
7
7
|
REQUIRES_ARGS = true
|
8
8
|
OPTIONS = [
|
9
|
-
app_option(required: true)
|
9
|
+
app_option(required: true),
|
10
|
+
skip_confirm_option
|
10
11
|
].freeze
|
11
12
|
DESCRIPTION = "Applies application-specific configs from templates"
|
12
13
|
LONG_DESCRIPTION = <<~DESC
|
@@ -27,28 +28,35 @@ module Command
|
|
27
28
|
EXAMPLES = <<~EX
|
28
29
|
```sh
|
29
30
|
# Applies single template.
|
30
|
-
cpl
|
31
|
+
cpl apply-template redis -a $APP_NAME
|
31
32
|
|
32
33
|
# Applies several templates (practically creating full app).
|
33
|
-
cpl
|
34
|
+
cpl apply-template gvc postgres redis rails -a $APP_NAME
|
34
35
|
```
|
35
36
|
EX
|
36
37
|
|
37
38
|
def call # rubocop:disable Metrics/MethodLength
|
39
|
+
ensure_templates!
|
40
|
+
|
38
41
|
@app_status = :existing
|
39
42
|
@created_workloads = []
|
40
43
|
@failed_workloads = []
|
44
|
+
@skipped_workloads = []
|
41
45
|
|
42
|
-
|
43
|
-
filename = "#{config.app_cpln_dir}/templates/#{template}.yml"
|
46
|
+
@asked_for_confirmation = false
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
pending_templates = templates.select do |template|
|
49
|
+
if template == "gvc"
|
50
|
+
confirm_app(template)
|
51
|
+
else
|
52
|
+
confirm_workload(template)
|
53
|
+
end
|
54
|
+
end
|
48
55
|
|
49
|
-
|
50
|
-
end
|
56
|
+
progress.puts if @asked_for_confirmation
|
51
57
|
|
58
|
+
pending_templates.each do |template, filename|
|
59
|
+
step("Applying template '#{template}'", abort_on_error: false) do
|
52
60
|
apply_template(filename)
|
53
61
|
if $CHILD_STATUS.success?
|
54
62
|
report_success(template)
|
@@ -63,10 +71,58 @@ module Command
|
|
63
71
|
print_app_status
|
64
72
|
print_created_workloads
|
65
73
|
print_failed_workloads
|
74
|
+
print_skipped_workloads
|
66
75
|
end
|
67
76
|
|
68
77
|
private
|
69
78
|
|
79
|
+
def templates
|
80
|
+
@templates ||= config.args.to_h do |template|
|
81
|
+
[template, "#{config.app_cpln_dir}/templates/#{template}.yml"]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def ensure_templates!
|
86
|
+
missing_templates = templates.filter { |_template, filename| !File.exist?(filename) }.to_h
|
87
|
+
return if missing_templates.empty?
|
88
|
+
|
89
|
+
missing_templates_str = missing_templates.map do |template, filename|
|
90
|
+
" - #{template} (#{filename})"
|
91
|
+
end.join("\n")
|
92
|
+
progress.puts("#{Shell.color('Missing templates:', :red)}\n#{missing_templates_str}\n\n")
|
93
|
+
|
94
|
+
raise "Can't find templates above, please create them."
|
95
|
+
end
|
96
|
+
|
97
|
+
def confirm_apply(message)
|
98
|
+
return true if config.options[:yes]
|
99
|
+
|
100
|
+
@asked_for_confirmation = true
|
101
|
+
Shell.confirm(message)
|
102
|
+
end
|
103
|
+
|
104
|
+
def confirm_app(template)
|
105
|
+
app = cp.fetch_gvc
|
106
|
+
return true unless app
|
107
|
+
|
108
|
+
confirmed = confirm_apply("App '#{config.app}' already exists, do you want to re-create it?")
|
109
|
+
return true if confirmed
|
110
|
+
|
111
|
+
report_skipped(template)
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
def confirm_workload(template)
|
116
|
+
workload = cp.fetch_workload(template)
|
117
|
+
return true unless workload
|
118
|
+
|
119
|
+
confirmed = confirm_apply("Workload '#{template}' already exists, do you want to re-create it?")
|
120
|
+
return true if confirmed
|
121
|
+
|
122
|
+
report_skipped(template)
|
123
|
+
false
|
124
|
+
end
|
125
|
+
|
70
126
|
def apply_template(filename)
|
71
127
|
data = File.read(filename)
|
72
128
|
.gsub("APP_GVC", config.app)
|
@@ -93,13 +149,24 @@ module Command
|
|
93
149
|
end
|
94
150
|
end
|
95
151
|
|
152
|
+
def report_skipped(template)
|
153
|
+
if template == "gvc"
|
154
|
+
@app_status = :skipped
|
155
|
+
else
|
156
|
+
@skipped_workloads.push(template)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
96
160
|
def print_app_status
|
97
161
|
return if @app_status == :existing
|
98
162
|
|
99
|
-
|
163
|
+
case @app_status
|
164
|
+
when :success
|
100
165
|
progress.puts("\n#{Shell.color("Created app '#{config.app}'.", :green)}")
|
101
|
-
|
166
|
+
when :failure
|
102
167
|
progress.puts("\n#{Shell.color("Failed to create app '#{config.app}'.", :red)}")
|
168
|
+
when :skipped
|
169
|
+
progress.puts("\n#{Shell.color("Skipped app '#{config.app}' (already exists).", :blue)}")
|
103
170
|
end
|
104
171
|
end
|
105
172
|
|
@@ -116,5 +183,12 @@ module Command
|
|
116
183
|
workloads = @failed_workloads.map { |template| " - #{template}" }.join("\n")
|
117
184
|
progress.puts("\n#{Shell.color('Failed to create workloads:', :red)}\n#{workloads}")
|
118
185
|
end
|
186
|
+
|
187
|
+
def print_skipped_workloads
|
188
|
+
return unless @skipped_workloads.any?
|
189
|
+
|
190
|
+
workloads = @skipped_workloads.map { |template| " - #{template}" }.join("\n")
|
191
|
+
progress.puts("\n#{Shell.color('Skipped workloads (already exist):', :blue)}\n#{workloads}")
|
192
|
+
end
|
119
193
|
end
|
120
194
|
end
|
data/lib/command/base.rb
CHANGED
@@ -142,13 +142,24 @@ module Command
|
|
142
142
|
}
|
143
143
|
end
|
144
144
|
|
145
|
+
def self.use_local_token_option(required: false)
|
146
|
+
{
|
147
|
+
name: :use_local_token,
|
148
|
+
params: {
|
149
|
+
desc: "Override remote CPLN_TOKEN with local token",
|
150
|
+
type: :boolean,
|
151
|
+
required: required
|
152
|
+
}
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
145
156
|
def self.all_options
|
146
157
|
methods.grep(/_option$/).map { |method| send(method.to_s) }
|
147
158
|
end
|
148
159
|
|
149
160
|
def self.all_options_by_key_name
|
150
161
|
all_options.each_with_object({}) do |option, result|
|
151
|
-
option[:params][:aliases]
|
162
|
+
option[:params][:aliases]&.each { |current_alias| result[current_alias.to_s] = option }
|
152
163
|
result["--#{option[:name]}"] = option
|
153
164
|
end
|
154
165
|
end
|
@@ -168,7 +179,7 @@ module Command
|
|
168
179
|
|
169
180
|
def wait_for_replica(workload, location)
|
170
181
|
wait_for("replica") do
|
171
|
-
cp.
|
182
|
+
cp.workload_get_replicas_safely(workload, location: location)&.dig("items", 0)
|
172
183
|
end
|
173
184
|
end
|
174
185
|
|
data/lib/command/run.rb
CHANGED
@@ -8,7 +8,9 @@ module Command
|
|
8
8
|
DEFAULT_ARGS = ["bash"].freeze
|
9
9
|
OPTIONS = [
|
10
10
|
app_option(required: true),
|
11
|
-
image_option
|
11
|
+
image_option,
|
12
|
+
workload_option,
|
13
|
+
use_local_token_option
|
12
14
|
].freeze
|
13
15
|
DESCRIPTION = "Runs one-off **_interactive_** replicas (analog of `heroku run`)"
|
14
16
|
LONG_DESCRIPTION = <<~DESC
|
@@ -34,19 +36,25 @@ module Command
|
|
34
36
|
# Uses a different image (which may not be promoted yet).
|
35
37
|
cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
|
36
38
|
cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
|
39
|
+
|
40
|
+
# Uses a different workload
|
41
|
+
cpl run bash -a $APP_NAME -w other-workload
|
42
|
+
|
43
|
+
# Overrides remote CPLN_TOKEN env variable with local token.
|
44
|
+
# Useful when need superuser rights in remote container
|
45
|
+
cpl run bash -a $APP_NAME --use-local-token
|
37
46
|
```
|
38
47
|
EX
|
39
48
|
|
40
|
-
attr_reader :location, :workload, :one_off
|
49
|
+
attr_reader :location, :workload, :one_off, :container
|
41
50
|
|
42
51
|
def call
|
43
52
|
@location = config[:default_location]
|
44
|
-
@workload = config[:one_off_workload]
|
53
|
+
@workload = config.options["workload"] || config[:one_off_workload]
|
45
54
|
@one_off = "#{workload}-run-#{rand(1000..9999)}"
|
46
55
|
|
47
56
|
clone_workload
|
48
57
|
wait_for_workload(one_off)
|
49
|
-
sleep 2 # sometimes replica query lags workload creation, despite ok by prev query
|
50
58
|
wait_for_replica(one_off, location)
|
51
59
|
run_in_replica
|
52
60
|
ensure
|
@@ -60,15 +68,16 @@ module Command
|
|
60
68
|
|
61
69
|
# Create a base copy of workload props
|
62
70
|
spec = cp.fetch_workload!(workload).fetch("spec")
|
63
|
-
|
71
|
+
container_spec = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
|
72
|
+
@container = container_spec["name"]
|
64
73
|
|
65
74
|
# remove other containers if any
|
66
|
-
spec["containers"] = [
|
75
|
+
spec["containers"] = [container_spec]
|
67
76
|
|
68
77
|
# Stub workload command with dummy server that just responds to port
|
69
78
|
# Needed to avoid execution of ENTRYPOINT and CMD of Dockerfile
|
70
|
-
|
71
|
-
|
79
|
+
container_spec["command"] = "ruby"
|
80
|
+
container_spec["args"] = ["-e", Scripts.http_dummy_server_ruby]
|
72
81
|
|
73
82
|
# Ensure one-off workload will be running
|
74
83
|
spec["defaultOptions"]["suspend"] = false
|
@@ -81,11 +90,15 @@ module Command
|
|
81
90
|
# Override image if specified
|
82
91
|
image = config.options[:image]
|
83
92
|
image = "/org/#{config.org}/image/#{latest_image}" if image == "latest"
|
84
|
-
|
93
|
+
container_spec["image"] = image if image
|
85
94
|
|
86
95
|
# Set runner
|
87
|
-
|
88
|
-
|
96
|
+
container_spec["env"] ||= []
|
97
|
+
container_spec["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
|
98
|
+
|
99
|
+
if config.options["use_local_token"]
|
100
|
+
container_spec["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
|
101
|
+
end
|
89
102
|
|
90
103
|
# Create workload clone
|
91
104
|
cp.apply("kind" => "workload", "name" => one_off, "spec" => spec)
|
@@ -93,6 +106,14 @@ module Command
|
|
93
106
|
|
94
107
|
def runner_script
|
95
108
|
script = Scripts.helpers_cleanup
|
109
|
+
|
110
|
+
if config.options["use_local_token"]
|
111
|
+
script += <<~SHELL
|
112
|
+
CPLN_TOKEN=$CONTROLPLANE_TOKEN
|
113
|
+
unset CONTROLPLANE_TOKEN
|
114
|
+
SHELL
|
115
|
+
end
|
116
|
+
|
96
117
|
script += args_join(config.args)
|
97
118
|
script
|
98
119
|
end
|
@@ -100,7 +121,7 @@ module Command
|
|
100
121
|
def run_in_replica
|
101
122
|
progress.puts "- Connecting"
|
102
123
|
command = %(bash -c 'eval "$CONTROLPLANE_RUNNER"')
|
103
|
-
cp.workload_exec(one_off, location: location, container:
|
124
|
+
cp.workload_exec(one_off, location: location, container: container, command: command)
|
104
125
|
end
|
105
126
|
end
|
106
127
|
end
|
data/lib/command/run_detached.rb
CHANGED
@@ -7,7 +7,8 @@ module Command
|
|
7
7
|
REQUIRES_ARGS = true
|
8
8
|
OPTIONS = [
|
9
9
|
app_option(required: true),
|
10
|
-
image_option
|
10
|
+
image_option,
|
11
|
+
workload_option
|
11
12
|
].freeze
|
12
13
|
DESCRIPTION = "Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)"
|
13
14
|
LONG_DESCRIPTION = <<~DESC
|
@@ -33,16 +34,19 @@ module Command
|
|
33
34
|
# Uses a different image (which may not be promoted yet).
|
34
35
|
cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
|
35
36
|
cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
|
37
|
+
|
38
|
+
# Uses a different workload
|
39
|
+
cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
|
36
40
|
```
|
37
41
|
EX
|
38
42
|
|
39
43
|
WORKLOAD_SLEEP_CHECK = 2
|
40
44
|
|
41
|
-
attr_reader :location, :workload, :one_off
|
45
|
+
attr_reader :location, :workload, :one_off, :container
|
42
46
|
|
43
47
|
def call
|
44
48
|
@location = config[:default_location]
|
45
|
-
@workload = config[:one_off_workload]
|
49
|
+
@workload = config.options["workload"] || config[:one_off_workload]
|
46
50
|
@one_off = "#{workload}-runner-#{rand(1000..9999)}"
|
47
51
|
|
48
52
|
clone_workload
|
@@ -60,14 +64,15 @@ module Command
|
|
60
64
|
|
61
65
|
# Get base specs of workload
|
62
66
|
spec = cp.fetch_workload!(workload).fetch("spec")
|
63
|
-
|
67
|
+
container_spec = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
|
68
|
+
@container = container_spec["name"]
|
64
69
|
|
65
70
|
# remove other containers if any
|
66
|
-
spec["containers"] = [
|
71
|
+
spec["containers"] = [container_spec]
|
67
72
|
|
68
73
|
# Set runner
|
69
|
-
|
70
|
-
|
74
|
+
container_spec["command"] = "bash"
|
75
|
+
container_spec["args"] = ["-c", 'eval "$CONTROLPLANE_RUNNER"']
|
71
76
|
|
72
77
|
# Ensure one-off workload will be running
|
73
78
|
spec["defaultOptions"]["suspend"] = false
|
@@ -80,17 +85,17 @@ module Command
|
|
80
85
|
# Override image if specified
|
81
86
|
image = config.options[:image]
|
82
87
|
image = "/org/#{config.org}/image/#{latest_image}" if image == "latest"
|
83
|
-
|
88
|
+
container_spec["image"] = image if image
|
84
89
|
|
85
90
|
# Set cron job props
|
86
91
|
spec["type"] = "cron"
|
87
92
|
spec["job"] = { "schedule" => "* * * * *", "restartPolicy" => "Never" }
|
88
93
|
spec["defaultOptions"]["autoscaling"] = {}
|
89
|
-
|
94
|
+
container_spec.delete("ports")
|
90
95
|
|
91
|
-
|
92
|
-
|
93
|
-
|
96
|
+
container_spec["env"] ||= []
|
97
|
+
container_spec["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
|
98
|
+
container_spec["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
|
94
99
|
|
95
100
|
# Create workload clone
|
96
101
|
cp.apply("kind" => "workload", "name" => one_off, "spec" => spec)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class SetupApp < Base
|
5
|
+
NAME = "setup-app"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true)
|
8
|
+
].freeze
|
9
|
+
DESCRIPTION = "Creates an app and all its workloads"
|
10
|
+
LONG_DESCRIPTION = <<~DESC
|
11
|
+
- Creates an app and all its workloads
|
12
|
+
- Specify the templates for the app and workloads through `setup` in the `.controlplane/controlplane.yml` file
|
13
|
+
- This should should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
|
14
|
+
DESC
|
15
|
+
|
16
|
+
def call
|
17
|
+
templates = config[:setup].join(" ")
|
18
|
+
|
19
|
+
app = cp.fetch_gvc
|
20
|
+
if app
|
21
|
+
raise "App '#{config.app}' already exists. If you want to update this app, " \
|
22
|
+
"either run 'cpl delete -a #{config.app}' and then re-run this command, " \
|
23
|
+
"or run 'cpl apply-template #{templates} -a #{config.app}'."
|
24
|
+
end
|
25
|
+
|
26
|
+
perform("cpl apply-template #{templates} -a #{config.app}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/core/controlplane.rb
CHANGED
@@ -130,6 +130,12 @@ class Controlplane # rubocop:disable Metrics/ClassLength
|
|
130
130
|
perform_yaml(cmd)
|
131
131
|
end
|
132
132
|
|
133
|
+
def workload_get_replicas_safely(workload, location:)
|
134
|
+
cmd = "cpln workload get-replicas #{workload} #{gvc_org} --location #{location} -o yaml 2> /dev/null"
|
135
|
+
result = `#{cmd}`
|
136
|
+
$CHILD_STATUS.success? ? YAML.safe_load(result) : nil
|
137
|
+
end
|
138
|
+
|
133
139
|
def workload_set_image_ref(workload, container:, image:)
|
134
140
|
cmd = "cpln workload update #{workload} #{gvc_org}"
|
135
141
|
cmd += " --set spec.containers.#{container}.image=/org/#{config.org}/image/#{image}"
|
data/lib/cpl/version.rb
CHANGED
data/lib/cpl.rb
CHANGED
@@ -9,7 +9,12 @@ require "tempfile"
|
|
9
9
|
require "thor"
|
10
10
|
require "yaml"
|
11
11
|
|
12
|
-
|
12
|
+
# We need to require base before all commands, since the commands inherit from it
|
13
|
+
require_relative "command/base"
|
14
|
+
|
15
|
+
modules = Dir["#{__dir__}/**/*.rb"].reject do |file|
|
16
|
+
file == __FILE__ || file.end_with?("main.rb") || file.end_with?("base.rb")
|
17
|
+
end
|
13
18
|
modules.sort.each { require(_1) }
|
14
19
|
|
15
20
|
# Fix for https://github.com/erikhuda/thor/issues/398
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cpl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Gordon
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-04-
|
12
|
+
date: 2023-04-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: debug
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- examples/circleci.yml
|
184
184
|
- examples/controlplane.yml
|
185
185
|
- googlee2da545df05d92f9.html
|
186
|
+
- lib/command/apply_template.rb
|
186
187
|
- lib/command/base.rb
|
187
188
|
- lib/command/build_image.rb
|
188
189
|
- lib/command/cleanup_old_images.rb
|
@@ -205,7 +206,7 @@ files:
|
|
205
206
|
- lib/command/ps_stop.rb
|
206
207
|
- lib/command/run.rb
|
207
208
|
- lib/command/run_detached.rb
|
208
|
-
- lib/command/
|
209
|
+
- lib/command/setup_app.rb
|
209
210
|
- lib/command/test.rb
|
210
211
|
- lib/command/version.rb
|
211
212
|
- lib/core/config.rb
|
@@ -250,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
250
251
|
- !ruby/object:Gem::Version
|
251
252
|
version: '0'
|
252
253
|
requirements: []
|
253
|
-
rubygems_version: 3.4.
|
254
|
+
rubygems_version: 3.4.12
|
254
255
|
signing_key:
|
255
256
|
specification_version: 4
|
256
257
|
summary: Heroku to Control Plane
|