cpflow 4.0.0 → 4.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b703678fbaeb6b6300473a8f4529a7c9e62dcc2439ab22cae79abe1a01f83fad
4
- data.tar.gz: 9a75cf47df352fce3efe005ebc283d1581befdc5185d8628de8eca0b3df70c5a
3
+ metadata.gz: 692a5e1a11ae3d172e2adf9cf4da3573f6fa639e69b49d797c8b09d619d1ccb4
4
+ data.tar.gz: e6a66549f0e5bb67816205a28a6d2df0cd5f8b53a2bf1d2e003985a19da5ce0e
5
5
  SHA512:
6
- metadata.gz: 26cff99f48b33180c93f3d90d1f726c766f7cf49ed983bb1079cc4260affa95f1e8d8596f21817f910f2abead651fca7856284245d2cb8ae936b100fde7507e9
7
- data.tar.gz: aa7160f2cb036ccff1aa99484a5566102331f07cabf0afe6e5fe4f592a0a1de68cb1c205706a694a91e10bc5ff5f2104dd5edc9d235985fd67e136f3a4b2b1f7
6
+ metadata.gz: 5c855e9908cc2b7cd014b51f7196cabec19f2f950a98c5b9116dfb2fc68b5cd703492864eb4ec9ed9b016ea18d23801feadfe5ea57321e90001fcbd99c7e04d2
7
+ data.tar.gz: 270f3f96e3a4a61a3875f9410e7116adfe5dc0a08bfccac43ff66b329da629e167a253986444e61c4832088afc65090e50d14da8b00c7a4e57d92ba642835e32
data/.rubocop.yml CHANGED
@@ -20,3 +20,7 @@ RSpec/ExampleLength:
20
20
 
21
21
  RSpec/MultipleExpectations:
22
22
  Enabled: false
23
+
24
+ RSpec/NestedGroups:
25
+ Enabled: true
26
+ Max: 5
data/CHANGELOG.md CHANGED
@@ -14,6 +14,19 @@ Changes since the last non-beta release.
14
14
 
15
15
  _Please add entries here for your pull requests that have not yet been released._
16
16
 
17
+ ## [4.1.0] - 2024-12-17
18
+
19
+ ### Fixed
20
+
21
+ - Fixed issue where `run` command fails when runner workload has ENV but original workload does not. [PR 227](https://github.com/shakacode/control-plane-flow/pull/227) by [Rafael Gomes](https://github.com/rafaelgomesxyz).
22
+ - Fixed potential infinite loop that could occur for a command if one of the execution steps fails and gets stuck. [PR 217](https://github.com/shakacode/control-plane-flow/pull/217) by [Zakir Dzhamaliddinov](https://github.com/zzaakiirr).
23
+ - Fixed issue where app cannot be deleted because one of the workloads has a volumeset in-use. [PR 245](https://github.com/shakacode/control-plane-flow/pull/245) by [Zakir Dzhamaliddinov](https://github.com/zzaakiirr).
24
+ - Fixed `resolv` may be not properly required [PR 250](https://github.com/shakacode/control-plane-flow/pull/250) by [Sergey Tarasov](https://github.com/dzirtusss).
25
+
26
+ ### Added
27
+
28
+ - Added `--docker-context` option to `build-image` command. [PR 250](https://github.com/shakacode/control-plane-flow/pull/250) by [Sergey Tarasov](https://github.com/dzirtusss).
29
+
17
30
 
18
31
  ## [4.0.0] - 2024-08-21
19
32
 
@@ -263,7 +276,8 @@ Deprecated `cpl` gem. New gem is `cpflow`.
263
276
 
264
277
  First release.
265
278
 
266
- [Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v4.0.0...HEAD
279
+ [Unreleased]: https://github.com/shakacode/control-plane-flow/compare/v4.1.0...HEAD
280
+ [4.1.0]: https://github.com/shakacode/control-plane-flow/compare/v4.0.0...v4.1.0
267
281
  [4.0.0]: https://github.com/shakacode/control-plane-flow/compare/v3.0.1...v4.0.0
268
282
  [3.0.1]: https://github.com/shakacode/control-plane-flow/compare/v3.0.0...v3.0.1
269
283
  [3.0.0]: https://github.com/shakacode/control-plane-flow/compare/v2.2.4...v3.0.0
data/COMM-LICENSE.txt ADDED
@@ -0,0 +1,9 @@
1
+ Control Plane Flow - Commercial Licensing
2
+
3
+ Control Plane Flow is currently licensed under the GNU Lesser General Public License v3.0, which allows for broad use, including integration with proprietary software, as long as modifications to Control Plane Flow itself are open-sourced.
4
+
5
+ While there are no current commercial license offerings, ShakaCode LLC reserves the right to offer commercial licenses or additional options in the future. This may include support packages, premium features, or alternative licensing terms.
6
+
7
+ For any inquiries or expressions of interest in potential commercial licensing, please reach out to ShakaCode LLC at justin@shakacode.com.
8
+
9
+ You can find the full terms of the GNU Lesser General Public License v3.0 at <http://www.gnu.org/licenses/lgpl-3.0.html>.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpflow (4.0.0)
4
+ cpflow (4.1.0)
5
5
  dotenv (~> 2.8.1)
6
6
  jwt (~> 2.8.1)
7
7
  psych (~> 5.1.0)
data/LICENSE CHANGED
@@ -1,21 +1,8 @@
1
- MIT License
1
+ Copyright (c) 2024 ShakaCode LLC
2
2
 
3
- Copyright (c) 2022 ShakaCode
3
+ Control Plane Flow is an Open Source project licensed under the terms of
4
+ the LGPLv3 license. Please see <http://www.gnu.org/licenses/lgpl-3.0.html> for license text.
4
5
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
6
+ Control Plane Flow may offer commercial-friendly licensing options in the future.
7
+ You can find any applicable commercial license terms in COMM-LICENSE.txt.
8
+ For inquiries, please contact justin@shakacode.com.
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # The power of Kubernetes with the ease of Heroku!
2
2
 
3
- <meta name="author" content="Justin Gordon and Sergey Tarasov">
4
- <meta name="description" content="Instructions on how to migrate from Heroku to Control Plane and a CLI called cpflow to make it easier.">
5
- <meta name="copyright" content="ShakaCode, 2023">
6
- <meta name="keywords" content="Control Plane, Heroku, Kubernetes, K8, Infrastructure">
3
+ <meta name="author" content="Justin Gordon and Sergey Tarasov" />
4
+ <meta name="description" content="Instructions on how to migrate from Heroku to Control Plane and a CLI called cpflow to make it easier." />
5
+ <meta name="copyright" content="ShakaCode, 2023" />
6
+ <meta name="keywords" content="Control Plane, Heroku, Kubernetes, K8, Infrastructure" />
7
7
  <meta name="google-site-verification" content="dIV4nMplcYl6YOKOaZMqgvdKXhLJ4cdYY6pS6e_YrPU" />
8
8
 
9
9
  [![RSpec](https://github.com/shakacode/control-plane-flow/actions/workflows/rspec.yml/badge.svg)](https://github.com/shakacode/control-plane-flow/actions/workflows/rspec.yml)
@@ -12,7 +12,9 @@
12
12
  [![Gem](https://badge.fury.io/rb/cpflow.svg)](https://badge.fury.io/rb/cpflow)
13
13
 
14
14
 
15
- Enable the [Heroku Flow](https://www.heroku.com/flow) deployment model with [Control Plane](https://shakacode.controlplane.com) using the `cpflow` gem.
15
+ Leverage the power of Kubernetes with the ease of Heroku! The `cpflow` gem enables simple CI configuration for Heroku-style "review apps," staging deployments, and seamless promotion from staging to production. This is similar to the the [Heroku Flow](https://www.heroku.com/flow) deployment model.
16
+
17
+ Follow the "convention over configuration" philosophy to streamline your deployment workflows and reduce complexity.
16
18
 
17
19
  ----
18
20
 
@@ -20,8 +22,8 @@ _If you need a free demo account for Control Plane (no CC required), you can con
20
22
 
21
23
  ---
22
24
 
23
- Be sure to see the [demo app](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane)
24
- If you would like to see the simple YAML configuration and setup,
25
+ Be sure to see the [demo app](https://github.com/shakacode/react-webpack-rails-tutorial/tree/master/.controlplane), which includes simple YAML configurations and setup for `cpflow`.
26
+
25
27
  Also, check [how the `cpflow` gem (this project) is used in the Github actions](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.github/actions/deploy-to-control-plane/action.yml).
26
28
  Here is a brief [video overview](https://www.youtube.com/watch?v=llaQoAV_6Iw).
27
29
 
@@ -33,11 +35,11 @@ Control Plane's `cpln` CLI.
33
35
  Heroku provides a UX and CLI that enables easy publishing of Ruby on Rails and other apps. This ease of use comes via
34
36
  many "Heroku" abstractions and naming conventions.
35
37
 
36
- Control Plane, on the other hand, gives you access to raw cloud computing power. However, you need to know precisely how
37
- to use it.
38
+ Control Plane provides access to raw cloud computing power but lacks the simple abstractions of Heroku. The `cpflow` CLI bridges this gap, delivering a streamlined and familiar experience for developers.
39
+
40
+ While this repository simplifies migration from Heroku, the `cpflow` CLI is versatile and can be used for new applications as well. It follows a **concept mapping** and **helper CLI** approach to streamline deployment workflows and minimize manual effort.
38
41
 
39
- To simplify migration to and usage of Control Plane for Heroku users, this repository provides a **concept mapping** and
40
- a **helper CLI** based on templates to save lots of day-to-day typing (and human errors).
42
+ Additionally, the documentation includes numerous examples and practical tips for teams transitioning from Heroku to Kubernetes, helping them make the most of Control Plane's advanced features.
41
43
 
42
44
  1. [Key Features](#key-features)
43
45
  2. [Concept Mapping](#concept-mapping)
@@ -58,8 +60,9 @@ a **helper CLI** based on templates to save lots of day-to-day typing (and human
58
60
 
59
61
  ## Key Features
60
62
 
61
- - A `cpflow` command to complement the default Control Plane `cpln` command with "Heroku style scripting." The Ruby source
62
- can serve as inspiration for your own scripts.
63
+ - The `cpflow` CLI complements the Control Plane `cpln` CLI, enabling "Heroku-style scripting" for review apps, staging, and production environments.
64
+ - Extensive Heroku-to-Control Plane migration examples included in the documentation.
65
+ - Convention-driven configuration to simplify workflows and reduce custom scripting requirements.
63
66
  - Easy to understand Heroku to Control Plane conventions in setup and naming.
64
67
  - **Safe, production-ready** equivalents of `heroku run` and `heroku run:detached` for Control Plane.
65
68
  - Automatic sequential release tagging for Docker images.
data/docs/commands.md CHANGED
@@ -1,4 +1,4 @@
1
- <!-- NOTE: This file is automatically generated by running `script/generate_commands_docs`. Do NOT edit it manually. -->
1
+ { /* Automatically Generated <!-- NOTE: This file is automatically generated by running `script/update_command_docs`. Do NOT edit it manually. --> */}
2
2
 
3
3
  ## Common Options
4
4
 
@@ -431,8 +431,8 @@ cpflow run -a $APP_NAME --entrypoint /app/alternative-entrypoint.sh -- rails db:
431
431
  - Creates an app and all its workloads
432
432
  - Specify the templates for the app and workloads through `setup_app_templates` in the `.controlplane/controlplane.yml` file
433
433
  - This should only be used for temporary apps like review apps, never for persistent apps like production or staging (to update workloads for those, use 'cpflow apply-template' instead)
434
- - Configures app to have org-level secrets with default name "{APP_PREFIX}-secrets"
435
- using org-level policy with default name "{APP_PREFIX}-secrets-policy" (names can be customized, see docs)
434
+ - Configures app to have org-level secrets with default name `"{APP_PREFIX}-secrets"`
435
+ using org-level policy with default name `"{APP_PREFIX}-secrets-policy"` (names can be customized, see docs)
436
436
  - Creates identity for secrets if it does not exist
437
437
  - Use `--skip-secrets-setup` to prevent the automatic setup of secrets,
438
438
  or set it through `skip_secrets_setup` in the `.controlplane/controlplane.yml` file
data/docs/postgres.md CHANGED
@@ -25,7 +25,7 @@ And if the database is small or it is a hobby app, this should not be looked any
25
25
  However, this is not acceptable for 99% of production apps as their databases are huge and maintenance time
26
26
  should be as small as possible.
27
27
 
28
- Rough timing for a 1Gb database can be (but your mileage may vary):
28
+ Rough timing for a 1Tb database can be (but your mileage may vary):
29
29
 
30
30
  - 2.5h creating Heroku backup
31
31
  - 0.5h downloading backup to EC2
@@ -52,7 +52,7 @@ The migration process with Bucardo looks as follows:
52
52
 
53
53
  Maintenance downtime here can be minutes not hours or days like in p1, but no free lunches - the process is more complex.
54
54
 
55
- Rough timing for a 1Gb database can be (but your mileage may vary):
55
+ Rough timing for a 1Tb database can be (but your mileage may vary):
56
56
 
57
57
  - whatever setup time, no hurry
58
58
  - 1.5 days for onetimecopy (in 1 thread) - DDL changes not allowed, but no downtime
data/lib/command/base.rb CHANGED
@@ -442,6 +442,17 @@ module Command
442
442
  }
443
443
  }
444
444
  end
445
+
446
+ def self.docker_context_option
447
+ {
448
+ name: :docker_context,
449
+ params: {
450
+ desc: "Path to the docker build context directory",
451
+ type: :string,
452
+ required: false
453
+ }
454
+ }
455
+ end
445
456
  # rubocop:enable Metrics/MethodLength
446
457
 
447
458
  def self.all_options
@@ -465,45 +476,50 @@ module Command
465
476
  $stderr
466
477
  end
467
478
 
468
- def step_error(error, abort_on_error: true)
469
- message = error.message
470
- if abort_on_error
471
- progress.puts(" #{Shell.color('failed!', :red)}\n\n")
472
- Shell.abort(message)
473
- else
474
- Shell.write_to_tmp_stderr(message)
475
- end
476
- end
477
-
478
- def step_finish(success)
479
+ def step_finish(success, abort_on_error: true)
479
480
  if success
480
481
  progress.puts(" #{Shell.color('done!', :green)}")
481
482
  else
482
483
  progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
484
+ exit(ExitCode::ERROR_DEFAULT) if abort_on_error
483
485
  end
484
486
  end
485
487
 
486
- def step(message, abort_on_error: true, retry_on_failure: false) # rubocop:disable Metrics/MethodLength
488
+ def step(message, abort_on_error: true, retry_on_failure: false, max_retry_count: 1000, wait: 1, &block) # rubocop:disable Metrics/MethodLength
487
489
  progress.print("#{message}...")
488
490
 
489
491
  Shell.use_tmp_stderr do
490
492
  success = false
491
493
 
492
494
  begin
493
- if retry_on_failure
494
- until (success = yield)
495
- progress.print(".")
496
- Kernel.sleep(1)
495
+ success =
496
+ if retry_on_failure
497
+ with_retry(max_retry_count: max_retry_count, wait: wait, &block)
498
+ else
499
+ yield
497
500
  end
498
- else
499
- success = yield
500
- end
501
501
  rescue RuntimeError => e
502
- step_error(e, abort_on_error: abort_on_error)
502
+ Shell.write_to_tmp_stderr(e.message)
503
503
  end
504
504
 
505
- step_finish(success)
505
+ step_finish(success, abort_on_error: abort_on_error)
506
+ end
507
+ end
508
+
509
+ def with_retry(max_retry_count:, wait:)
510
+ retry_count = 0
511
+ success = false
512
+
513
+ while !success && retry_count <= max_retry_count
514
+ success = yield
515
+ break if success
516
+
517
+ progress.print(".")
518
+ Kernel.sleep(wait)
519
+ retry_count += 1
506
520
  end
521
+
522
+ success
507
523
  end
508
524
 
509
525
  def cp
@@ -5,7 +5,8 @@ module Command
5
5
  NAME = "build-image"
6
6
  OPTIONS = [
7
7
  app_option(required: true),
8
- commit_option
8
+ commit_option,
9
+ docker_context_option
9
10
  ].freeze
10
11
  ACCEPTS_EXTRA_OPTIONS = true
11
12
  DESCRIPTION = "Builds and pushes the image to Control Plane"
@@ -34,9 +35,12 @@ module Command
34
35
  build_args = []
35
36
  build_args.push("GIT_COMMIT=#{commit}") if commit
36
37
 
38
+ docker_context = config.options[:docker_context] || config.app_dir
39
+
37
40
  cp.image_build(image_url, dockerfile: dockerfile,
38
41
  docker_args: config.args,
39
- build_args: build_args)
42
+ build_args: build_args,
43
+ docker_context: docker_context)
40
44
 
41
45
  push_path = "/org/#{config.org}/image/#{image_name}"
42
46
 
@@ -106,9 +106,9 @@ module Command
106
106
  def delete_volumesets
107
107
  @volumesets.each do |volumeset|
108
108
  step("Deleting volumeset '#{volumeset['name']}' from app '#{config.app}'") do
109
- # If the volumeset is attached to a workload, we need to delete the workload first
110
- workload = volumeset.dig("status", "usedByWorkload")&.split("/")&.last
111
- cp.delete_workload(workload) if workload
109
+ # If the volumeset is attached to workloads, we need to delete the workloads first
110
+ workloads = volumeset.dig("status", "workloadLinks")&.map { |workload_link| workload_link.split("/").last }
111
+ workloads&.each { |workload| cp.delete_workload(workload) }
112
112
 
113
113
  cp.delete_volumeset(volumeset["name"])
114
114
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "resolv"
4
+
3
5
  module Command
4
6
  class DeployImage < Base
5
7
  NAME = "deploy-image"
data/lib/command/run.rb CHANGED
@@ -207,7 +207,7 @@ module Command
207
207
  original_env_str = original_container_spec["env"]&.sort_by { |env| env["name"] }.to_s
208
208
  env_str = container_spec["env"]&.sort_by { |env| env["name"] }.to_s
209
209
  if original_env_str != env_str
210
- container_spec["env"] = original_container_spec["env"]
210
+ container_spec["env"] = original_container_spec["env"] || []
211
211
  should_update = true
212
212
  end
213
213
 
@@ -14,8 +14,8 @@ module Command
14
14
  - Creates an app and all its workloads
15
15
  - Specify the templates for the app and workloads through `setup_app_templates` in the `.controlplane/controlplane.yml` file
16
16
  - This should only be used for temporary apps like review apps, never for persistent apps like production or staging (to update workloads for those, use 'cpflow apply-template' instead)
17
- - Configures app to have org-level secrets with default name "{APP_PREFIX}-secrets"
18
- using org-level policy with default name "{APP_PREFIX}-secrets-policy" (names can be customized, see docs)
17
+ - Configures app to have org-level secrets with default name `"{APP_PREFIX}-secrets"`
18
+ using org-level policy with default name `"{APP_PREFIX}-secrets-policy"` (names can be customized, see docs)
19
19
  - Creates identity for secrets if it does not exist
20
20
  - Use `--skip-secrets-setup` to prevent the automatic setup of secrets,
21
21
  or set it through `skip_secrets_setup` in the `.controlplane/controlplane.yml` file
@@ -90,7 +90,7 @@ class Controlplane # rubocop:disable Metrics/ClassLength
90
90
  api.query_images(org: a_org, gvc: a_gvc, gvc_op_type: gvc_op)
91
91
  end
92
92
 
93
- def image_build(image, dockerfile:, docker_args: [], build_args: [])
93
+ def image_build(image, dockerfile:, docker_context:, docker_args: [], build_args: [])
94
94
  # https://docs.controlplane.com/guides/push-image#step-2
95
95
  # Might need to use `docker buildx build` if compatiblitity issues arise
96
96
  cmd = "docker build --platform=linux/amd64 -t #{image} -f #{dockerfile}"
@@ -98,7 +98,7 @@ class Controlplane # rubocop:disable Metrics/ClassLength
98
98
 
99
99
  cmd += " #{docker_args.join(' ')}" if docker_args.any?
100
100
  build_args.each { |build_arg| cmd += " --build-arg #{build_arg}" }
101
- cmd += " #{config.app_dir}"
101
+ cmd += " #{docker_context}"
102
102
 
103
103
  perform!(cmd)
104
104
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cpflow
4
- VERSION = "4.0.0"
4
+ VERSION = "4.1.0"
5
5
  MIN_CPLN_VERSION = "3.1.0"
6
6
  end
@@ -44,7 +44,7 @@ commands_str = commands_str_arr.join("\n\n")
44
44
  file_path = "#{__dir__}/../docs/commands.md"
45
45
  file_data =
46
46
  <<~DATA
47
- <!-- NOTE: This file is automatically generated by running `script/generate_commands_docs`. Do NOT edit it manually. -->
47
+ { /* Automatically Generated <!-- NOTE: This file is automatically generated by running `script/update_command_docs`. Do NOT edit it manually. --> */}
48
48
 
49
49
  ## Common Options
50
50
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.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: 2024-08-22 00:00:00.000000000 Z
12
+ date: 2024-12-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dotenv
@@ -87,6 +87,7 @@ files:
87
87
  - ".rubocop.yml"
88
88
  - ".simplecov_spawn.rb"
89
89
  - CHANGELOG.md
90
+ - COMM-LICENSE.txt
90
91
  - CONTRIBUTING.md
91
92
  - Gemfile
92
93
  - Gemfile.lock