kitsune-kit 0.3.0 → 0.4.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/README.md +1 -0
- data/lib/kitsune/blueprints/.env.template +5 -0
- data/lib/kitsune/kit/ansi_color.rb +78 -0
- data/lib/kitsune/kit/cli.rb +9 -1
- data/lib/kitsune/kit/commands/bootstrap.rb +15 -7
- data/lib/kitsune/kit/commands/dns.rb +112 -0
- data/lib/kitsune/kit/commands/ssh.rb +46 -0
- data/lib/kitsune/kit/defaults.rb +3 -4
- data/lib/kitsune/kit/env_loader.rb +2 -2
- data/lib/kitsune/kit/provisioner.rb +1 -3
- data/lib/kitsune/kit/version.rb +1 -1
- metadata +5 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2860b56f9307be49ac06572e05cdf79e02bf76946262e64651d36c729505c8a8
|
4
|
+
data.tar.gz: c38a154d06774e6755dfec97f35a75d4ad2208b262ac37bb3ce20a25612836a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45ca3cd5d65502bb6c4e2fbdfa965152426d19bb732812651aee0957988d05eff5fe93432758825120e9ac2f20d8041afee8f7d34ac80aab438931c6948c15ad
|
7
|
+
data.tar.gz: f53ede98dd9cbf482e42ed91530cd07ddba5ed1744df1fcc46a92e6e5797f9629180057ff1a5e53cd80987f2ef0892d41400caff2b3a51273310b1676e9f93c5
|
data/README.md
CHANGED
@@ -18,6 +18,7 @@
|
|
18
18
|
- ♻️ Enables automatic security updates (unattended-upgrades)
|
19
19
|
- 💾 Configures swap space for better performance
|
20
20
|
- 📊 Installs [DigitalOcean monitoring agent](https://docs.digitalocean.com/products/monitoring/how-to/install-agent/)
|
21
|
+
- 🌐 **Automatically links** domains or subdomains (A records) to your server using DigitalOcean DNS
|
21
22
|
- 🐳 Installs and configures Docker Engine and private networking
|
22
23
|
- 🐘 Deploys PostgreSQL via Docker Compose with healthcheck
|
23
24
|
- 🗄️ Deploys Redis via Docker Compose with healthcheck
|
@@ -7,6 +7,11 @@ IMAGE=
|
|
7
7
|
SSH_KEY_ID=
|
8
8
|
TAG_NAME=
|
9
9
|
ENABLE_DO_METRICS=true
|
10
|
+
# If you want DNS records to be created automatically, set the following variables:
|
11
|
+
# DOMAIN_NAMES=example.com,test.example.org # (optional, comma-separated list of domain names to add to the droplet)
|
12
|
+
# DNS_TTL=3600 # (optional, time-to-live for DNS records in seconds, default is 3600)
|
13
|
+
# Check the DigitalOcean documentation for more information on domain names:
|
14
|
+
# https://docs.digitalocean.com/products/networking/dns/getting-started/dns-registrars/
|
10
15
|
|
11
16
|
# SSH
|
12
17
|
SSH_KEY_PATH=
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module AnsiColor
|
2
|
+
COLORS = {
|
3
|
+
black: 30,
|
4
|
+
red: 31,
|
5
|
+
green: 32,
|
6
|
+
yellow: 33,
|
7
|
+
blue: 34,
|
8
|
+
magenta: 35,
|
9
|
+
cyan: 36,
|
10
|
+
white: 37,
|
11
|
+
|
12
|
+
light_black: 90,
|
13
|
+
light_red: 91,
|
14
|
+
light_green: 92,
|
15
|
+
light_yellow: 93,
|
16
|
+
light_blue: 94,
|
17
|
+
light_magenta: 95,
|
18
|
+
light_cyan: 96,
|
19
|
+
light_white: 97
|
20
|
+
}
|
21
|
+
|
22
|
+
BACKGROUNDS = {
|
23
|
+
black: 40,
|
24
|
+
red: 41,
|
25
|
+
green: 42,
|
26
|
+
yellow: 43,
|
27
|
+
blue: 44,
|
28
|
+
magenta: 45,
|
29
|
+
cyan: 46,
|
30
|
+
white: 47,
|
31
|
+
|
32
|
+
light_black: 100,
|
33
|
+
light_red: 101,
|
34
|
+
light_green: 102,
|
35
|
+
light_yellow: 103,
|
36
|
+
light_blue: 104,
|
37
|
+
light_magenta: 105,
|
38
|
+
light_cyan: 106,
|
39
|
+
light_white: 107
|
40
|
+
}
|
41
|
+
|
42
|
+
STYLES = {
|
43
|
+
bold: 1,
|
44
|
+
italic: 3,
|
45
|
+
underline: 4
|
46
|
+
}
|
47
|
+
|
48
|
+
def self.colorize(text, color: nil, background: nil, style: nil)
|
49
|
+
codes = []
|
50
|
+
codes << COLORS[color] if color
|
51
|
+
codes << BACKGROUNDS[background] if background
|
52
|
+
codes << STYLES[style] if style
|
53
|
+
|
54
|
+
raise ArgumentError, "No valid formatting options given" if codes.empty?
|
55
|
+
|
56
|
+
"\e[#{codes.join(';')}m#{text}\e[0m"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.demo
|
60
|
+
puts "Text Colors:"
|
61
|
+
COLORS.each_key do |color|
|
62
|
+
puts colorize(" #{color.to_s.ljust(15)}", color: color)
|
63
|
+
end
|
64
|
+
|
65
|
+
puts "\nBackground Colors:"
|
66
|
+
BACKGROUNDS.each_key do |bg|
|
67
|
+
puts colorize(" #{bg.to_s.ljust(15)}", background: bg)
|
68
|
+
end
|
69
|
+
|
70
|
+
puts "\nStyles:"
|
71
|
+
STYLES.each_key do |style|
|
72
|
+
puts colorize(" #{style.to_s.ljust(15)}", color: :white, style: style)
|
73
|
+
end
|
74
|
+
|
75
|
+
puts "\nCombined Example:"
|
76
|
+
puts colorize(" bold green on light_black ", color: :green, background: :light_black, style: :bold)
|
77
|
+
end
|
78
|
+
end
|
data/lib/kitsune/kit/cli.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "thor"
|
2
|
-
|
2
|
+
require_relative "ansi_color"
|
3
3
|
require_relative "env_loader"
|
4
4
|
require_relative "commands/init"
|
5
5
|
require_relative "commands/switch_env"
|
6
6
|
require_relative "commands/provision"
|
7
|
+
require_relative "commands/dns"
|
7
8
|
require_relative "commands/setup_user"
|
8
9
|
require_relative "commands/setup_firewall"
|
9
10
|
require_relative "commands/setup_unattended"
|
@@ -16,6 +17,7 @@ require_relative "commands/postinstall_docker"
|
|
16
17
|
require_relative "commands/bootstrap_docker"
|
17
18
|
require_relative "commands/setup_postgres_docker"
|
18
19
|
require_relative "commands/setup_redis_docker"
|
20
|
+
require_relative "commands/ssh"
|
19
21
|
|
20
22
|
module Kitsune
|
21
23
|
module Kit
|
@@ -47,6 +49,9 @@ module Kitsune
|
|
47
49
|
desc "provision SUBCOMMAND", "Provisioning tasks"
|
48
50
|
subcommand "provision", Kitsune::Kit::Commands::Provision
|
49
51
|
|
52
|
+
desc "dns SUBCOMMAND", "Manage DNS"
|
53
|
+
subcommand "dns", Kitsune::Kit::Commands::Dns
|
54
|
+
|
50
55
|
desc "setup_user SUBCOMMAND", "Create or rollback deploy user on remote server"
|
51
56
|
subcommand "setup_user", Kitsune::Kit::Commands::SetupUser
|
52
57
|
|
@@ -82,6 +87,9 @@ module Kitsune
|
|
82
87
|
|
83
88
|
desc "setup_redis_docker SUBCOMMAND", "Setup Redis via Docker Compose on remote server"
|
84
89
|
subcommand "setup_redis_docker", Kitsune::Kit::Commands::SetupRedisDocker
|
90
|
+
|
91
|
+
desc "ssh connect", "SSH into the server"
|
92
|
+
subcommand "ssh", Kitsune::Kit::Commands::Ssh
|
85
93
|
end
|
86
94
|
end
|
87
95
|
end
|
@@ -44,6 +44,7 @@ module Kitsune
|
|
44
44
|
run_cli("setup_unattended create", droplet_ip, filled_options)
|
45
45
|
run_cli("setup_swap create", droplet_ip, filled_options)
|
46
46
|
run_cli("setup_do_metrics create", droplet_ip, filled_options)
|
47
|
+
run_cli("dns link", droplet_ip, filled_options.merge(domains: ENV["DOMAIN_NAMES"]))
|
47
48
|
end
|
48
49
|
|
49
50
|
def rollback_sequence(filled_options)
|
@@ -75,10 +76,11 @@ module Kitsune
|
|
75
76
|
run_cli("setup_user rollback", droplet_ip, filled_options)
|
76
77
|
|
77
78
|
unless filled_options[:keep_server]
|
79
|
+
run_cli("dns rollback", droplet_ip, filled_options.merge(domains: ENV["DOMAIN_NAMES"]))
|
78
80
|
say "▶️ Running: kitsune kit provision rollback", :blue
|
79
81
|
Kitsune::Kit::CLI.start(%w[provision rollback])
|
80
82
|
else
|
81
|
-
say "⏭️ Skipping droplet deletion (--keep-server enabled)", :yellow
|
83
|
+
say "⏭️ Skipping droplet deletion (--keep-server enabled), DNS rollback won't be executed", :yellow
|
82
84
|
end
|
83
85
|
end
|
84
86
|
|
@@ -99,12 +101,18 @@ module Kitsune
|
|
99
101
|
def run_cli(command, droplet_ip, filled_options)
|
100
102
|
say "\n▶️ Running: kitsune kit #{command} --server-ip #{droplet_ip}", :blue
|
101
103
|
subcommand, action = command.split(" ", 2)
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
"--ssh-key-path", filled_options[:ssh_key_path]
|
107
|
-
|
104
|
+
|
105
|
+
args = [subcommand, action, "--server-ip", droplet_ip]
|
106
|
+
|
107
|
+
if subcommand != "dns"
|
108
|
+
args += ["--ssh-port", filled_options[:ssh_port], "--ssh-key-path", filled_options[:ssh_key_path]]
|
109
|
+
end
|
110
|
+
|
111
|
+
if subcommand == "dns" && ENV["DOMAIN_NAMES"]
|
112
|
+
args += ["--domains", ENV["DOMAIN_NAMES"]]
|
113
|
+
end
|
114
|
+
|
115
|
+
Kitsune::Kit::CLI.start(args)
|
108
116
|
rescue SystemExit => e
|
109
117
|
abort "❌ Command failed: #{command} (exit #{e.status})"
|
110
118
|
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require "droplet_kit"
|
2
|
+
require "thor"
|
3
|
+
|
4
|
+
module Kitsune
|
5
|
+
module Kit
|
6
|
+
module Commands
|
7
|
+
class Dns < Thor
|
8
|
+
namespace "dns"
|
9
|
+
|
10
|
+
class_option :domains, type: :string, desc: "Comma-separated domain list (or from ENV['DOMAIN_NAMES'])"
|
11
|
+
class_option :server_ip, type: :string, required: true, desc: "IPv4 to assign to domain(s)"
|
12
|
+
class_option :ttl, type: :numeric, default: 3600, desc: "TTL in seconds for DNS records"
|
13
|
+
|
14
|
+
desc "link", "Link domains to a given IP using A records"
|
15
|
+
def link
|
16
|
+
validate_ip!
|
17
|
+
|
18
|
+
domains = resolve_domains
|
19
|
+
return if domains.empty?
|
20
|
+
|
21
|
+
ip = options[:server_ip]
|
22
|
+
ttl = ENV.fetch("DNS_TTL", options[:ttl]).to_i
|
23
|
+
|
24
|
+
client = DropletKit::Client.new(access_token: ENV.fetch("DO_API_TOKEN"))
|
25
|
+
|
26
|
+
domains.each do |fqdn|
|
27
|
+
parts = fqdn.split('.')
|
28
|
+
next if parts.size < 2
|
29
|
+
|
30
|
+
root_domain = parts[-2..].join('.')
|
31
|
+
subdomain = parts[0..-3].join('.')
|
32
|
+
name_for_a = subdomain.empty? ? "@" : subdomain
|
33
|
+
|
34
|
+
puts "\n🌐 Linking '#{fqdn}' to IP #{ip} (domain: #{root_domain}, record: #{name_for_a})"
|
35
|
+
|
36
|
+
records = client.domain_records.all(for_domain: root_domain)
|
37
|
+
existing = records.find { |r| r.type == "A" && r.name == name_for_a }
|
38
|
+
|
39
|
+
domain_record = DropletKit::DomainRecord.new(
|
40
|
+
type: "A",
|
41
|
+
name: name_for_a,
|
42
|
+
data: ip,
|
43
|
+
ttl: ttl
|
44
|
+
)
|
45
|
+
|
46
|
+
msg = "'#{AnsiColor.colorize(name_for_a, color: :green)}.#{AnsiColor.colorize(root_domain, color: :green)}' → #{AnsiColor.colorize(ip, color: :light_cyan)}"
|
47
|
+
if existing
|
48
|
+
client.domain_records.update(
|
49
|
+
domain_record,
|
50
|
+
for_domain: root_domain,
|
51
|
+
id: existing.id
|
52
|
+
)
|
53
|
+
puts "✅ Updated A record #{msg}"
|
54
|
+
else
|
55
|
+
client.domain_records.create(
|
56
|
+
domain_record,
|
57
|
+
for_domain: root_domain
|
58
|
+
)
|
59
|
+
puts "✅ Created A record #{msg}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "rollback", "Remove A records for the specified domains"
|
65
|
+
def rollback
|
66
|
+
domains = resolve_domains
|
67
|
+
return if domains.empty?
|
68
|
+
|
69
|
+
client = DropletKit::Client.new(access_token: ENV.fetch("DO_API_TOKEN"))
|
70
|
+
|
71
|
+
domains.each do |fqdn|
|
72
|
+
parts = fqdn.split('.')
|
73
|
+
next if parts.size < 2
|
74
|
+
|
75
|
+
root_domain = parts[-2..].join('.')
|
76
|
+
subdomain = parts[0..-3].join('.')
|
77
|
+
name_for_a = subdomain.empty? ? "@" : subdomain
|
78
|
+
|
79
|
+
puts "\n🗑️ Attempting to delete A record for '#{fqdn}' (domain: #{root_domain}, record: #{name_for_a})"
|
80
|
+
|
81
|
+
records = client.domain_records.all(for_domain: root_domain)
|
82
|
+
existing = records.find { |r| r.type == "A" && r.name == name_for_a }
|
83
|
+
|
84
|
+
if existing
|
85
|
+
client.domain_records.delete(for_domain: root_domain, id: existing.id)
|
86
|
+
puts "✅ Deleted A record '#{name_for_a}.#{root_domain}'"
|
87
|
+
else
|
88
|
+
puts "💡 No A record found for '#{name_for_a}.#{root_domain}', nothing to delete"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
no_commands do
|
94
|
+
def validate_ip!
|
95
|
+
if options[:server_ip].nil? || options[:server_ip].empty?
|
96
|
+
abort "❌ Missing required option: --server-ip"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def resolve_domains
|
101
|
+
raw = options[:domains] || ENV["DOMAIN_NAMES"]
|
102
|
+
if raw.nil? || raw.strip.empty?
|
103
|
+
puts "⏭️ No domains provided. Skipping DNS operation."
|
104
|
+
return []
|
105
|
+
end
|
106
|
+
raw.split(',').map(&:strip).reject(&:empty?)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
require "droplet_kit"
|
5
|
+
|
6
|
+
module Kitsune
|
7
|
+
module Kit
|
8
|
+
module Commands
|
9
|
+
class Ssh < Thor
|
10
|
+
namespace "ssh"
|
11
|
+
default_task :connect
|
12
|
+
|
13
|
+
desc "connect", "Connect to a remote server via SSH"
|
14
|
+
option :ip, type: :string, desc: "Server IP address (optional)"
|
15
|
+
option :user, type: :string, default: "deploy", desc: "SSH user"
|
16
|
+
def connect
|
17
|
+
Kitsune::Kit::EnvLoader.load!
|
18
|
+
|
19
|
+
ip = options[:ip] || fetch_server_ip
|
20
|
+
user = options[:user]
|
21
|
+
key_path = Kitsune::Kit::Defaults.ssh[:ssh_key_path]
|
22
|
+
|
23
|
+
say "🔗 Connecting to #{user}@#{ip}...", :green
|
24
|
+
exec "ssh -i #{key_path} -o StrictHostKeyChecking=no #{user}@#{ip}"
|
25
|
+
end
|
26
|
+
|
27
|
+
no_commands do
|
28
|
+
def fetch_server_ip
|
29
|
+
token = ENV.fetch("DO_API_TOKEN") { abort "❌ DO_API_TOKEN is missing" }
|
30
|
+
|
31
|
+
client = DropletKit::Client.new(access_token: token)
|
32
|
+
name = Kitsune::Kit::Defaults.infra[:droplet_name]
|
33
|
+
|
34
|
+
droplet = client.droplets.all.find { |d| d.name == name }
|
35
|
+
abort "❌ Droplet '#{name}' not found on DigitalOcean" unless droplet
|
36
|
+
|
37
|
+
ip = droplet.networks.v4.find { |n| n.type == "public" }&.ip_address
|
38
|
+
abort "❌ No public IP found for droplet '#{name}'" unless ip
|
39
|
+
|
40
|
+
ip
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/kitsune/kit/defaults.rb
CHANGED
@@ -2,11 +2,11 @@ module Kitsune
|
|
2
2
|
module Kit
|
3
3
|
module Defaults
|
4
4
|
DROPLET = {
|
5
|
-
droplet_name: "app-
|
5
|
+
droplet_name: "app-dev",
|
6
6
|
region: "sfo3",
|
7
7
|
size: "s-1vcpu-1gb",
|
8
8
|
image: "ubuntu-22-04-x64",
|
9
|
-
tag: "rails-
|
9
|
+
tag: "rails-dev"
|
10
10
|
}.freeze
|
11
11
|
|
12
12
|
SSH = {
|
@@ -15,7 +15,6 @@ module Kitsune
|
|
15
15
|
}.freeze
|
16
16
|
|
17
17
|
POSTGRES = {
|
18
|
-
db_prefix: "myapp_db",
|
19
18
|
user: "postgres",
|
20
19
|
password: "secret",
|
21
20
|
port: "5432",
|
@@ -59,7 +58,7 @@ module Kitsune
|
|
59
58
|
env = ENV.fetch('KIT_ENV', 'development')
|
60
59
|
|
61
60
|
{
|
62
|
-
postgres_db: ENV.fetch('POSTGRES_DB') { "#{
|
61
|
+
postgres_db: ENV.fetch('POSTGRES_DB') { "myapp_db_#{env}" },
|
63
62
|
postgres_user: ENV.fetch('POSTGRES_USER', POSTGRES[:user]),
|
64
63
|
postgres_password: ENV.fetch('POSTGRES_PASSWORD', POSTGRES[:password]),
|
65
64
|
postgres_port: ENV.fetch('POSTGRES_PORT', POSTGRES[:port]),
|
@@ -18,8 +18,8 @@ module Kitsune
|
|
18
18
|
|
19
19
|
if found
|
20
20
|
Dotenv.load(found)
|
21
|
-
puts "🧪 Loaded Kitsune environment from #{found
|
22
|
-
puts "=======================================================================\n"
|
21
|
+
puts AnsiColor.colorize("🧪 Loaded Kitsune environment from #{found}", color: :light_cyan)
|
22
|
+
puts AnsiColor.colorize("=======================================================================\n", color: :light_cyan)
|
23
23
|
else
|
24
24
|
puts "⚠️ No Kitsune infra config found for environment '#{env}' (looked for infra.#{env}.env and infra.env)"
|
25
25
|
end
|
@@ -9,9 +9,7 @@ module Kitsune
|
|
9
9
|
@size = opts[:size]
|
10
10
|
@image = opts[:image]
|
11
11
|
@tag = opts[:tag]
|
12
|
-
@ssh_key_id = opts[:ssh_key_id]
|
13
|
-
abort "❌ You must export SSH_KEY_ID or use --ssh_key_id"
|
14
|
-
end
|
12
|
+
@ssh_key_id = opts[:ssh_key_id] { abort "❌ You must export SSH_KEY_ID or use --ssh_key_id" }
|
15
13
|
|
16
14
|
@client = DropletKit::Client.new(access_token: ENV.fetch("DO_API_TOKEN"))
|
17
15
|
end
|
data/lib/kitsune/kit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kitsune-kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Omar Herrera
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-ssh
|
@@ -94,20 +94,6 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.3'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: colorize
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 1.0.4
|
104
|
-
type: :runtime
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 1.0.4
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: pry
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -187,9 +173,11 @@ files:
|
|
187
173
|
- lib/kitsune/blueprints/docker/redis.yml
|
188
174
|
- lib/kitsune/blueprints/kit.env.template
|
189
175
|
- lib/kitsune/kit.rb
|
176
|
+
- lib/kitsune/kit/ansi_color.rb
|
190
177
|
- lib/kitsune/kit/cli.rb
|
191
178
|
- lib/kitsune/kit/commands/bootstrap.rb
|
192
179
|
- lib/kitsune/kit/commands/bootstrap_docker.rb
|
180
|
+
- lib/kitsune/kit/commands/dns.rb
|
193
181
|
- lib/kitsune/kit/commands/init.rb
|
194
182
|
- lib/kitsune/kit/commands/install_docker_engine.rb
|
195
183
|
- lib/kitsune/kit/commands/postinstall_docker.rb
|
@@ -202,6 +190,7 @@ files:
|
|
202
190
|
- lib/kitsune/kit/commands/setup_swap.rb
|
203
191
|
- lib/kitsune/kit/commands/setup_unattended.rb
|
204
192
|
- lib/kitsune/kit/commands/setup_user.rb
|
193
|
+
- lib/kitsune/kit/commands/ssh.rb
|
205
194
|
- lib/kitsune/kit/commands/switch_env.rb
|
206
195
|
- lib/kitsune/kit/defaults.rb
|
207
196
|
- lib/kitsune/kit/env_loader.rb
|