mimas 0.2.2 → 0.3.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: 465b5f5dab298e62003b3d43b417dcc13d2c6836cba3ade389fe487d3ee59c9d
4
- data.tar.gz: 3bd799075d78069a206a2cafd8b4d4abc3f7b040aa737e42c864704eb041c1ff
3
+ metadata.gz: ea7a87706ea7f9976b782cb891e446b813c7c866e2a4907f451565e670d194a5
4
+ data.tar.gz: adde800fcc3df657cc512cfd14b9fe1ef314e3d4f19f903c68259c3d7394ef28
5
5
  SHA512:
6
- metadata.gz: 4a0da3d7890be014ee7709a47a1ef8c9cba601b55e45fcf9d978f9787e560f4f4aab837f54483801dcc902ce8688d804e7a03484625d1149221a5475ddfbc1dc
7
- data.tar.gz: 5d82db21fab21f4146480c509864360396679031b4ec191a43c37bde4d08c2ed8f84f9bbed492acb5a14d3aa984dc005464ca8f68141dfe8c79022bdf526652d
6
+ metadata.gz: 984c764fc02feeb671c63f33528258abb8ad271811400d27affe7e220fd4eb6d66652b57a3b829fa1bf972aa23a6a2d5fbb42fe6bc7ec290cf1c1155fc352654
7
+ data.tar.gz: 939fa01df07457e75ecb9b2929757edfa0045cb109ec7f7b33366566397af491aca94df1f4a00125f99bd119ab05fc8cc4b318f3cb6c21e0bdabbc03a1853619
@@ -2,18 +2,12 @@ require 'zlib'
2
2
  require 'rubygems/package'
3
3
 
4
4
  module Mimas
5
- module Archive
6
- def archive(root: Dir.pwd, output:, archive_root: "", glob: nil, files: [])
7
- Archiver
8
- .new(root: root, output: output, archive_root: archive_root, glob: glob, files: files)
9
- .package
10
- end
11
- end
12
-
13
5
  class Archiver
14
- def initialize(root:, output:, archive_root:, glob: nil, files: [])
6
+ DEFAULT_OUTPUT_PATH = Pathname.new(Dir.pwd).join("tmp")
7
+
8
+ def initialize(root:, output_path: DEFAULT_OUTPUT_PATH, output_file:, archive_root: nil, glob: nil, files: [])
15
9
  @root = root || Dir.pwd
16
- @output = output
10
+ @output = Pathname.new(output_path).join(output_file)
17
11
  @archive_root = archive_root || ""
18
12
  @glob = glob
19
13
  @source_files = files
@@ -27,6 +21,8 @@ module Mimas
27
21
 
28
22
  tar.close
29
23
  gz.close
24
+
25
+ return @output.to_s
30
26
  end
31
27
 
32
28
  private
data/lib/mimas/cli.rb CHANGED
@@ -8,6 +8,7 @@ module Mimas
8
8
  register "provision", Provision
9
9
  register "push", Push
10
10
  register "console", Console
11
+ register "archive", Archive
11
12
  register "setup caddy", Setup::Caddy
12
13
  register "setup deploy_user", Setup::DeployUser
13
14
  register "setup ruby", Setup::Ruby
@@ -0,0 +1,19 @@
1
+ module Mimas
2
+ module CLI
3
+ module Commands
4
+ class Archive < BaseCommand
5
+ desc "Create your site's archive which will be uploaded to the server"
6
+
7
+ argument :site, desc: "The name of the site to archive"
8
+
9
+ def call(site: :default)
10
+ site = Config.current.sites[site.to_sym]
11
+
12
+ site.archive
13
+
14
+ say "Your site's archive has been created in #{Archiver::DEFAULT_OUTPUT_PATH}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -7,7 +7,7 @@ module Mimas
7
7
  argument :server_name, required: true, desc: "The name of the server to run the console on"
8
8
  argument :site, desc: "The site to run the console for. Uses the default site if unspecified"
9
9
 
10
- def call(server_name, site: :default)
10
+ def call(server_name:, site: :default)
11
11
  server = Config.current.servers[server_name.to_sym]
12
12
  site = Config.current.sites[site.to_sym]
13
13
 
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)
@@ -10,7 +10,7 @@ module Mimas
10
10
  end
11
11
 
12
12
  def archive_path
13
- @archive_path ||= File.join(Dir.pwd, "tmp", archive_name)
13
+ @archive_path
14
14
  end
15
15
 
16
16
  def site_root
@@ -4,27 +4,14 @@ module Mimas
4
4
  def deploy_ruby_app
5
5
  say "Starting deployment for #{site.domain}"
6
6
 
7
- archive(output: archive_path, files: site.files)
7
+ @archive_path = site.archive(filename: archive_name)
8
8
 
9
9
  ssh(server) do |session|
10
- begin
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
- # Create the release folder
18
- session.run "mkdir -p #{releases_path}"
12
+ create_directory_skeleton(session)
19
13
 
20
- # Get expired releases. Mimas will only retain the last 5 releases.
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
- # Revert symlink if there's an existing live release, otherwise delete it
82
- if remote_current_path.size > 0
83
- say "Reverting symlink ..."
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
- site.services.each do |_, service|
93
- systemd_service_name = systemd_service_name(service)
94
- session.run "systemctl --user stop #{systemd_service_name}", silent: true, capture: true
95
- session.run "systemctl --user disable #{systemd_service_name}", silent: true, capture: true
96
- session.run "rm #{server.user_systemd_path.join("#{systemd_service_name}.service")}", silent: true
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
- session.run "rm -f #{unix_socket(version: version)}"
100
- session.run "rm -f #{site_root.join("Caddyfile.new")}"
101
- session.run "rm -rf #{remote_destination}"
76
+ private
102
77
 
103
- exit 1
104
- end
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
- say "\n"
121
- say "Deployment complete! #{version} is now live.".bold.white
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
@@ -4,7 +4,7 @@ module Mimas
4
4
  def deploy_static_site
5
5
  say "Starting deployment for #{site.domain}"
6
6
 
7
- archive(root: site.root_dir, output: archive_path, archive_root: "root", glob: site.glob)
7
+ @archive_path = site.archive(filename: archive_name)
8
8
 
9
9
  ssh(server) do |session|
10
10
  refreshing_caddy(session) do
@@ -1,6 +1,6 @@
1
1
  module Mimas
2
2
  class Deployment
3
- include Terminal::Printer, Template, Archive, SSH
3
+ include Terminal::Printer, Template, SSH
4
4
 
5
5
  include Paths, Files
6
6
  include StaticSite, RubyApp, Caddy
@@ -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
- useradd $DEPLOY_USER -s /bin/bash -m
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..."
@@ -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
@@ -0,0 +1,13 @@
1
+ module Mimas
2
+ class Site
3
+ module Archive
4
+ def archive(filename: "#{name}.tar.gz")
5
+ if self.ruby_app?
6
+ Archiver.new(output_file: filename, files: files).package
7
+ else
8
+ Archiver.new(root: root_dir, output_file: filename, archive_root: "root", glob: glob, files: files).package
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
data/lib/mimas/site.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module Mimas
2
2
  class Site
3
+ include Archive
4
+
3
5
  attr_reader :name
4
6
  def initialize(name, args)
5
7
  @name = name
@@ -20,5 +22,38 @@ module Mimas
20
22
  def ruby_app?
21
23
  services.any?
22
24
  end
25
+
26
+ # Placeholder, will be overwritten by the config file if defined
27
+ def glob
28
+ nil
29
+ end
30
+
31
+ # Placeholder, will be overwritten by the config file if defined
32
+ def files
33
+ nil
34
+ end
35
+
36
+ def validate!
37
+ raise Config::InvalidConfiguration.new("`site` requires a `domain`") \
38
+ unless self.respond_to?(:domain)
39
+
40
+ if ruby_app?
41
+ raise Config::InvalidConfiguration.new("`site` requires a `files` directive") \
42
+ unless self.files != nil
43
+
44
+ services.values.each do |service|
45
+ raise Config::InvalidConfiguration.new("#{service[:name]} service requires a `command` directive") \
46
+ unless service[:command]
47
+ end
48
+ else
49
+ raise Config::InvalidConfiguration.new("`site` requires a `root_dir` directive") \
50
+ unless self.respond_to?(:root_dir)
51
+
52
+ raise Config::InvalidConfiguration.new("`site` requires a `files` or `glob` directive") \
53
+ unless self.glob != nil || self.files != nil
54
+ end
55
+
56
+ true
57
+ end
23
58
  end
24
59
  end
data/lib/mimas/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mimas
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/mimas.rb CHANGED
@@ -16,6 +16,7 @@ require_relative "mimas/hooks"
16
16
 
17
17
  require_relative "mimas/config"
18
18
 
19
+ require_relative "mimas/site/archive"
19
20
  require_relative "mimas/site"
20
21
 
21
22
  require_relative "mimas/server/prerequisites"
@@ -35,6 +36,7 @@ require_relative "mimas/deployment"
35
36
  require_relative "mimas/plugins"
36
37
 
37
38
  require_relative "mimas/base_command"
39
+ require_relative "mimas/commands/archive"
38
40
  require_relative "mimas/commands/console"
39
41
  require_relative "mimas/commands/init"
40
42
  require_relative "mimas/commands/install"
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.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ayush Newatia
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-07-23 00:00:00.000000000 Z
10
+ date: 2026-07-30 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dry-cli
@@ -104,6 +104,7 @@ files:
104
104
  - lib/mimas/archiver.rb
105
105
  - lib/mimas/base_command.rb
106
106
  - lib/mimas/cli.rb
107
+ - lib/mimas/commands/archive.rb
107
108
  - lib/mimas/commands/console.rb
108
109
  - lib/mimas/commands/init.rb
109
110
  - lib/mimas/commands/install.rb
@@ -135,6 +136,7 @@ files:
135
136
  - lib/mimas/server/prerequisites.rb
136
137
  - lib/mimas/server/ruby.rb
137
138
  - lib/mimas/site.rb
139
+ - lib/mimas/site/archive.rb
138
140
  - lib/mimas/ssh.rb
139
141
  - lib/mimas/template.rb
140
142
  - lib/mimas/templates/Caddyfile.ruby.erb