mimas 0.2.2 → 0.2.3
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/lib/mimas/config.rb +13 -0
- data/lib/mimas/deployment/ruby_app.rb +73 -45
- data/lib/mimas/scripts/create_deploy_user.sh +3 -1
- data/lib/mimas/scripts/harden.sh +3 -1
- data/lib/mimas/server.rb +10 -0
- data/lib/mimas/site.rb +20 -0
- data/lib/mimas/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a200733060462cb02f5bb316922a18a44f2c02631707ded251f42f25fd4ea0ac
|
|
4
|
+
data.tar.gz: ddd5a59c92ae52c85312a92698e3d8f2b7ca85f53c7333bc82376d9bf4b47742
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05d4669a9e1122b00de75885ad66734ca6b19da728e5b7b5df02e8a68d46dc2cf3d0bc01155ba88c41949c41534c71d8750608fb688e4c14b340aeca08acfc79
|
|
7
|
+
data.tar.gz: 632f575040f53862208831bef4f743ee9960f1a47a56023b15c0b2c49a5767e70a8e14fac0a22c030cd15373f7d168659f6d8f478dc1d2e506ea6b9114c5f08a
|
data/lib/mimas/config.rb
CHANGED
|
@@ -37,6 +37,17 @@ module Mimas
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
class InvalidConfiguration < StandardError
|
|
41
|
+
attr_reader :message
|
|
42
|
+
def initialize(message)
|
|
43
|
+
@message = message
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_s
|
|
47
|
+
@message.to_s
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
40
51
|
private
|
|
41
52
|
|
|
42
53
|
class DSL
|
|
@@ -56,12 +67,14 @@ module Mimas
|
|
|
56
67
|
name = name.to_sym
|
|
57
68
|
args = Site.evaluate(&block)
|
|
58
69
|
@config.sites[name] = Mimas::Site.new(name, args)
|
|
70
|
+
@config.sites[name].validate!
|
|
59
71
|
end
|
|
60
72
|
|
|
61
73
|
def server(name, &block)
|
|
62
74
|
name = name.to_sym
|
|
63
75
|
args = Options.evaluate(&block)
|
|
64
76
|
@config.servers[name] = Mimas::Server.new(name, args)
|
|
77
|
+
@config.servers[name].validate!
|
|
65
78
|
end
|
|
66
79
|
|
|
67
80
|
def hooks(&block)
|
|
@@ -7,24 +7,11 @@ module Mimas
|
|
|
7
7
|
archive(output: archive_path, files: site.files)
|
|
8
8
|
|
|
9
9
|
ssh(server) do |session|
|
|
10
|
-
|
|
11
|
-
session.run "test -d ~/.rubies/ruby-#{ruby_version}"
|
|
12
|
-
say "Ruby #{ruby_version} found on the server..."
|
|
13
|
-
rescue SSH::Session::NonZeroExitCode
|
|
14
|
-
raise "Ruby version not installed on server"
|
|
15
|
-
end
|
|
10
|
+
validate_server_ruby_version(session)
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
session.run "mkdir -p #{releases_path}"
|
|
12
|
+
create_directory_skeleton(session)
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
releases = session.run "ls #{releases_path}", capture: true
|
|
22
|
-
expired_releases = releases.split("\n").sort.reverse.drop(5)
|
|
23
|
-
|
|
24
|
-
if expired_releases.any?
|
|
25
|
-
say "Deleting versions: #{expired_releases.join(", ")}"
|
|
26
|
-
session.run "cd #{releases_path} && rm -rf #{expired_releases.join(" ")}"
|
|
27
|
-
end
|
|
14
|
+
expire_old_releases(session)
|
|
28
15
|
|
|
29
16
|
# Check `current` symlink to get currently live version
|
|
30
17
|
remote_current_path = session.run("readlink #{current_path}", capture: true, silent: true).chomp
|
|
@@ -32,12 +19,9 @@ module Mimas
|
|
|
32
19
|
|
|
33
20
|
say "Current live version is #{remote_current_version}" if remote_current_version.size > 0
|
|
34
21
|
|
|
35
|
-
# Make systemd path and the site's mimas folder
|
|
36
|
-
session.run "mkdir -p #{server.user_systemd_path}"
|
|
37
|
-
session.run "mkdir -p #{mimas_path}"
|
|
38
|
-
|
|
39
22
|
refreshing_caddy(session) do
|
|
40
23
|
# Upload the mimas.env and touch an `.env` file in the site's root
|
|
24
|
+
session.run "cp #{mimas_path.join("mimas.env")} #{mimas_path.join("mimas.env.backup")}"
|
|
41
25
|
session.upload StringIO.new(mimas_env), mimas_path.join("mimas.env")
|
|
42
26
|
session.run "touch #{site_root.join(".env")}"
|
|
43
27
|
|
|
@@ -78,30 +62,40 @@ module Mimas
|
|
|
78
62
|
rescue Exception => e
|
|
79
63
|
say "Error raised during deploy: #{e}".red.bold
|
|
80
64
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
session.run "ln -sfn #{remote_current_path} #{current_path}"
|
|
85
|
-
else
|
|
86
|
-
say "Deleting symlink ..."
|
|
87
|
-
session.run "rm -f #{current_path}"
|
|
88
|
-
end
|
|
65
|
+
revert_files_after_failed_deployment(session, remote_current_path: remote_current_path)
|
|
66
|
+
exit 1
|
|
67
|
+
end
|
|
89
68
|
|
|
90
|
-
say "Deleting released files ..."
|
|
91
69
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
end
|
|
70
|
+
cleanup_successful_deployment(session, remote_current_version: remote_current_version)
|
|
71
|
+
say "\n"
|
|
72
|
+
say "Deployment complete! #{version} is now live.".bold.white
|
|
73
|
+
end
|
|
74
|
+
end
|
|
98
75
|
|
|
99
|
-
|
|
100
|
-
session.run "rm -f #{site_root.join("Caddyfile.new")}"
|
|
101
|
-
session.run "rm -rf #{remote_destination}"
|
|
76
|
+
private
|
|
102
77
|
|
|
103
|
-
|
|
104
|
-
|
|
78
|
+
def validate_server_ruby_version(session)
|
|
79
|
+
session.run "test -d ~/.rubies/ruby-#{ruby_version}"
|
|
80
|
+
say "Ruby #{ruby_version} found on the server..."
|
|
81
|
+
rescue SSH::Session::NonZeroExitCode
|
|
82
|
+
raise "Ruby version not installed on server"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def create_directory_skeleton(session)
|
|
86
|
+
# Create the release folder
|
|
87
|
+
session.run "mkdir -p #{releases_path}"
|
|
88
|
+
|
|
89
|
+
# Make systemd path and the site's mimas folder
|
|
90
|
+
session.run "mkdir -p #{server.user_systemd_path}"
|
|
91
|
+
session.run "mkdir -p #{mimas_path}"
|
|
92
|
+
|
|
93
|
+
# Create empty .env file
|
|
94
|
+
session.run "touch #{mimas_path.join("mimas.env")}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def cleanup_successful_deployment(session, remote_current_version:)
|
|
98
|
+
session.run "rm -f #{mimas_path.join("mimas.env.backup")}"
|
|
105
99
|
|
|
106
100
|
# Delete the old service if one exists, and the new service started up
|
|
107
101
|
if remote_current_version.size > 0
|
|
@@ -109,18 +103,52 @@ module Mimas
|
|
|
109
103
|
systemd_service_name = systemd_service_name(service, version: remote_current_version)
|
|
110
104
|
|
|
111
105
|
say "Stopping old service: #{systemd_service_name}"
|
|
112
|
-
session.run "systemctl --user stop #{systemd_service_name}"
|
|
113
|
-
session.run "systemctl --user disable #{systemd_service_name}"
|
|
106
|
+
session.run "systemctl --user stop #{systemd_service_name}", capture: true, silent: true
|
|
107
|
+
session.run "systemctl --user disable #{systemd_service_name}", capture: true, silent: true
|
|
114
108
|
session.run "rm #{server.user_systemd_path.join("#{systemd_service_name}.service")}"
|
|
115
109
|
say "#{systemd_service_name} stopped and deleted."
|
|
116
110
|
session.run "rm -f #{unix_socket(version: remote_current_version)}"
|
|
117
111
|
end
|
|
118
112
|
end
|
|
113
|
+
end
|
|
119
114
|
|
|
120
|
-
|
|
121
|
-
|
|
115
|
+
def revert_files_after_failed_deployment(session, remote_current_path:)
|
|
116
|
+
# Revert symlink if there's an existing live release, otherwise delete it
|
|
117
|
+
if remote_current_path.size > 0
|
|
118
|
+
say "Reverting symlink ..."
|
|
119
|
+
session.run "ln -sfn #{remote_current_path} #{current_path}"
|
|
120
|
+
else
|
|
121
|
+
say "Deleting symlink ..."
|
|
122
|
+
session.run "rm -f #{current_path}"
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Restore the previous mimas environment
|
|
126
|
+
session.run "mv #{mimas_path.join("mimas.env.backup")} #{mimas_path.join("mimas.env")}"
|
|
127
|
+
|
|
128
|
+
say "Deleting released files ..."
|
|
129
|
+
|
|
130
|
+
site.services.each do |_, service|
|
|
131
|
+
systemd_service_name = systemd_service_name(service)
|
|
132
|
+
session.run "systemctl --user stop #{systemd_service_name}", capture: true, silent: true
|
|
133
|
+
session.run "systemctl --user disable #{systemd_service_name}", capture: true, silent: true
|
|
134
|
+
session.run "rm #{server.user_systemd_path.join("#{systemd_service_name}.service")}", silent: true
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
session.run "rm -f #{unix_socket(version: version)}"
|
|
138
|
+
session.run "rm -f #{site_root.join("Caddyfile.new")}"
|
|
139
|
+
session.run "rm -rf #{remote_destination}"
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def expire_old_releases(session)
|
|
143
|
+
# Get expired releases. Mimas will only retain the last 5 releases.
|
|
144
|
+
releases = session.run "ls #{releases_path}", capture: true
|
|
145
|
+
expired_releases = releases.split("\n").sort.reverse.drop(5)
|
|
146
|
+
|
|
147
|
+
if expired_releases.any?
|
|
148
|
+
say "Deleting versions: #{expired_releases.join(", ")}"
|
|
149
|
+
session.run "cd #{releases_path} && rm -rf #{expired_releases.join(" ")}"
|
|
150
|
+
end
|
|
122
151
|
end
|
|
123
|
-
end
|
|
124
152
|
end
|
|
125
153
|
end
|
|
126
154
|
end
|
|
@@ -7,7 +7,9 @@ DEPLOY_USER="${DEPLOY_USER:-deploy}"
|
|
|
7
7
|
|
|
8
8
|
if ! id $DEPLOY_USER >/dev/null 2>&1; then
|
|
9
9
|
printf "Creating the $DEPLOY_USER user\n\n"
|
|
10
|
-
|
|
10
|
+
getent group $DEPLOY_USER >/dev/null || groupadd $DEPLOY_USER
|
|
11
|
+
useradd $DEPLOY_USER -g $DEPLOY_USER -s /bin/bash -m
|
|
12
|
+
|
|
11
13
|
printf "$DEPLOY_USER user created\n\n"
|
|
12
14
|
else
|
|
13
15
|
printf "$DEPLOY_USER user exists. Configuring the user..."
|
data/lib/mimas/scripts/harden.sh
CHANGED
|
@@ -18,8 +18,10 @@ printf "UFW enabled\n\n"
|
|
|
18
18
|
printf "Creating the admin user\n\n"
|
|
19
19
|
|
|
20
20
|
if ! id admin >/dev/null 2>&1; then
|
|
21
|
+
# Create an admin group
|
|
22
|
+
getent group admin >/dev/null || groupadd admin
|
|
21
23
|
# Add a new user, set the default shell, and create a home directory
|
|
22
|
-
useradd admin -s /bin/bash -m
|
|
24
|
+
useradd admin -g admin -s /bin/bash -m
|
|
23
25
|
fi
|
|
24
26
|
|
|
25
27
|
# Disable password login
|
data/lib/mimas/server.rb
CHANGED
|
@@ -33,5 +33,15 @@ module Mimas
|
|
|
33
33
|
def current_path(site)
|
|
34
34
|
site_root(site).join("current")
|
|
35
35
|
end
|
|
36
|
+
|
|
37
|
+
def validate!
|
|
38
|
+
raise Config::InvalidConfiguration.new("`server` requires a `host`") \
|
|
39
|
+
unless self.host && self.host.size > 0
|
|
40
|
+
|
|
41
|
+
raise Config::InvalidConfiguration.new("`server` requires a `user`") \
|
|
42
|
+
unless self.user && self.user.size > 0
|
|
43
|
+
|
|
44
|
+
true
|
|
45
|
+
end
|
|
36
46
|
end
|
|
37
47
|
end
|
data/lib/mimas/site.rb
CHANGED
|
@@ -20,5 +20,25 @@ module Mimas
|
|
|
20
20
|
def ruby_app?
|
|
21
21
|
services.any?
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
def validate!
|
|
25
|
+
raise Config::InvalidConfiguration.new("`site` requires a `domain`") \
|
|
26
|
+
unless self.respond_to?(:domain)
|
|
27
|
+
|
|
28
|
+
if ruby_app?
|
|
29
|
+
raise Config::InvalidConfiguration.new("`site` requires a `files` directive") \
|
|
30
|
+
unless self.respond_to?(:files)
|
|
31
|
+
|
|
32
|
+
services.values.each do |service|
|
|
33
|
+
raise Config::InvalidConfiguration.new("#{service[:name]} service requires a `command` directive") \
|
|
34
|
+
unless service[:command]
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
raise Config::InvalidConfiguration.new("`site` requires a `root_dir` and `glob` directive") \
|
|
38
|
+
unless self.respond_to?(:root_dir) && self.respond_to?(:glob)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
true
|
|
42
|
+
end
|
|
23
43
|
end
|
|
24
44
|
end
|
data/lib/mimas/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mimas
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ayush Newatia
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-07-
|
|
10
|
+
date: 2026-07-30 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: dry-cli
|