kaiser 0.0.0 → 0.6.4
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 +5 -5
- data/README.md +129 -0
- data/exe/kaiser +87 -0
- data/lib/kaiser/after_dotter.rb +23 -0
- data/lib/kaiser/cli.rb +624 -0
- data/lib/kaiser/cli_options.rb +14 -0
- data/lib/kaiser/cmds/attach.rb +23 -0
- data/lib/kaiser/cmds/db_load.rb +29 -0
- data/lib/kaiser/cmds/db_reset.rb +22 -0
- data/lib/kaiser/cmds/db_reset_hard.rb +21 -0
- data/lib/kaiser/cmds/db_save.rb +26 -0
- data/lib/kaiser/cmds/deinit.rb +22 -0
- data/lib/kaiser/cmds/down.rb +21 -0
- data/lib/kaiser/cmds/init.rb +39 -0
- data/lib/kaiser/cmds/login.rb +21 -0
- data/lib/kaiser/cmds/logs.rb +19 -0
- data/lib/kaiser/cmds/root.rb +21 -0
- data/lib/kaiser/cmds/set.rb +73 -0
- data/lib/kaiser/cmds/show.rb +40 -0
- data/lib/kaiser/cmds/shutdown.rb +26 -0
- data/lib/kaiser/cmds/up.rb +43 -0
- data/lib/kaiser/command_runner.rb +50 -0
- data/lib/kaiser/config.rb +81 -0
- data/lib/kaiser/databases/mysql.rb +45 -0
- data/lib/kaiser/databases/postgres.rb +46 -0
- data/lib/kaiser/docker_control.rb +10 -0
- data/lib/kaiser/dotter.rb +21 -0
- data/lib/kaiser/error.rb +14 -0
- data/lib/kaiser/kaiserfile.rb +107 -0
- data/lib/kaiser/plugin.rb +68 -0
- data/lib/kaiser/plugins/database.rb +30 -0
- data/lib/kaiser/plugins/git_submodule.rb +23 -0
- data/lib/kaiser/service.rb +22 -0
- data/lib/kaiser/version.rb +5 -0
- data/lib/kaiser.rb +52 -5
- metadata +178 -17
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class DbResetHard < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Shuts down the database docker container, deletes the docker volume on which the db was stored, deletes the default database image stored at \`~/.kaiser/<ENV_NAME>/<current_github_branch_name>/default.tar.bz\`, rebuilds the docker volume and the default database image from scratch and then brings the container up again.
|
9
|
+
|
10
|
+
USAGE: kaiser db_reset_hard
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(_opts)
|
15
|
+
ensure_setup
|
16
|
+
FileUtils.rm db_image_path('default') if File.exist?(db_image_path('default'))
|
17
|
+
setup_db
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class DbSave < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Shuts down the database docker container, backs up the database and brings the container back up.
|
9
|
+
|
10
|
+
The database will be saved as a tarball to \`~/.kaiser/<ENV_NAME>/<current_github_branch_name>/<DB_BACKUP_FILENAME>.tar.bz\`
|
11
|
+
|
12
|
+
Alternatively you can also save it to your current directory.
|
13
|
+
|
14
|
+
USAGE: kaiser db_save DB_BACKUP_FILENAME
|
15
|
+
kaiser db_save ./my_database.tar.bz
|
16
|
+
EOS
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute(_opts)
|
20
|
+
ensure_setup
|
21
|
+
name = ARGV.shift || 'default'
|
22
|
+
save_db(name)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Deinit < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Removes the Kaiser environment from \`~/.kaiser/.config.yml\`. This however does not delete the \`~/.kaiser/databases/<ENV_NAME>\` directory.
|
9
|
+
|
10
|
+
USAGE: kaiser init ENV_NAME
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(_opts)
|
15
|
+
down
|
16
|
+
Config.config[:envs].delete(envname)
|
17
|
+
Config.config[:envnames].delete(Config.work_dir)
|
18
|
+
save_config
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Down < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Shuts down and *deletes* the containers that were started using \`kaiser up\`.
|
9
|
+
|
10
|
+
USAGE: kaiser down
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(_opts)
|
15
|
+
stop_db
|
16
|
+
stop_app
|
17
|
+
delete_db_volume
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Init < Cli
|
6
|
+
# TODO: Add explanation for the Already initialized error.
|
7
|
+
def usage
|
8
|
+
<<~EOS
|
9
|
+
Initializes a Kaiser environment and assigns ports for it in \`~/.kaiser/.config.yml\`. When running \`kaiser up\` later the directory \`~/.kaiser/databases/<ENV_NAME>\` will get created.
|
10
|
+
|
11
|
+
USAGE: kaiser init ENV_NAME
|
12
|
+
EOS
|
13
|
+
end
|
14
|
+
|
15
|
+
def execute(_opts)
|
16
|
+
return Optimist.die "Already initialized as #{envname}" if envname
|
17
|
+
|
18
|
+
name = ARGV.shift
|
19
|
+
return Optimist.die 'Needs environment name' if name.nil?
|
20
|
+
|
21
|
+
init_config_for_env(name)
|
22
|
+
save_config
|
23
|
+
end
|
24
|
+
|
25
|
+
def init_config_for_env(name)
|
26
|
+
Config.config[:envnames][Config.work_dir] = name
|
27
|
+
Config.config[:envs][name] = {
|
28
|
+
app_port: (largest_port + 1).to_s,
|
29
|
+
db_port: (largest_port + 2).to_s
|
30
|
+
}
|
31
|
+
Config.config[:largest_port] = Config.config[:largest_port] + 2
|
32
|
+
end
|
33
|
+
|
34
|
+
def largest_port
|
35
|
+
Config.config[:largest_port]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Login < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Executes a command on the application docker container. By executing the command \`sh\` you can get a login shell.
|
9
|
+
|
10
|
+
USAGE: kaiser login COMMAND
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(_opts)
|
15
|
+
ensure_setup
|
16
|
+
cmd = (ARGV || []).join(' ')
|
17
|
+
exec "docker exec -ti #{app_container_name} #{cmd}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Logs < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Continuously monitors the application container's logs.
|
9
|
+
|
10
|
+
USAGE: kaiser logs
|
11
|
+
EOS
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(_opts)
|
15
|
+
exec "docker logs -f #{app_container_name}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Root < Cli
|
6
|
+
def usage
|
7
|
+
<<~USAGE
|
8
|
+
Executes a command on the application docker container as a root user.
|
9
|
+
|
10
|
+
USAGE: kaiser root COMMAND
|
11
|
+
USAGE
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(_opts)
|
15
|
+
ensure_setup
|
16
|
+
cmd = (ARGV || []).join(' ')
|
17
|
+
exec "docker exec -ti --user root #{app_container_name} #{cmd}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Set < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
This command lets you set up special variables that configure kaiser's behavior for you.
|
9
|
+
|
10
|
+
Available subcommands:
|
11
|
+
|
12
|
+
http-suffix - Sets the domain suffix for the reverse proxy to use (defaults to lvh.me)
|
13
|
+
cert-url - Sets up a URL from which HTTPS certificates can be downloaded.
|
14
|
+
cert-folder - Sets up a folder from which HTTPS certificates can be copied.
|
15
|
+
help-https - Shows the HTTPS notes.
|
16
|
+
|
17
|
+
USAGE: kaiser set cert-url
|
18
|
+
kaiser set cert-folder
|
19
|
+
kaiser set http-suffix
|
20
|
+
kaiser set help-https
|
21
|
+
EOS
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute(_opts)
|
25
|
+
cmd = ARGV.shift
|
26
|
+
|
27
|
+
case cmd
|
28
|
+
when 'cert-url'
|
29
|
+
Config.config[:cert_source] = {
|
30
|
+
url: ARGV.shift
|
31
|
+
}
|
32
|
+
when 'cert-folder'
|
33
|
+
Config.config[:cert_source] = {
|
34
|
+
folder: ARGV.shift
|
35
|
+
}
|
36
|
+
when 'http-suffix'
|
37
|
+
Config.config[:http_suffix] = ARGV.shift
|
38
|
+
when 'help-https'
|
39
|
+
puts <<~SET_HELP
|
40
|
+
Notes on HTTPS:
|
41
|
+
|
42
|
+
You need to set suffix and either cert-url or cert-folder to enable HTTPS.
|
43
|
+
|
44
|
+
cert-url and cert-folder are mutually exclusive. If you set one of them the other will be erased.
|
45
|
+
|
46
|
+
The cert-url and cert-folder must satisfy the following requirements to work:
|
47
|
+
|
48
|
+
The strings must be the root of certificates named after the suffix. For example,
|
49
|
+
|
50
|
+
if cert-url is https://mydomain.com/certs and your suffix is local.mydomain.com, the following
|
51
|
+
url need to be the certificate files:
|
52
|
+
|
53
|
+
https://mydomain.com/certs/local.mydomain.com.chain.pem
|
54
|
+
https://mydomain.com/certs/local.mydomain.com.crt
|
55
|
+
https://mydomain.com/certs/local.mydomain.com.key
|
56
|
+
|
57
|
+
Another example:
|
58
|
+
|
59
|
+
If you use suffix of localme.com and cert-folder is /home/me/https, The following files need to exist:
|
60
|
+
|
61
|
+
/home/me/https/localme.com.chain.pem
|
62
|
+
/home/me/https/localme.com.crt
|
63
|
+
/home/me/https/localme.com.key
|
64
|
+
SET_HELP
|
65
|
+
else
|
66
|
+
Optimist.die "Unknown subcommand: '#{cmd}'"
|
67
|
+
end
|
68
|
+
|
69
|
+
save_config
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Show < Cli
|
6
|
+
def usage
|
7
|
+
<<~EOS
|
8
|
+
Subcommand that shows information about the environment such as the TCP ports or the certificate used for HTTPS.
|
9
|
+
|
10
|
+
USAGE: kaiser show ports
|
11
|
+
kaiser show cert-source
|
12
|
+
kaiser show http-suffix
|
13
|
+
EOS
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(_opts)
|
17
|
+
ensure_setup
|
18
|
+
cmd = ARGV.shift
|
19
|
+
valid_cmds = 'ports cert-source http-suffix'
|
20
|
+
return Optimist.die "Available things to show: #{valid_cmds}" unless cmd
|
21
|
+
|
22
|
+
case cmd
|
23
|
+
when 'ports'
|
24
|
+
Config.info_out.puts "app: #{app_port}"
|
25
|
+
Config.info_out.puts "db: #{db_port}"
|
26
|
+
when 'cert-source'
|
27
|
+
unless Config.config[:cert_source]
|
28
|
+
Optimist.die 'No certificate source set.
|
29
|
+
see kaiser set help'
|
30
|
+
end
|
31
|
+
|
32
|
+
source = Config.config[:cert_source][:url] || Config.config[:cert_source][:folder]
|
33
|
+
Config.info_out.puts source
|
34
|
+
when 'http-suffix'
|
35
|
+
Config.info_out.puts http_suffix
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Shutdown < Cli
|
6
|
+
def usage
|
7
|
+
# TODO: Explain a bit more about what these containers do and what shutting
|
8
|
+
# them down really means for an end user.
|
9
|
+
<<~EOS
|
10
|
+
Shuts down all the containers used internally by Kaiser.
|
11
|
+
|
12
|
+
USAGE: kaiser shutdown
|
13
|
+
EOS
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute(_opts)
|
17
|
+
Config.config[:shared_names].each do |_, container_name|
|
18
|
+
killrm container_name
|
19
|
+
end
|
20
|
+
|
21
|
+
CommandRunner.run Config.out, "docker network rm #{Config.config[:networkname]}"
|
22
|
+
CommandRunner.run Config.out, "docker volume rm #{Config.config[:shared_names][:certs]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Cmds
|
5
|
+
class Up < Cli
|
6
|
+
option :attach,
|
7
|
+
"Bind mount the current source code directory in the app container (as the \`kaiser attach\` command would)", short: '-a'
|
8
|
+
|
9
|
+
def usage
|
10
|
+
<<~EOS
|
11
|
+
Boots up the application in docker as defined in the \`Kaiserfile\` in its source code. Usually this will create two docker containers \`<ENV_NAME>-db\` and \`<ENV_NAME>-app\` running your database and application respectively.
|
12
|
+
|
13
|
+
A backup of the default database is created and saved to \`~/.kaiser/<ENV_NAME>/<current_github_branch_name>/default.tar.bz\`. This can be restored at any time using the \`db_reset\` command.
|
14
|
+
|
15
|
+
USAGE: kaiser up
|
16
|
+
EOS
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute(opts)
|
20
|
+
ensure_setup
|
21
|
+
setup_app
|
22
|
+
setup_db
|
23
|
+
|
24
|
+
if opts[:attach]
|
25
|
+
attach_app
|
26
|
+
else
|
27
|
+
start_app
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def setup_app
|
32
|
+
Config.info_out.puts 'Setting up application'
|
33
|
+
File.write(tmp_dockerfile_name, docker_file_contents)
|
34
|
+
build_args = docker_build_args.map { |k, v| "--build-arg #{k}=#{v}" }
|
35
|
+
CommandRunner.run! Config.out, "docker build
|
36
|
+
-t kaiser:#{envname}-#{current_branch}
|
37
|
+
-f #{tmp_dockerfile_name} #{Config.work_dir}
|
38
|
+
#{build_args.join(' ')}"
|
39
|
+
FileUtils.rm(tmp_dockerfile_name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
|
5
|
+
# This is the command runner
|
6
|
+
module Kaiser
|
7
|
+
# Make running easy
|
8
|
+
class CommandRunner
|
9
|
+
def self.run(out, cmd, &block)
|
10
|
+
out.puts "> #{cmd}"
|
11
|
+
CommandRunner.new(out, cmd).run_command(&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.run!(out, cmd, &block)
|
15
|
+
status = run(out, cmd, &block)
|
16
|
+
raise Kaiser::CmdError.new(cmd, status) if status.to_s != '0'
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(out, cmd)
|
20
|
+
@out = out
|
21
|
+
@cmd = cmd.tr "\n", ' '
|
22
|
+
end
|
23
|
+
|
24
|
+
def print_and_return_status(status = 0)
|
25
|
+
@out.puts "$? = #{status}"
|
26
|
+
@out.flush
|
27
|
+
status
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_lines(lines)
|
31
|
+
lines.each do |line|
|
32
|
+
@out.print line
|
33
|
+
@out.flush
|
34
|
+
yield line.chomp if block_given?
|
35
|
+
end
|
36
|
+
rescue Errno::EIO
|
37
|
+
# Happens when `lines` stream is closed
|
38
|
+
end
|
39
|
+
|
40
|
+
def run_command(&block)
|
41
|
+
PTY.spawn("#{@cmd} 2>&1") do |stdout, _stdin, pid|
|
42
|
+
print_lines(stdout, &block)
|
43
|
+
Process.wait(pid)
|
44
|
+
end
|
45
|
+
print_and_return_status $CHILD_STATUS.exitstatus
|
46
|
+
rescue PTY::ChildExited => e
|
47
|
+
print_and_return_status(e.status)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
class Config
|
5
|
+
class << self
|
6
|
+
attr_accessor :out,
|
7
|
+
:info_out
|
8
|
+
|
9
|
+
attr_reader :work_dir,
|
10
|
+
:config_dir,
|
11
|
+
:config_file,
|
12
|
+
:kaiserfile,
|
13
|
+
:config
|
14
|
+
|
15
|
+
def load(work_dir)
|
16
|
+
@work_dir = work_dir
|
17
|
+
@config_dir = "#{ENV['HOME']}/.kaiser"
|
18
|
+
|
19
|
+
migrate_dotted_config_files
|
20
|
+
|
21
|
+
FileUtils.mkdir_p @config_dir
|
22
|
+
@config_file = "#{@config_dir}/config.yml"
|
23
|
+
@kaiserfile = Kaiserfile.new("#{@work_dir}/Kaiserfile")
|
24
|
+
|
25
|
+
@config = {
|
26
|
+
envnames: {},
|
27
|
+
envs: {},
|
28
|
+
networkname: 'kaiser_net',
|
29
|
+
shared_names: {
|
30
|
+
redis: 'kaiser-redis',
|
31
|
+
nginx: 'kaiser-nginx',
|
32
|
+
chrome: 'kaiser-chrome',
|
33
|
+
dns: 'kaiser-dns',
|
34
|
+
certs: 'kaiser-certs'
|
35
|
+
},
|
36
|
+
largest_port: 9000,
|
37
|
+
always_verbose: false
|
38
|
+
}
|
39
|
+
|
40
|
+
load_config
|
41
|
+
|
42
|
+
alt_kaiserfile = "#{ENV['HOME']}/kaiserfiles/Kaiserfile.#{@config[:envnames][work_dir]}"
|
43
|
+
@kaiserfile = Kaiserfile.new(alt_kaiserfile) if File.exist?(alt_kaiserfile)
|
44
|
+
|
45
|
+
@config
|
46
|
+
end
|
47
|
+
|
48
|
+
def always_verbose?
|
49
|
+
@config[:always_verbose]
|
50
|
+
end
|
51
|
+
|
52
|
+
# Up until version 0.5.1, kaiser used dotfiles for all of it configuration.
|
53
|
+
# It makes sense of hide the configuration directory itself but hiding the files
|
54
|
+
# inside of it just causes confusion.
|
55
|
+
#
|
56
|
+
# Kaiser 0.5.2 started using non-dotted files instead. This method renames the old
|
57
|
+
# files in case you have just upgraded from an older version.
|
58
|
+
def migrate_dotted_config_files
|
59
|
+
return unless File.exist?("#{@config_dir}/.config.yml")
|
60
|
+
|
61
|
+
Dir["#{@config_dir}/**/.*"].each do |x|
|
62
|
+
dest = x.sub(%r{/\.([a-z.]+)$}, '/\1')
|
63
|
+
FileUtils.mv x, dest
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def load_config
|
68
|
+
loaded = YAML.load_file(@config_file) if File.exist?(@config_file)
|
69
|
+
|
70
|
+
config_shared_names = @config[:shared_names] if @config
|
71
|
+
loaded_shared_names = loaded[:shared_names] if loaded
|
72
|
+
|
73
|
+
@config = {
|
74
|
+
**(@config || {}),
|
75
|
+
**(loaded || {}),
|
76
|
+
shared_names: { **(config_shared_names || {}), **(loaded_shared_names || {}) }
|
77
|
+
}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Databases
|
5
|
+
class Mysql
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def options_hash
|
11
|
+
testpass = @options[:root_password] || 'testpassword'
|
12
|
+
parameters = @options[:parameters] || ''
|
13
|
+
port = @options[:port] || 3306
|
14
|
+
|
15
|
+
{
|
16
|
+
port: port,
|
17
|
+
data_dir: '/var/lib/mysql',
|
18
|
+
params: "-e MYSQL_ROOT_PASSWORD=#{testpass}",
|
19
|
+
commands: parameters,
|
20
|
+
waitscript_params: "
|
21
|
+
-e MYSQL_ADDR=<%= db_container_name %>
|
22
|
+
-e MYSQL_PORT=#{port}
|
23
|
+
-e MYSQL_ROOT_PASSWORD=#{testpass}",
|
24
|
+
waitscript: <<~SCRIPT
|
25
|
+
#!/bin/bash
|
26
|
+
|
27
|
+
echo "Waiting for mysql to start."
|
28
|
+
until mysql -h"$MYSQL_ADDR" -P"$MYSQL_PORT" -uroot -p"$MYSQL_ROOT_PASSWORD" -e "SELECT 1"
|
29
|
+
do
|
30
|
+
printf "."
|
31
|
+
sleep 1
|
32
|
+
done
|
33
|
+
|
34
|
+
echo -e "\nmysql started."
|
35
|
+
SCRIPT
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def image_name
|
40
|
+
version = @options[:version] || '5.6'
|
41
|
+
"mysql:#{version}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
module Databases
|
5
|
+
class Postgres
|
6
|
+
def initialize(options)
|
7
|
+
@options = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def options_hash
|
11
|
+
testpass = @options[:root_password] || 'testpassword'
|
12
|
+
parameters = @options[:parameters] || ''
|
13
|
+
port = @options[:port] || 3306
|
14
|
+
platform = @options[:platform] || 'linux/amd64'
|
15
|
+
|
16
|
+
{
|
17
|
+
port: port,
|
18
|
+
data_dir: '/var/lib/postgresql/data',
|
19
|
+
params: "-e POSTGRES_PASSWORD=#{testpass}",
|
20
|
+
commands: parameters,
|
21
|
+
platform: platform,
|
22
|
+
waitscript_params: "
|
23
|
+
-e PG_HOST=<%= db_container_name %>
|
24
|
+
-e PG_USER=postgres
|
25
|
+
-e PGPASSWORD=#{testpass}
|
26
|
+
-e PG_DATABASE=postgres",
|
27
|
+
waitscript: <<~SCRIPT
|
28
|
+
#!/bin/sh
|
29
|
+
|
30
|
+
RETRIES=5
|
31
|
+
|
32
|
+
until psql -h $PG_HOST -U $PG_USER -d $PG_DATABASE -c "select 1" > /dev/null 2>&1 || [ $RETRIES -eq 0 ]; do
|
33
|
+
echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..."
|
34
|
+
sleep 1
|
35
|
+
done
|
36
|
+
SCRIPT
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def image_name
|
41
|
+
version = @options[:version] || 'alpine'
|
42
|
+
"postgres:#{version}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
# Prints dots for every line printed
|
5
|
+
class Dotter
|
6
|
+
attr_accessor :dotted
|
7
|
+
|
8
|
+
def method_missing(name, *value)
|
9
|
+
$stderr.print '.'
|
10
|
+
@dotted = true
|
11
|
+
super unless @dotted
|
12
|
+
end
|
13
|
+
|
14
|
+
# rubocop:disable Lint/UselessMethodDefinition
|
15
|
+
# If we remove this method rubocop complains about it not existing instead.
|
16
|
+
def respond_to_missing?(name)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
# rubocop:enable Lint/UselessMethodDefinition
|
20
|
+
end
|
21
|
+
end
|
data/lib/kaiser/error.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Kaiser
|
4
|
+
# Base class for Kaiser-related errors.
|
5
|
+
class Error < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
# Raised when a command exits with non-zero exit status.
|
9
|
+
class CmdError < Error
|
10
|
+
def initialize(cmd, status)
|
11
|
+
super "ERROR\n#{cmd}\n- exited with code #{status}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|