cpflow 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/check_cpln_links.yml +19 -0
- data/.github/workflows/command_docs.yml +24 -0
- data/.github/workflows/rspec-shared.yml +56 -0
- data/.github/workflows/rspec.yml +28 -0
- data/.github/workflows/rubocop.yml +24 -0
- data/.gitignore +18 -0
- data/.overcommit.yml +16 -0
- data/.rubocop.yml +22 -0
- data/.simplecov_spawn.rb +10 -0
- data/CHANGELOG.md +259 -0
- data/CONTRIBUTING.md +73 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +126 -0
- data/LICENSE +21 -0
- data/README.md +546 -0
- data/Rakefile +21 -0
- data/bin/cpflow +6 -0
- data/cpflow +6 -0
- data/cpflow.gemspec +41 -0
- data/docs/assets/grafana-alert.png +0 -0
- data/docs/assets/memcached.png +0 -0
- data/docs/assets/sidekiq-pre-stop-hook.png +0 -0
- data/docs/commands.md +454 -0
- data/docs/dns.md +15 -0
- data/docs/migrating.md +262 -0
- data/docs/postgres.md +436 -0
- data/docs/redis.md +128 -0
- data/docs/secrets-and-env-values.md +42 -0
- data/docs/tips.md +150 -0
- data/docs/troubleshooting.md +6 -0
- data/examples/circleci.yml +104 -0
- data/examples/controlplane.yml +159 -0
- data/lib/command/apply_template.rb +209 -0
- data/lib/command/base.rb +540 -0
- data/lib/command/build_image.rb +49 -0
- data/lib/command/cleanup_images.rb +136 -0
- data/lib/command/cleanup_stale_apps.rb +79 -0
- data/lib/command/config.rb +48 -0
- data/lib/command/copy_image_from_upstream.rb +108 -0
- data/lib/command/delete.rb +149 -0
- data/lib/command/deploy_image.rb +56 -0
- data/lib/command/doctor.rb +47 -0
- data/lib/command/env.rb +22 -0
- data/lib/command/exists.rb +23 -0
- data/lib/command/generate.rb +45 -0
- data/lib/command/info.rb +222 -0
- data/lib/command/latest_image.rb +19 -0
- data/lib/command/logs.rb +49 -0
- data/lib/command/maintenance.rb +42 -0
- data/lib/command/maintenance_off.rb +62 -0
- data/lib/command/maintenance_on.rb +62 -0
- data/lib/command/maintenance_set_page.rb +34 -0
- data/lib/command/no_command.rb +23 -0
- data/lib/command/open.rb +33 -0
- data/lib/command/open_console.rb +26 -0
- data/lib/command/promote_app_from_upstream.rb +38 -0
- data/lib/command/ps.rb +41 -0
- data/lib/command/ps_restart.rb +37 -0
- data/lib/command/ps_start.rb +51 -0
- data/lib/command/ps_stop.rb +82 -0
- data/lib/command/ps_wait.rb +40 -0
- data/lib/command/run.rb +573 -0
- data/lib/command/setup_app.rb +113 -0
- data/lib/command/test.rb +23 -0
- data/lib/command/version.rb +18 -0
- data/lib/constants/exit_code.rb +7 -0
- data/lib/core/config.rb +316 -0
- data/lib/core/controlplane.rb +552 -0
- data/lib/core/controlplane_api.rb +170 -0
- data/lib/core/controlplane_api_direct.rb +112 -0
- data/lib/core/doctor_service.rb +104 -0
- data/lib/core/helpers.rb +26 -0
- data/lib/core/shell.rb +100 -0
- data/lib/core/template_parser.rb +76 -0
- data/lib/cpflow/version.rb +6 -0
- data/lib/cpflow.rb +288 -0
- data/lib/deprecated_commands.json +9 -0
- data/lib/generator_templates/Dockerfile +27 -0
- data/lib/generator_templates/controlplane.yml +62 -0
- data/lib/generator_templates/entrypoint.sh +8 -0
- data/lib/generator_templates/templates/app.yml +21 -0
- data/lib/generator_templates/templates/postgres.yml +176 -0
- data/lib/generator_templates/templates/rails.yml +36 -0
- data/rakelib/create_release.rake +81 -0
- data/script/add_command +37 -0
- data/script/check_command_docs +3 -0
- data/script/check_cpln_links +45 -0
- data/script/rename_command +43 -0
- data/script/update_command_docs +62 -0
- data/templates/app.yml +13 -0
- data/templates/daily-task.yml +32 -0
- data/templates/maintenance.yml +25 -0
- data/templates/memcached.yml +24 -0
- data/templates/postgres.yml +32 -0
- data/templates/rails.yml +27 -0
- data/templates/redis.yml +21 -0
- data/templates/redis2.yml +37 -0
- data/templates/sidekiq.yml +38 -0
- metadata +341 -0
data/lib/command/ps.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class Ps < Base
|
5
|
+
NAME = "ps"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true),
|
8
|
+
location_option,
|
9
|
+
workload_option
|
10
|
+
].freeze
|
11
|
+
DESCRIPTION = "Shows running replicas in app"
|
12
|
+
LONG_DESCRIPTION = <<~DESC
|
13
|
+
- Shows running replicas in app
|
14
|
+
DESC
|
15
|
+
EXAMPLES = <<~EX
|
16
|
+
```sh
|
17
|
+
# Shows running replicas in app, for all workloads.
|
18
|
+
cpflow ps -a $APP_NAME
|
19
|
+
|
20
|
+
# Shows running replicas in app, for a specific workload.
|
21
|
+
cpflow ps -a $APP_NAME -w $WORKLOAD_NAME
|
22
|
+
```
|
23
|
+
EX
|
24
|
+
WITH_INFO_HEADER = false
|
25
|
+
|
26
|
+
def call
|
27
|
+
cp.fetch_gvc!
|
28
|
+
|
29
|
+
location = config.location
|
30
|
+
|
31
|
+
workloads = [config.options[:workload]] if config.options[:workload]
|
32
|
+
workloads ||= config[:app_workloads] + config[:additional_workloads]
|
33
|
+
workloads.each do |workload|
|
34
|
+
cp.fetch_workload!(workload)
|
35
|
+
|
36
|
+
result = cp.fetch_workload_replicas(workload, location: location)
|
37
|
+
result["items"].each { |replica| puts replica }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class PsRestart < Base
|
5
|
+
NAME = "ps:restart"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true),
|
8
|
+
workload_option
|
9
|
+
].freeze
|
10
|
+
DESCRIPTION = "Forces redeploy of workloads in app"
|
11
|
+
LONG_DESCRIPTION = <<~DESC
|
12
|
+
- Forces redeploy of workloads in app
|
13
|
+
DESC
|
14
|
+
EXAMPLES = <<~EX
|
15
|
+
```sh
|
16
|
+
# Forces redeploy of all workloads in app.
|
17
|
+
cpflow ps:restart -a $APP_NAME
|
18
|
+
|
19
|
+
# Forces redeploy of a specific workload in app.
|
20
|
+
cpflow ps:restart -a $APP_NAME -w $WORKLOAD_NAME
|
21
|
+
```
|
22
|
+
EX
|
23
|
+
|
24
|
+
def call
|
25
|
+
workloads = [config.options[:workload]] if config.options[:workload]
|
26
|
+
workloads ||= config[:app_workloads] + config[:additional_workloads]
|
27
|
+
|
28
|
+
workloads.each do |workload|
|
29
|
+
step("Restarting workload '#{workload}'") do
|
30
|
+
cp.fetch_workload!(workload)
|
31
|
+
|
32
|
+
cp.workload_force_redeployment(workload)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class PsStart < Base
|
5
|
+
NAME = "ps:start"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true),
|
8
|
+
workload_option,
|
9
|
+
location_option,
|
10
|
+
wait_option("workload to be ready")
|
11
|
+
].freeze
|
12
|
+
DESCRIPTION = "Starts workloads in app"
|
13
|
+
LONG_DESCRIPTION = <<~DESC
|
14
|
+
- Starts workloads in app
|
15
|
+
DESC
|
16
|
+
EXAMPLES = <<~EX
|
17
|
+
```sh
|
18
|
+
# Starts all workloads in app.
|
19
|
+
cpflow ps:start -a $APP_NAME
|
20
|
+
|
21
|
+
# Starts a specific workload in app.
|
22
|
+
cpflow ps:start -a $APP_NAME -w $WORKLOAD_NAME
|
23
|
+
```
|
24
|
+
EX
|
25
|
+
|
26
|
+
def call
|
27
|
+
@workloads = [config.options[:workload]] if config.options[:workload]
|
28
|
+
@workloads ||= config[:app_workloads] + config[:additional_workloads]
|
29
|
+
|
30
|
+
@workloads.reverse_each do |workload|
|
31
|
+
step("Starting workload '#{workload}'") do
|
32
|
+
cp.set_workload_suspend(workload, false)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
wait_for_ready if config.options[:wait]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def wait_for_ready
|
42
|
+
progress.puts
|
43
|
+
|
44
|
+
@workloads.reverse_each do |workload|
|
45
|
+
step("Waiting for workload '#{workload}' to be ready", retry_on_failure: true) do
|
46
|
+
cp.workload_deployments_ready?(workload, location: config.location, expected_status: true)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class PsStop < Base
|
5
|
+
NAME = "ps:stop"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true),
|
8
|
+
workload_option,
|
9
|
+
replica_option,
|
10
|
+
location_option,
|
11
|
+
wait_option("workload to not be ready")
|
12
|
+
].freeze
|
13
|
+
DESCRIPTION = "Stops workloads in app"
|
14
|
+
LONG_DESCRIPTION = <<~DESC
|
15
|
+
- Stops workloads in app
|
16
|
+
DESC
|
17
|
+
EXAMPLES = <<~EX
|
18
|
+
```sh
|
19
|
+
# Stops all workloads in app.
|
20
|
+
cpflow ps:stop -a $APP_NAME
|
21
|
+
|
22
|
+
# Stops a specific workload in app.
|
23
|
+
cpflow ps:stop -a $APP_NAME -w $WORKLOAD_NAME
|
24
|
+
|
25
|
+
# Stops a specific replica of a workload.
|
26
|
+
cpflow ps:stop -a $APP_NAME -w $WORKLOAD_NAME -r $REPLICA_NAME
|
27
|
+
```
|
28
|
+
EX
|
29
|
+
|
30
|
+
def call
|
31
|
+
workload = config.options[:workload]
|
32
|
+
replica = config.options[:replica]
|
33
|
+
if replica
|
34
|
+
stop_replica(workload, replica)
|
35
|
+
else
|
36
|
+
workloads = [workload] if workload
|
37
|
+
workloads ||= config[:app_workloads] + config[:additional_workloads]
|
38
|
+
|
39
|
+
stop_workloads(workloads)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def stop_workloads(workloads)
|
46
|
+
workloads.each do |workload|
|
47
|
+
step("Stopping workload '#{workload}'") do
|
48
|
+
cp.set_workload_suspend(workload, true)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
wait_for_workloads_not_ready(workloads) if config.options[:wait]
|
53
|
+
end
|
54
|
+
|
55
|
+
def stop_replica(workload, replica)
|
56
|
+
step("Stopping replica '#{replica}'", retry_on_failure: true) do
|
57
|
+
cp.stop_workload_replica(workload, replica, location: config.location)
|
58
|
+
end
|
59
|
+
|
60
|
+
wait_for_replica_not_ready(workload, replica) if config.options[:wait]
|
61
|
+
end
|
62
|
+
|
63
|
+
def wait_for_workloads_not_ready(workloads)
|
64
|
+
progress.puts
|
65
|
+
|
66
|
+
workloads.each do |workload|
|
67
|
+
step("Waiting for workload '#{workload}' to not be ready", retry_on_failure: true) do
|
68
|
+
cp.workload_deployments_ready?(workload, location: config.location, expected_status: false)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def wait_for_replica_not_ready(workload, replica)
|
74
|
+
progress.puts
|
75
|
+
|
76
|
+
step("Waiting for replica '#{replica}' to not be ready", retry_on_failure: true) do
|
77
|
+
result = cp.fetch_workload_replicas(workload, location: config.location)
|
78
|
+
!result["items"].include?(replica)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Command
|
4
|
+
class PsWait < Base
|
5
|
+
NAME = "ps:wait"
|
6
|
+
OPTIONS = [
|
7
|
+
app_option(required: true),
|
8
|
+
workload_option,
|
9
|
+
location_option
|
10
|
+
].freeze
|
11
|
+
DESCRIPTION = "Waits for workloads in app to be ready after re-deployment"
|
12
|
+
LONG_DESCRIPTION = <<~DESC
|
13
|
+
- Waits for workloads in app to be ready after re-deployment
|
14
|
+
DESC
|
15
|
+
EXAMPLES = <<~EX
|
16
|
+
```sh
|
17
|
+
# Waits for all workloads in app.
|
18
|
+
cpflow ps:wait -a $APP_NAME
|
19
|
+
|
20
|
+
# Waits for a specific workload in app.
|
21
|
+
cpflow ps:swait -a $APP_NAME -w $WORKLOAD_NAME
|
22
|
+
```
|
23
|
+
EX
|
24
|
+
|
25
|
+
def call # rubocop:disable Metrics/MethodLength
|
26
|
+
@workloads = [config.options[:workload]] if config.options[:workload]
|
27
|
+
@workloads ||= config[:app_workloads] + config[:additional_workloads]
|
28
|
+
|
29
|
+
@workloads.reverse_each do |workload|
|
30
|
+
if cp.workload_suspended?(workload)
|
31
|
+
progress.puts("Workload '#{workload}' is suspended. Skipping...")
|
32
|
+
else
|
33
|
+
step("Waiting for workload '#{workload}' to be ready", retry_on_failure: true) do
|
34
|
+
cp.workload_deployments_ready?(workload, location: config.location, expected_status: true)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|