standard-procedure-anvil 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 47f486a924f5bdee358e37587a81182f20578c61180508124ed2cef551b1fd62
4
- data.tar.gz: 87f4d8498543db8f3aefd10ddd5e288bed1d9db89c47e84c82de2745bdd61a4a
3
+ metadata.gz: 826f4465c3c26af2077d355b53142e7755aa8897eceda3a030ef8dc024fa1a3a
4
+ data.tar.gz: c2e780bd49774ce57fc357210b10f867bd8edb1e3694698a0886527ab72d5d38
5
5
  SHA512:
6
- metadata.gz: 92a3dbc97db730b1a55d31bdae8cae9b607f36070b2cee53b6dc386b1cfc755b13f57b90f6874c885882f4d08fd9cc6057dc5e520d9d8dcce7750339124ca518
7
- data.tar.gz: b378044a88edce05a58234c9cca4c7878d7ed7ed25255e57b544392286d18458afffd5b709e51fe70e5e237df0a876111eb3cf4ed529ff2042ac2d8051aa6abd
6
+ metadata.gz: 0d0fe31b85a435a86777fd01de0e0a4c79356dff5f831872a74f0eb552a32f03479a9f5a8a8a371b56aa646e3a2f71d3cdbbdc6d5f8c42479356403f7e163485
7
+ data.tar.gz: f64d1bc0457cc69932acc4a8405206ee7e63c038e68655e2fb96ac10d31bb79a7dc221a5ea497c831cf701176a223bae828e8ce157635fcc12df579f8880f0e8
@@ -0,0 +1,22 @@
1
+ // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
+ // README at: https://github.com/devcontainers/templates/tree/main/src/ruby
3
+ {
4
+ "name": "Ruby",
5
+ // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
6
+ "image": "mcr.microsoft.com/devcontainers/ruby:0-3-bullseye"
7
+
8
+ // Features to add to the dev container. More info: https://containers.dev/features.
9
+ // "features": {},
10
+
11
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
12
+ // "forwardPorts": [],
13
+
14
+ // Use 'postCreateCommand' to run commands after the container is created.
15
+ // "postCreateCommand": "ruby --version",
16
+
17
+ // Configure tool-specific properties.
18
+ // "customizations": {},
19
+
20
+ // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
21
+ // "remoteUser": "root"
22
+ }
data/lib/anvil/cli.rb CHANGED
@@ -18,11 +18,32 @@ class Anvil::Cli < Thor
18
18
  DESC
19
19
  option :private_key, type: :string, default: nil, aliases: "-k"
20
20
  option :passphrase, type: :string, default: nil, aliases: "-p"
21
-
22
21
  def install config = "anvil.yml", private_key = nil, passphrase = nil
23
22
  Anvil::Installer.new(configuration_from(config), private_key, passphrase).call
24
23
  end
25
24
 
25
+ desc "anvil deploy", "Deploy the current app"
26
+ long_desc <<-DESC
27
+ Deploy the current app to the server to the servers
28
+
29
+ Example:
30
+ `anvil deploy CONFIG`
31
+
32
+ The default CONFIG file is `anvil.yml` in the current directory.
33
+ Options:
34
+ --private_key, -k: The path to the key certificate file to use when connecting to the server.
35
+ --passphrase, -p: The passphrase to use when connecting to the server.
36
+ DESC
37
+ option :private_key, type: :string, default: nil, aliases: "-k"
38
+ option :passphrase, type: :string, default: nil, aliases: "-p"
39
+ def deploy config = "anvil.yml", private_key = nil, passphrase = nil
40
+ end
41
+
42
+ desc "anvil version", "Print the version of the anvil gem"
43
+ def version
44
+ puts Anvil::VERSION
45
+ end
46
+
26
47
  def self.exit_on_failure?
27
48
  true
28
49
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Anvil::ServerInstaller::CreateUser < Struct.new(:ssh_connection, :user_name)
4
+ def call
5
+ script = <<~SCRIPT
6
+ if id -u #{user_name} >/dev/null 2>&1; then
7
+ echo "#{user_name} already exists"
8
+ else
9
+ echo "Adding #{user_name}"
10
+ adduser --disabled-password --gecos "" #{user_name}
11
+ usermod -aG sudo #{user_name}
12
+ usermod -aG docker #{user_name}
13
+ echo "#{user_name} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
14
+ fi
15
+ SCRIPT
16
+ ssh_connection.exec! script, "CreateUser"
17
+ end
18
+ end
@@ -13,18 +13,20 @@ require_relative "logger"
13
13
  # - Configure nginx
14
14
  # - Install dokku plugins and run any configuration you have defined
15
15
  # - Disallows root and passwordless logins over SSH
16
- class Anvil::ServerInstaller < Struct.new(:hostname, :configuration, :private_key, :passphrase)
16
+ # You can specify a custom logger or SSH executor using the options hash.
17
+ class Anvil::ServerInstaller < Struct.new(:hostname, :configuration, :private_key, :passphrase, :options)
17
18
  require_relative "server_installer/set_hostname"
18
19
  require_relative "server_installer/set_timezone"
19
20
  require_relative "server_installer/install_packages"
20
- require_relative "server_installer/create_users"
21
+ require_relative "server_installer/create_user"
21
22
  require_relative "server_installer/configure_dokku"
22
23
  require_relative "server_installer/configure_docker"
23
24
  require_relative "server_installer/install_plugins"
24
25
  require_relative "server_installer/configure_firewall"
25
26
  require_relative "server_installer/configure_ssh_server"
27
+
26
28
  def call
27
- Anvil::SshExecutor.new(hostname, server_configuration["user"], logger).call do |ssh_connection|
29
+ ssh_executor.call do |ssh_connection|
28
30
  logger.info "SetHostname"
29
31
  Anvil::ServerInstaller::SetHostname.new(ssh_connection, hostname).call
30
32
  logger.info "SetTimezone"
@@ -34,7 +36,7 @@ class Anvil::ServerInstaller < Struct.new(:hostname, :configuration, :private_ke
34
36
  logger.info "ConfigureDokku"
35
37
  Anvil::ServerInstaller::ConfigureDokku.new(ssh_connection, hostname).call
36
38
  logger.info "CreateUsers"
37
- Anvil::ServerInstaller::CreateUsers.new(ssh_connection, app_names).call
39
+ Anvil::ServerInstaller::CreateUser.new(ssh_connection, server_configuration["app_user"]).call
38
40
  logger.info "InstallPlugins"
39
41
  Anvil::ServerInstaller::InstallPlugins.new(ssh_connection, server_configuration["plugins"]).call
40
42
  logger.info "ConfigureDocker"
@@ -47,14 +49,18 @@ class Anvil::ServerInstaller < Struct.new(:hostname, :configuration, :private_ke
47
49
  end
48
50
 
49
51
  def server_configuration
50
- configuration["server_config"]
52
+ configuration["server"]
51
53
  end
52
54
 
53
- def app_names
54
- configuration["apps"].keys
55
+ def options
56
+ super || {}
55
57
  end
56
58
 
57
59
  def logger
58
- Anvil::Logger.new(hostname)
60
+ options[:logger].nil? ? Anvil::Logger.new(hostname) : options[:logger]
61
+ end
62
+
63
+ def ssh_executor
64
+ options[:ssh_executor].nil? ? Anvil::SshExecutor.new(hostname, server_configuration["install_user"], server_configuration["use_sudo"], logger) : options[:ssh_executor]
59
65
  end
60
66
  end
@@ -2,18 +2,36 @@
2
2
 
3
3
  require "net/ssh"
4
4
 
5
- # The Installer reads the configuration and runs the ServerInstaller for each host.
6
- class Anvil::SshExecutor < Struct.new(:hostname, :user, :logger)
5
+ # The SSH executor is responsible for executing scripts on a remote server via SSH.
6
+ # It can be used with or without sudo
7
+ # - without sudo it runs the scripts as supplied
8
+ # - with sudo it creates a script on the remote server, runs it via sudo, and then deletes it
9
+ # If supplied, it will also write the output of the script to a logger.
10
+ class Anvil::SshExecutor < Struct.new(:hostname, :user, :use_sudo, :logger)
7
11
  def call &block
8
12
  @connection = Net::SSH.start hostname, user, use_agent: true
9
13
  block.call self
10
14
  end
11
15
 
12
16
  def exec! script, category = ""
13
- @connection.exec! script do |channel, stream, data|
17
+ method = use_sudo ? :exec_with_sudo : :exec_without_sudo
18
+ send(method, script, category) do |channel, stream, data|
14
19
  data.to_s.split("\n") do |line|
15
- logger.info line, category
20
+ logger&.info line, category
16
21
  end
17
22
  end
18
23
  end
24
+
25
+ protected
26
+
27
+ def exec_without_sudo script, category = "", &block
28
+ @connection.exec! script, &block
29
+ end
30
+
31
+ def exec_with_sudo script, category = "", &block
32
+ @connection.exec! "cat >> exec.sh << SCRIPT\n#{script}\nSCRIPT", &block
33
+ @connection.exec! "chmod 755 exec.sh", &block
34
+ @connection.exec! "sudo ./exec.sh", &block
35
+ @connection.exec! "rm exec.sh", &block
36
+ end
19
37
  end
data/lib/anvil/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anvil
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard-procedure-anvil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rahoul Baruah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-20 00:00:00.000000000 Z
11
+ date: 2023-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -73,6 +73,7 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".devcontainer/devcontainer.json"
76
77
  - ".rspec"
77
78
  - ".standard.yml"
78
79
  - CHANGELOG.md
@@ -89,7 +90,7 @@ files:
89
90
  - lib/anvil/server_installer/configure_dokku.rb
90
91
  - lib/anvil/server_installer/configure_firewall.rb
91
92
  - lib/anvil/server_installer/configure_ssh_server.rb
92
- - lib/anvil/server_installer/create_users.rb
93
+ - lib/anvil/server_installer/create_user.rb
93
94
  - lib/anvil/server_installer/install_packages.rb
94
95
  - lib/anvil/server_installer/install_plugins.rb
95
96
  - lib/anvil/server_installer/set_hostname.rb
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Anvil::ServerInstaller::CreateUsers < Struct.new(:ssh_connection, :names)
4
- def call
5
- names.collect do |name|
6
- script = <<~SCRIPT
7
- if id -u #{name} >/dev/null 2>&1; then
8
- echo "#{name} already exists"
9
- else
10
- echo "Adding #{name}"
11
- adduser --disabled-password --gecos "" #{name}
12
- usermod -aG sudo #{name}
13
- usermod -aG docker #{name}
14
- echo "#{name} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
15
- fi
16
- SCRIPT
17
- ssh_connection.exec! script, "CreateUsers"
18
- end
19
- end
20
- end