cpl 1.1.2.rc.0 → 1.2.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/.github/workflows/rspec.yml +1 -1
- data/CHANGELOG.md +36 -1
- data/CONTRIBUTING.md +2 -6
- data/Gemfile.lock +7 -7
- data/README.md +94 -53
- data/docs/commands.md +22 -5
- data/docs/migrating.md +3 -3
- data/examples/controlplane.yml +63 -4
- data/lib/command/apply_template.rb +30 -54
- data/lib/command/base.rb +43 -0
- data/lib/command/copy_image_from_upstream.rb +5 -2
- data/lib/command/delete.rb +40 -11
- data/lib/command/env.rb +1 -0
- data/lib/command/generate.rb +45 -0
- data/lib/command/info.rb +5 -5
- data/lib/command/latest_image.rb +1 -0
- data/lib/command/maintenance.rb +1 -0
- data/lib/command/no_command.rb +6 -3
- data/lib/command/open_console.rb +26 -0
- data/lib/command/ps.rb +5 -1
- data/lib/command/run.rb +2 -2
- data/lib/command/run_detached.rb +2 -1
- data/lib/command/setup_app.rb +3 -3
- data/lib/command/version.rb +1 -0
- data/lib/core/config.rb +185 -54
- data/lib/core/controlplane.rb +76 -24
- data/lib/core/controlplane_api.rb +9 -1
- data/lib/core/controlplane_api_direct.rb +20 -2
- data/lib/core/helpers.rb +10 -0
- data/lib/core/shell.rb +36 -2
- data/lib/cpl/version.rb +1 -1
- data/lib/cpl.rb +28 -2
- data/lib/generator_templates/Dockerfile +27 -0
- data/lib/generator_templates/controlplane.yml +57 -0
- data/lib/generator_templates/entrypoint.sh +8 -0
- data/lib/generator_templates/templates/gvc.yml +21 -0
- data/lib/generator_templates/templates/postgres.yml +176 -0
- data/lib/generator_templates/templates/rails.yml +36 -0
- metadata +14 -5
@@ -7,6 +7,7 @@ module Command
|
|
7
7
|
REQUIRES_ARGS = true
|
8
8
|
OPTIONS = [
|
9
9
|
app_option(required: true),
|
10
|
+
location_option,
|
10
11
|
skip_confirm_option
|
11
12
|
].freeze
|
12
13
|
DESCRIPTION = "Applies application-specific configs from templates"
|
@@ -35,13 +36,12 @@ module Command
|
|
35
36
|
```
|
36
37
|
EX
|
37
38
|
|
38
|
-
def call # rubocop:disable Metrics/MethodLength
|
39
|
+
def call # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
|
39
40
|
ensure_templates!
|
40
41
|
|
41
|
-
@
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@skipped_workloads = []
|
42
|
+
@created_items = []
|
43
|
+
@failed_templates = []
|
44
|
+
@skipped_templates = []
|
45
45
|
|
46
46
|
@asked_for_confirmation = false
|
47
47
|
|
@@ -57,9 +57,11 @@ module Command
|
|
57
57
|
|
58
58
|
pending_templates.each do |template, filename|
|
59
59
|
step("Applying template '#{template}'", abort_on_error: false) do
|
60
|
-
apply_template(filename)
|
61
|
-
if
|
62
|
-
|
60
|
+
items = apply_template(filename)
|
61
|
+
if items
|
62
|
+
items.each do |item|
|
63
|
+
report_success(item)
|
64
|
+
end
|
63
65
|
else
|
64
66
|
report_failure(template)
|
65
67
|
end
|
@@ -68,10 +70,9 @@ module Command
|
|
68
70
|
end
|
69
71
|
end
|
70
72
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
print_skipped_workloads
|
73
|
+
print_created_items
|
74
|
+
print_failed_templates
|
75
|
+
print_skipped_templates
|
75
76
|
end
|
76
77
|
|
77
78
|
private
|
@@ -126,7 +127,7 @@ module Command
|
|
126
127
|
def apply_template(filename)
|
127
128
|
data = File.read(filename)
|
128
129
|
.gsub("APP_GVC", config.app)
|
129
|
-
.gsub("APP_LOCATION", config
|
130
|
+
.gsub("APP_LOCATION", config.location)
|
130
131
|
.gsub("APP_ORG", config.org)
|
131
132
|
.gsub("APP_IMAGE", latest_image)
|
132
133
|
|
@@ -134,62 +135,37 @@ module Command
|
|
134
135
|
cp.apply_template(data)
|
135
136
|
end
|
136
137
|
|
137
|
-
def report_success(
|
138
|
-
|
139
|
-
@app_status = :success
|
140
|
-
else
|
141
|
-
@created_workloads.push(template)
|
142
|
-
end
|
138
|
+
def report_success(item)
|
139
|
+
@created_items.push(item)
|
143
140
|
end
|
144
141
|
|
145
142
|
def report_failure(template)
|
146
|
-
|
147
|
-
@app_status = :failure
|
148
|
-
else
|
149
|
-
@failed_workloads.push(template)
|
150
|
-
end
|
143
|
+
@failed_templates.push(template)
|
151
144
|
end
|
152
145
|
|
153
146
|
def report_skipped(template)
|
154
|
-
|
155
|
-
@app_status = :skipped
|
156
|
-
else
|
157
|
-
@skipped_workloads.push(template)
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def print_app_status
|
162
|
-
return if @app_status == :existing
|
163
|
-
|
164
|
-
case @app_status
|
165
|
-
when :success
|
166
|
-
progress.puts("\n#{Shell.color("Created app '#{config.app}'.", :green)}")
|
167
|
-
when :failure
|
168
|
-
progress.puts("\n#{Shell.color("Failed to create app '#{config.app}'.", :red)}")
|
169
|
-
when :skipped
|
170
|
-
progress.puts("\n#{Shell.color("Skipped app '#{config.app}' (already exists).", :blue)}")
|
171
|
-
end
|
147
|
+
@skipped_templates.push(template)
|
172
148
|
end
|
173
149
|
|
174
|
-
def
|
175
|
-
return unless @
|
150
|
+
def print_created_items
|
151
|
+
return unless @created_items.any?
|
176
152
|
|
177
|
-
|
178
|
-
progress.puts("\n#{Shell.color('Created
|
153
|
+
created = @created_items.map { |item| " - [#{item[:kind]}] #{item[:name]}" }.join("\n")
|
154
|
+
progress.puts("\n#{Shell.color('Created items:', :green)}\n#{created}")
|
179
155
|
end
|
180
156
|
|
181
|
-
def
|
182
|
-
return unless @
|
157
|
+
def print_failed_templates
|
158
|
+
return unless @failed_templates.any?
|
183
159
|
|
184
|
-
|
185
|
-
progress.puts("\n#{Shell.color('Failed to
|
160
|
+
failed = @failed_templates.map { |template| " - #{template}" }.join("\n")
|
161
|
+
progress.puts("\n#{Shell.color('Failed to apply templates:', :red)}\n#{failed}")
|
186
162
|
end
|
187
163
|
|
188
|
-
def
|
189
|
-
return unless @
|
164
|
+
def print_skipped_templates
|
165
|
+
return unless @skipped_templates.any?
|
190
166
|
|
191
|
-
|
192
|
-
progress.puts("\n#{Shell.color('Skipped
|
167
|
+
skipped = @skipped_templates.map { |template| " - #{template}" }.join("\n")
|
168
|
+
progress.puts("\n#{Shell.color('Skipped templates (already exist):', :blue)}\n#{skipped}")
|
193
169
|
end
|
194
170
|
end
|
195
171
|
end
|
data/lib/command/base.rb
CHANGED
@@ -23,6 +23,8 @@ module Command
|
|
23
23
|
EXAMPLES = ""
|
24
24
|
# If `true`, hides the command from `cpl help`
|
25
25
|
HIDE = false
|
26
|
+
# Whether or not to show key information like ORG and APP name in commands
|
27
|
+
WITH_INFO_HEADER = true
|
26
28
|
|
27
29
|
NO_IMAGE_AVAILABLE = "NO_IMAGE_AVAILABLE"
|
28
30
|
|
@@ -38,6 +40,10 @@ module Command
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
43
|
+
def self.common_options
|
44
|
+
[org_option, verbose_option, trace_option]
|
45
|
+
end
|
46
|
+
|
41
47
|
def self.org_option(required: false)
|
42
48
|
{
|
43
49
|
name: :org,
|
@@ -103,6 +109,19 @@ module Command
|
|
103
109
|
}
|
104
110
|
end
|
105
111
|
|
112
|
+
def self.location_option(required: false)
|
113
|
+
{
|
114
|
+
name: :location,
|
115
|
+
params: {
|
116
|
+
aliases: ["-l"],
|
117
|
+
banner: "LOCATION_NAME",
|
118
|
+
desc: "Location name",
|
119
|
+
type: :string,
|
120
|
+
required: required
|
121
|
+
}
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
106
125
|
def self.upstream_token_option(required: false)
|
107
126
|
{
|
108
127
|
name: :upstream_token,
|
@@ -176,6 +195,29 @@ module Command
|
|
176
195
|
}
|
177
196
|
end
|
178
197
|
|
198
|
+
def self.verbose_option(required: false)
|
199
|
+
{
|
200
|
+
name: :verbose,
|
201
|
+
params: {
|
202
|
+
aliases: ["-d"],
|
203
|
+
desc: "Shows detailed logs",
|
204
|
+
type: :boolean,
|
205
|
+
required: required
|
206
|
+
}
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.trace_option(required: false)
|
211
|
+
{
|
212
|
+
name: :trace,
|
213
|
+
params: {
|
214
|
+
desc: "Shows trace of API calls. WARNING: may contain sensitive data",
|
215
|
+
type: :boolean,
|
216
|
+
required: required
|
217
|
+
}
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
179
221
|
def self.all_options
|
180
222
|
methods.grep(/_option$/).map { |method| send(method.to_s) }
|
181
223
|
end
|
@@ -227,6 +269,7 @@ module Command
|
|
227
269
|
end
|
228
270
|
|
229
271
|
def latest_image_next(app = config.app, org = config.org, commit: nil)
|
272
|
+
# debugger
|
230
273
|
commit ||= config.options[:commit]
|
231
274
|
|
232
275
|
@latest_image_next ||= {}
|
@@ -29,7 +29,7 @@ module Command
|
|
29
29
|
ensure_docker_running!
|
30
30
|
|
31
31
|
@upstream = config[:upstream]
|
32
|
-
@upstream_org = config.apps[@upstream.to_sym][:cpln_org]
|
32
|
+
@upstream_org = config.apps[@upstream.to_sym][:cpln_org] || ENV.fetch("CPLN_ORG_UPSTREAM", nil)
|
33
33
|
ensure_upstream_org!
|
34
34
|
|
35
35
|
create_upstream_profile
|
@@ -51,7 +51,10 @@ module Command
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def ensure_upstream_org!
|
54
|
-
|
54
|
+
return if @upstream_org
|
55
|
+
|
56
|
+
raise "Can't find option 'cpln_org' for app '#{@upstream}' in 'controlplane.yml', " \
|
57
|
+
"and CPLN_ORG_UPSTREAM env var is not set."
|
55
58
|
end
|
56
59
|
|
57
60
|
def create_upstream_profile
|
data/lib/command/delete.rb
CHANGED
@@ -7,21 +7,45 @@ module Command
|
|
7
7
|
app_option(required: true),
|
8
8
|
skip_confirm_option
|
9
9
|
].freeze
|
10
|
-
DESCRIPTION = "Deletes the whole app (GVC with all workloads and all images)"
|
10
|
+
DESCRIPTION = "Deletes the whole app (GVC with all workloads, all volumesets and all images)"
|
11
11
|
LONG_DESCRIPTION = <<~DESC
|
12
|
-
- Deletes the whole app (GVC with all workloads and all images)
|
12
|
+
- Deletes the whole app (GVC with all workloads, all volumesets and all images)
|
13
13
|
- Will ask for explicit user confirmation
|
14
14
|
DESC
|
15
15
|
|
16
16
|
def call
|
17
|
+
return progress.puts("App '#{config.app}' does not exist.") if cp.fetch_gvc.nil?
|
18
|
+
|
19
|
+
check_volumesets
|
20
|
+
check_images
|
17
21
|
return unless confirm_delete
|
18
22
|
|
23
|
+
delete_volumesets
|
19
24
|
delete_gvc
|
20
25
|
delete_images
|
21
26
|
end
|
22
27
|
|
23
28
|
private
|
24
29
|
|
30
|
+
def check_volumesets
|
31
|
+
@volumesets = cp.fetch_volumesets["items"]
|
32
|
+
return progress.puts("No volumesets to delete.") unless @volumesets.any?
|
33
|
+
|
34
|
+
message = "The following volumesets will be deleted along with the app:"
|
35
|
+
volumesets_list = @volumesets.map { |volumeset| "- #{volumeset['name']}" }.join("\n")
|
36
|
+
progress.puts("#{Shell.color(message, :red)}\n#{volumesets_list}\n\n")
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_images
|
40
|
+
@images = cp.query_images["items"]
|
41
|
+
.select { |image| image["name"].start_with?("#{config.app}:") }
|
42
|
+
return progress.puts("No images to delete.") unless @images.any?
|
43
|
+
|
44
|
+
message = "The following images will be deleted along with the app:"
|
45
|
+
images_list = @images.map { |image| "- #{image['name']}" }.join("\n")
|
46
|
+
progress.puts("#{Shell.color(message, :red)}\n#{images_list}\n\n")
|
47
|
+
end
|
48
|
+
|
25
49
|
def confirm_delete
|
26
50
|
return true if config.options[:yes]
|
27
51
|
|
@@ -33,22 +57,27 @@ module Command
|
|
33
57
|
end
|
34
58
|
|
35
59
|
def delete_gvc
|
36
|
-
return progress.puts("App '#{config.app}' does not exist.") if cp.fetch_gvc.nil?
|
37
|
-
|
38
60
|
step("Deleting app '#{config.app}'") do
|
39
61
|
cp.gvc_delete
|
40
62
|
end
|
41
63
|
end
|
42
64
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
65
|
+
def delete_volumesets
|
66
|
+
@volumesets.each do |volumeset|
|
67
|
+
step("Deleting volumeset '#{volumeset['name']}'") do
|
68
|
+
# If the volumeset is attached to a workload, we need to delete the workload first
|
69
|
+
workload = volumeset.dig("status", "usedByWorkload")&.split("/")&.last
|
70
|
+
cp.delete_workload(workload) if workload
|
46
71
|
|
47
|
-
|
72
|
+
cp.delete_volumeset(volumeset["name"])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
48
76
|
|
49
|
-
|
50
|
-
|
51
|
-
|
77
|
+
def delete_images
|
78
|
+
@images.each do |image|
|
79
|
+
step("Deleting image '#{image['name']}'") do
|
80
|
+
cp.image_delete(image["name"])
|
52
81
|
end
|
53
82
|
end
|
54
83
|
end
|
data/lib/command/env.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class Generator < Thor::Group
|
5
|
+
include Thor::Actions
|
6
|
+
|
7
|
+
def copy_files
|
8
|
+
directory("generator_templates", ".controlplane")
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.source_root
|
12
|
+
File.expand_path("../", __dir__)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Generate < Base
|
17
|
+
NAME = "generate"
|
18
|
+
DESCRIPTION = "Creates base Control Plane config and template files"
|
19
|
+
LONG_DESCRIPTION = <<~DESC
|
20
|
+
Creates base Control Plane config and template files
|
21
|
+
DESC
|
22
|
+
EXAMPLES = <<~EX
|
23
|
+
```sh
|
24
|
+
# Creates .controlplane directory with Control Plane config and other templates
|
25
|
+
cpl generate
|
26
|
+
```
|
27
|
+
EX
|
28
|
+
WITH_INFO_HEADER = false
|
29
|
+
|
30
|
+
def call
|
31
|
+
if controlplane_directory_exists?
|
32
|
+
Shell.warn("The directory '.controlplane' already exists!")
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
Generator.start
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def controlplane_directory_exists?
|
42
|
+
Dir.exist? ".controlplane"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/command/info.rb
CHANGED
@@ -4,7 +4,6 @@ module Command
|
|
4
4
|
class Info < Base # rubocop:disable Metrics/ClassLength
|
5
5
|
NAME = "info"
|
6
6
|
OPTIONS = [
|
7
|
-
org_option,
|
8
7
|
app_option
|
9
8
|
].freeze
|
10
9
|
DESCRIPTION = "Displays the diff between defined/available apps/workloads (apps equal GVCs)"
|
@@ -17,7 +16,7 @@ module Command
|
|
17
16
|
DESC
|
18
17
|
EXAMPLES = <<~EX
|
19
18
|
```sh
|
20
|
-
# Shows diff for all apps in all orgs.
|
19
|
+
# Shows diff for all apps in all orgs (based on `.controlplane/controlplane.yml`).
|
21
20
|
cpl info
|
22
21
|
|
23
22
|
# Shows diff for all apps in a specific org.
|
@@ -27,6 +26,7 @@ module Command
|
|
27
26
|
cpl info -a $APP_NAME
|
28
27
|
```
|
29
28
|
EX
|
29
|
+
WITH_INFO_HEADER = false
|
30
30
|
|
31
31
|
def call
|
32
32
|
@missing_apps_workloads = {}
|
@@ -84,14 +84,14 @@ module Command
|
|
84
84
|
def orgs # rubocop:disable Metrics/MethodLength
|
85
85
|
result = []
|
86
86
|
|
87
|
-
if config.
|
88
|
-
result.push(config.
|
87
|
+
if config.org
|
88
|
+
result.push(config.org)
|
89
89
|
else
|
90
90
|
config.apps.each do |app_name, app_options|
|
91
91
|
next if config.app && !app_matches?(config.app, app_name, app_options)
|
92
92
|
|
93
93
|
org = app_options[:cpln_org]
|
94
|
-
result.push(org)
|
94
|
+
result.push(org) if org && !result.include?(org)
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
data/lib/command/latest_image.rb
CHANGED
data/lib/command/maintenance.rb
CHANGED
@@ -14,6 +14,7 @@ module Command
|
|
14
14
|
- Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
|
15
15
|
- Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
|
16
16
|
DESC
|
17
|
+
WITH_INFO_HEADER = false
|
17
18
|
|
18
19
|
def call # rubocop:disable Metrics/MethodLength
|
19
20
|
one_off_workload = config[:one_off_workload]
|
data/lib/command/no_command.rb
CHANGED
@@ -9,11 +9,14 @@ module Command
|
|
9
9
|
- Called when no command was specified
|
10
10
|
DESC
|
11
11
|
HIDE = true
|
12
|
+
WITH_INFO_HEADER = false
|
12
13
|
|
13
14
|
def call
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
if config.options[:version]
|
16
|
+
Cpl::Cli.start(["version"])
|
17
|
+
else
|
18
|
+
Cpl::Cli.start(["help"])
|
19
|
+
end
|
17
20
|
end
|
18
21
|
end
|
19
22
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class OpenConsole < Base
|
5
|
+
NAME = "open-console"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true),
|
8
|
+
workload_option
|
9
|
+
].freeze
|
10
|
+
DESCRIPTION = "Opens the app console on Control Plane in the default browser"
|
11
|
+
LONG_DESCRIPTION = <<~DESC
|
12
|
+
- Opens the app console on Control Plane in the default browser
|
13
|
+
- Can also go directly to a workload page if `--workload` is provided
|
14
|
+
DESC
|
15
|
+
|
16
|
+
def call
|
17
|
+
workload = config.options[:workload]
|
18
|
+
url = "https://console.cpln.io/console/org/#{config.org}/gvc/#{config.app}"
|
19
|
+
url += "/workload/#{workload}" if workload
|
20
|
+
url += "/-info"
|
21
|
+
opener = `which xdg-open open`.split("\n").grep_v("not found").first
|
22
|
+
|
23
|
+
exec %(#{opener} "#{url}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/command/ps.rb
CHANGED
@@ -5,6 +5,7 @@ module Command
|
|
5
5
|
NAME = "ps"
|
6
6
|
OPTIONS = [
|
7
7
|
app_option(required: true),
|
8
|
+
location_option,
|
8
9
|
workload_option
|
9
10
|
].freeze
|
10
11
|
DESCRIPTION = "Shows running replicas in app"
|
@@ -20,16 +21,19 @@ module Command
|
|
20
21
|
cpl ps -a $APP_NAME -w $WORKLOAD_NAME
|
21
22
|
```
|
22
23
|
EX
|
24
|
+
WITH_INFO_HEADER = false
|
23
25
|
|
24
26
|
def call
|
25
27
|
cp.fetch_gvc!
|
26
28
|
|
29
|
+
location = config.location
|
30
|
+
|
27
31
|
workloads = [config.options[:workload]] if config.options[:workload]
|
28
32
|
workloads ||= config[:app_workloads] + config[:additional_workloads]
|
29
33
|
workloads.each do |workload|
|
30
34
|
cp.fetch_workload!(workload)
|
31
35
|
|
32
|
-
result = cp.workload_get_replicas(workload, location:
|
36
|
+
result = cp.workload_get_replicas(workload, location: location)
|
33
37
|
result["items"].each { |replica| puts replica }
|
34
38
|
end
|
35
39
|
end
|
data/lib/command/run.rb
CHANGED
@@ -10,6 +10,7 @@ module Command
|
|
10
10
|
app_option(required: true),
|
11
11
|
image_option,
|
12
12
|
workload_option,
|
13
|
+
location_option,
|
13
14
|
use_local_token_option,
|
14
15
|
terminal_size_option
|
15
16
|
].freeze
|
@@ -17,7 +18,6 @@ module Command
|
|
17
18
|
LONG_DESCRIPTION = <<~DESC
|
18
19
|
- Runs one-off **_interactive_** replicas (analog of `heroku run`)
|
19
20
|
- Uses `Standard` workload type and `cpln exec` as the execution method, with CLI streaming
|
20
|
-
- May not work correctly with tasks that last over 5 minutes (there's a Control Plane scaling bug at the moment)
|
21
21
|
- If `fix_terminal_size` is `true` in the `.controlplane/controlplane.yml` file, the remote terminal size will be fixed to match the local terminal size (may also be overriden through `--terminal-size`)
|
22
22
|
|
23
23
|
> **IMPORTANT:** Useful for development where it's needed for interaction, and where network connection drops and
|
@@ -57,7 +57,7 @@ module Command
|
|
57
57
|
attr_reader :location, :workload, :one_off, :container
|
58
58
|
|
59
59
|
def call # rubocop:disable Metrics/MethodLength
|
60
|
-
@location = config
|
60
|
+
@location = config.location
|
61
61
|
@workload = config.options["workload"] || config[:one_off_workload]
|
62
62
|
@one_off = "#{workload}-run-#{rand(1000..9999)}"
|
63
63
|
|
data/lib/command/run_detached.rb
CHANGED
@@ -9,6 +9,7 @@ module Command
|
|
9
9
|
app_option(required: true),
|
10
10
|
image_option,
|
11
11
|
workload_option,
|
12
|
+
location_option,
|
12
13
|
use_local_token_option
|
13
14
|
].freeze
|
14
15
|
DESCRIPTION = "Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)"
|
@@ -47,7 +48,7 @@ module Command
|
|
47
48
|
attr_reader :location, :workload, :one_off, :container
|
48
49
|
|
49
50
|
def call # rubocop:disable Metrics/MethodLength
|
50
|
-
@location = config
|
51
|
+
@location = config.location
|
51
52
|
@workload = config.options["workload"] || config[:one_off_workload]
|
52
53
|
@one_off = "#{workload}-runner-#{rand(1000..9999)}"
|
53
54
|
|
data/lib/command/setup_app.rb
CHANGED
@@ -9,12 +9,12 @@ module Command
|
|
9
9
|
DESCRIPTION = "Creates an app and all its workloads"
|
10
10
|
LONG_DESCRIPTION = <<~DESC
|
11
11
|
- Creates an app and all its workloads
|
12
|
-
- Specify the templates for the app and workloads through `
|
13
|
-
- This should
|
12
|
+
- Specify the templates for the app and workloads through `setup_app_templates` in the `.controlplane/controlplane.yml` file
|
13
|
+
- This 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
14
|
DESC
|
15
15
|
|
16
16
|
def call
|
17
|
-
templates = config[:
|
17
|
+
templates = config[:setup_app_templates]
|
18
18
|
|
19
19
|
app = cp.fetch_gvc
|
20
20
|
if app
|