mrsk 0.0.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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