mrsk 0.0.3 → 0.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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +193 -77
  3. data/bin/mrsk +5 -0
  4. data/lib/mrsk/cli/accessory.rb +85 -0
  5. data/lib/mrsk/cli/app.rb +123 -0
  6. data/lib/mrsk/cli/base.rb +48 -0
  7. data/lib/mrsk/cli/build.rb +53 -0
  8. data/lib/mrsk/cli/main.rb +110 -0
  9. data/lib/mrsk/cli/prune.rb +19 -0
  10. data/lib/mrsk/cli/registry.rb +18 -0
  11. data/lib/mrsk/cli/server.rb +8 -0
  12. data/lib/mrsk/cli/templates/deploy.yml +17 -0
  13. data/lib/mrsk/cli/traefik.rb +77 -0
  14. data/lib/mrsk/cli.rb +9 -0
  15. data/lib/mrsk/commander.rb +45 -5
  16. data/lib/mrsk/commands/accessory.rb +61 -0
  17. data/lib/mrsk/commands/app.rb +50 -10
  18. data/lib/mrsk/commands/base.rb +13 -9
  19. data/lib/mrsk/commands/builder/base.rb +26 -0
  20. data/lib/mrsk/commands/builder/multiarch/remote.rb +12 -4
  21. data/lib/mrsk/commands/builder/multiarch.rb +17 -9
  22. data/lib/mrsk/commands/builder/native/remote.rb +71 -0
  23. data/lib/mrsk/commands/builder/native.rb +3 -7
  24. data/lib/mrsk/commands/builder.rb +11 -7
  25. data/lib/mrsk/commands/traefik.rb +13 -3
  26. data/lib/mrsk/configuration/accessory.rb +60 -0
  27. data/lib/mrsk/configuration/role.rb +46 -14
  28. data/lib/mrsk/configuration.rb +86 -43
  29. data/lib/mrsk/sshkit_with_ext.rb +12 -0
  30. data/lib/mrsk/utils.rb +29 -0
  31. data/lib/mrsk/version.rb +1 -1
  32. data/lib/mrsk.rb +0 -1
  33. metadata +40 -18
  34. data/lib/mrsk/engine.rb +0 -4
  35. data/lib/tasks/mrsk/app.rake +0 -97
  36. data/lib/tasks/mrsk/build.rake +0 -52
  37. data/lib/tasks/mrsk/mrsk.rake +0 -37
  38. data/lib/tasks/mrsk/prune.rake +0 -18
  39. data/lib/tasks/mrsk/registry.rake +0 -16
  40. data/lib/tasks/mrsk/server.rake +0 -11
  41. data/lib/tasks/mrsk/setup.rb +0 -6
  42. data/lib/tasks/mrsk/templates/deploy.yml +0 -24
  43. data/lib/tasks/mrsk/templates/mrsk +0 -8
  44. data/lib/tasks/mrsk/traefik.rake +0 -41
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mrsk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-13 00:00:00.000000000 Z
11
+ date: 2023-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: railties
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 7.0.0
19
+ version: '7.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 7.0.0
26
+ version: '7.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sshkit
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,40 +38,62 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.21'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.2'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
41
55
  description:
42
56
  email: dhh@hey.com
43
- executables: []
57
+ executables:
58
+ - mrsk
44
59
  extensions: []
45
60
  extra_rdoc_files: []
46
61
  files:
47
62
  - MIT-LICENSE
48
63
  - README.md
64
+ - bin/mrsk
49
65
  - lib/mrsk.rb
66
+ - lib/mrsk/cli.rb
67
+ - lib/mrsk/cli/accessory.rb
68
+ - lib/mrsk/cli/app.rb
69
+ - lib/mrsk/cli/base.rb
70
+ - lib/mrsk/cli/build.rb
71
+ - lib/mrsk/cli/main.rb
72
+ - lib/mrsk/cli/prune.rb
73
+ - lib/mrsk/cli/registry.rb
74
+ - lib/mrsk/cli/server.rb
75
+ - lib/mrsk/cli/templates/deploy.yml
76
+ - lib/mrsk/cli/traefik.rb
50
77
  - lib/mrsk/commander.rb
51
78
  - lib/mrsk/commands.rb
79
+ - lib/mrsk/commands/accessory.rb
52
80
  - lib/mrsk/commands/app.rb
53
81
  - lib/mrsk/commands/base.rb
54
82
  - lib/mrsk/commands/builder.rb
83
+ - lib/mrsk/commands/builder/base.rb
55
84
  - lib/mrsk/commands/builder/multiarch.rb
56
85
  - lib/mrsk/commands/builder/multiarch/remote.rb
57
86
  - lib/mrsk/commands/builder/native.rb
87
+ - lib/mrsk/commands/builder/native/remote.rb
58
88
  - lib/mrsk/commands/prune.rb
59
89
  - lib/mrsk/commands/registry.rb
60
90
  - lib/mrsk/commands/traefik.rb
61
91
  - lib/mrsk/configuration.rb
92
+ - lib/mrsk/configuration/accessory.rb
62
93
  - lib/mrsk/configuration/role.rb
63
- - lib/mrsk/engine.rb
94
+ - lib/mrsk/sshkit_with_ext.rb
95
+ - lib/mrsk/utils.rb
64
96
  - lib/mrsk/version.rb
65
- - lib/tasks/mrsk/app.rake
66
- - lib/tasks/mrsk/build.rake
67
- - lib/tasks/mrsk/mrsk.rake
68
- - lib/tasks/mrsk/prune.rake
69
- - lib/tasks/mrsk/registry.rake
70
- - lib/tasks/mrsk/server.rake
71
- - lib/tasks/mrsk/setup.rb
72
- - lib/tasks/mrsk/templates/deploy.yml
73
- - lib/tasks/mrsk/templates/mrsk
74
- - lib/tasks/mrsk/traefik.rake
75
97
  homepage: https://github.com/rails/mrsk
76
98
  licenses:
77
99
  - MIT
@@ -94,5 +116,5 @@ requirements: []
94
116
  rubygems_version: 3.4.1
95
117
  signing_key:
96
118
  specification_version: 4
97
- summary: Deploy Docker containers with zero downtime to any host.
119
+ summary: Deploy Rails apps in containers to servers running Docker with zero downtime.
98
120
  test_files: []
data/lib/mrsk/engine.rb DELETED
@@ -1,4 +0,0 @@
1
- module Mrsk
2
- class Engine < ::Rails::Engine
3
- end
4
- end
@@ -1,97 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- namespace :app do
5
- desc "Run app on servers (or start them if they've already been run)"
6
- task :run do
7
- MRSK.config.roles.each do |role|
8
- on(role.hosts) do |host|
9
- begin
10
- execute *MRSK.app.run(role: role.name)
11
- rescue SSHKit::Command::Failed => e
12
- if e.message =~ /already in use/
13
- error "Container with same version already deployed on #{host}, starting that instead"
14
- execute *MRSK.app.start, host: host
15
- else
16
- raise
17
- end
18
- end
19
- end
20
- end
21
- end
22
-
23
- desc "Start existing app on servers (use VERSION=<git-hash> to designate which version)"
24
- task :start do
25
- on(MRSK.config.hosts) { execute *MRSK.app.start, raise_on_non_zero_exit: false }
26
- end
27
-
28
- desc "Stop app on servers"
29
- task :stop do
30
- on(MRSK.config.hosts) { execute *MRSK.app.stop, raise_on_non_zero_exit: false }
31
- end
32
-
33
- desc "Start app on servers (use VERSION=<git-hash> to designate which version)"
34
- task restart: %i[ stop start ]
35
-
36
- desc "Display information about app containers"
37
- task :info do
38
- on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.info) + "\n\n" }
39
- end
40
-
41
- desc "Execute a custom task on servers passed in as CMD='bin/rake some:task'"
42
- task :exec do
43
- on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.exec(ENV["CMD"])) + "\n\n" }
44
- end
45
-
46
- desc "Start Rails Console on primary host"
47
- task :console do
48
- puts "Launching Rails console on #{MRSK.config.primary_host}..."
49
- exec app.console
50
- end
51
-
52
- namespace :exec do
53
- desc "Execute Rails command on servers, like CMD='runner \"puts %(Hello World)\""
54
- task :rails do
55
- on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.exec("bin/rails", ENV["CMD"])) + "\n\n" }
56
- end
57
-
58
- desc "Execute a custom task on the first defined server"
59
- task :once do
60
- on(MRSK.config.primary_host) { puts capture(*MRSK.app.exec(ENV["CMD"])) }
61
- end
62
-
63
- namespace :once do
64
- desc "Execute Rails command on the first defined server, like CMD='runner \"puts %(Hello World)\""
65
- task :rails do
66
- on(MRSK.config.primary_host) { puts capture(*MRSK.app.exec("bin/rails", ENV["CMD"])) }
67
- end
68
- end
69
- end
70
-
71
- desc "List all the app containers currently on servers"
72
- task :containers do
73
- on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.list_containers) + "\n\n" }
74
- end
75
-
76
- desc "Show last 100 log lines from app on servers"
77
- task :logs do
78
- # FIXME: Catch when app containers aren't running
79
- on(MRSK.config.hosts) { |host| puts "App Host: #{host}\n" + capture(*MRSK.app.logs) + "\n\n" }
80
- end
81
-
82
- desc "Remove app containers and images from servers"
83
- task remove: %w[ remove:containers remove:images ]
84
-
85
- namespace :remove do
86
- desc "Remove app containers from servers"
87
- task :containers do
88
- on(MRSK.config.hosts) { execute *MRSK.app.remove_containers }
89
- end
90
-
91
- desc "Remove app images from servers"
92
- task :images do
93
- on(MRSK.config.hosts) { execute *MRSK.app.remove_images }
94
- end
95
- end
96
- end
97
- end
@@ -1,52 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- namespace :build do
5
- desc "Deliver a newly built app image to servers"
6
- task deliver: %i[ push pull ]
7
-
8
- desc "Build locally and push app image to registry"
9
- task :push do
10
- run_locally do
11
- begin
12
- debug "Using builder: #{MRSK.builder.name}"
13
- info "Building image may take a while (run with VERBOSE=1 for progress logging)"
14
- execute *MRSK.builder.push
15
- rescue SSHKit::Command::Failed => e
16
- error "Missing compatible builder, so creating a new one first"
17
- execute *MRSK.builder.create
18
- execute *MRSK.builder.push
19
- end
20
- end unless ENV["VERSION"]
21
- end
22
-
23
- desc "Pull app image from the registry onto servers"
24
- task :pull do
25
- on(MRSK.config.hosts) { execute *MRSK.builder.pull }
26
- end
27
-
28
- desc "Create a local build setup"
29
- task :create do
30
- run_locally do
31
- debug "Using builder: #{MRSK.builder.name}"
32
- execute *MRSK.builder.create
33
- end
34
- end
35
-
36
- desc "Remove local build setup"
37
- task :remove do
38
- run_locally do
39
- debug "Using builder: #{MRSK.builder.name}"
40
- execute *MRSK.builder.remove
41
- end
42
- end
43
-
44
- desc "Show the name of the configured builder"
45
- task :info do
46
- run_locally do
47
- puts "Builder: #{MRSK.builder.name} (#{MRSK.builder.target.class.name})"
48
- puts capture(*MRSK.builder.info)
49
- end
50
- end
51
- end
52
- end
@@ -1,37 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- desc "Deploy app for the first time to a fresh server"
5
- task fresh: %w[ server:bootstrap registry:login build:deliver traefik:run app:stop app:run ]
6
-
7
- desc "Push the latest version of the app, ensure Traefik is running, then restart app"
8
- task deploy: %w[ registry:login build:deliver traefik:run app:stop app:run prune ]
9
-
10
- desc "Rollback to VERSION=x that was already run as a container on servers"
11
- task rollback: %w[ app:restart ]
12
-
13
- desc "Display information about Traefik and app containers"
14
- task info: %w[ traefik:info app:info ]
15
-
16
- desc "Create config stub in config/deploy.yml"
17
- task :init do
18
- require "fileutils"
19
-
20
- if (deploy_file = Rails.root.join("config/deploy.yml")).exist?
21
- puts "Config file already exists in config/deploy.yml (remove first to create a new one)"
22
- else
23
- FileUtils.cp_r Pathname.new(File.expand_path("templates/deploy.yml", __dir__)), deploy_file
24
- puts "Created configuration file in config/deploy.yml"
25
- end
26
-
27
- if (binstub = Rails.root.join("bin/mrsk")).exist?
28
- puts "Binstub already exists in bin/mrsk (remove first to create a new one)"
29
- else
30
- FileUtils.cp_r Pathname.new(File.expand_path("templates/mrsk", __dir__)), binstub
31
- puts "Created binstub file in bin/mrsk"
32
- end
33
- end
34
-
35
- desc "Remove Traefik, app, and registry session from servers"
36
- task remove: %w[ traefik:remove app:remove registry:logout ]
37
- end
@@ -1,18 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- desc "Prune unused images and stopped containers"
5
- task prune: %w[ prune:containers prune:images ]
6
-
7
- namespace :prune do
8
- desc "Prune unused images older than 30 days"
9
- task :images do
10
- on(MRSK.config.hosts) { MRSK.verbosity(:debug) { execute *MRSK.prune.images } }
11
- end
12
-
13
- desc "Prune stopped containers for the service older than 3 days"
14
- task :containers do
15
- on(MRSK.config.hosts) { MRSK.verbosity(:debug) { execute *MRSK.prune.containers } }
16
- end
17
- end
18
- end
@@ -1,16 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- namespace :registry do
5
- desc "Login to the registry locally and remotely"
6
- task :login do
7
- run_locally { execute *MRSK.registry.login }
8
- on(MRSK.config.hosts) { execute *MRSK.registry.login }
9
- end
10
-
11
- desc "Logout of the registry remotely"
12
- task :logout do
13
- on(MRSK.config.hosts) { execute *MRSK.registry.logout }
14
- end
15
- end
16
- end
@@ -1,11 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- namespace :server do
5
- desc "Setup Docker on the remote servers"
6
- task :bootstrap do
7
- # FIXME: Detect when apt-get is not available and use the appropriate alternative
8
- on(MRSK.config.hosts) { execute "apt-get install docker.io -y" }
9
- end
10
- end
11
- end
@@ -1,6 +0,0 @@
1
- require "sshkit"
2
- require "sshkit/dsl"
3
-
4
- include SSHKit::DSL
5
-
6
- MRSK = Mrsk::Commander.new config_file: Rails.root.join("config/deploy.yml"), verbose: ENV["VERBOSE"]
@@ -1,24 +0,0 @@
1
- # Name of your application will be used for uniquely configuring Traefik and app containers.
2
- # Your Dockerfile should set LABEL service=the-same-value to ensure image pruning works.
3
- service: my-app
4
-
5
- # Name of the container image
6
- image: user/my-app
7
-
8
- # All the servers targeted for deploy. You can reference a single server for a command by using SERVERS=192.168.0.1
9
- servers:
10
- - 192.168.0.1
11
-
12
- # The following envs are made available to the container when started
13
- env:
14
- # Remember never to put passwords or tokens directly into this file, use encrypted credentials
15
- # REDIS_URL: redis://x/y
16
-
17
- # Where your images will be hosted
18
- registry:
19
- # Specify the registry server, if you're not using Docker Hub
20
- # server: registry.digitalocean.com / ghcr.io / ...
21
-
22
- # Set credentials with bin/rails credentials:edit
23
- username: my-user
24
- password: my-password-should-go-in-credentials
@@ -1,8 +0,0 @@
1
- #!/bin/bash
2
-
3
- if [ "${*}" == "" ]; then
4
- # Improve so list matches
5
- exec bin/rake -T mrsk
6
- else
7
- exec bin/rake "mrsk:$@"
8
- fi
@@ -1,41 +0,0 @@
1
- require_relative "setup"
2
-
3
- namespace :mrsk do
4
- namespace :traefik do
5
- desc "Run Traefik on servers"
6
- task :run do
7
- on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.run, raise_on_non_zero_exit: false }
8
- end
9
-
10
- desc "Start existing Traefik on servers"
11
- task :start do
12
- on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.start, raise_on_non_zero_exit: false }
13
- end
14
-
15
- desc "Stop Traefik on servers"
16
- task :stop do
17
- on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.stop, raise_on_non_zero_exit: false }
18
- end
19
-
20
- desc "Restart Traefik on servers"
21
- task restart: %i[ stop start ]
22
-
23
- desc "Display information about Traefik containers from servers"
24
- task :info do
25
- on(MRSK.config.role(:web).hosts) { |host| puts "Traefik Host: #{host}\n" + capture(*MRSK.traefik.info) + "\n\n" }
26
- end
27
-
28
- desc "Show last 100 log lines from Traefik on servers"
29
- task :logs do
30
- on(MRSK.config.hosts) { |host| puts "Traefik Host: #{host}\n" + capture(*MRSK.traefik.logs) + "\n\n" }
31
- end
32
-
33
- desc "Remove Traefik container and image from servers"
34
- task remove: %i[ stop ] do
35
- on(MRSK.config.role(:web).hosts) do
36
- execute *MRSK.traefik.remove_container
37
- execute *MRSK.traefik.remove_image
38
- end
39
- end
40
- end
41
- end