escualo 0.2.1 → 0.2.2

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
  SHA1:
3
- metadata.gz: a7735e5b6aa9c1a1865ec1719c0b0628239dd98d
4
- data.tar.gz: fc8f3fa5e936c4146a0d14c64d4c20ce7f4dce28
3
+ metadata.gz: 747639e8ec926a1c4bbf9abc2811a38668716595
4
+ data.tar.gz: 481b31181d1341593b77c40202da33d7b7d4bbb5
5
5
  SHA512:
6
- metadata.gz: 829ce07501eaa8ccd5c863a0b8851e12765f8bae79e066fa4f6c73807f96748b7d6136e4464336b357720af33bdca93299f369804f451b8d5fe496ccf7e8953e
7
- data.tar.gz: 2ea012c64d7bf9e43d6c21ad5a8c4a3ac26186b0964aa675de7e1604d0d75db1c1f0c8cf8fbf36a2cfd2ce908306cd9d016d183457998717db556b69eb1c9308
6
+ metadata.gz: dfffe1a982a76c7efb7ac80ba6d5d48aa17dd4f6f488fd78f52114eeabf01816bd5545d7d5e74c2213f1c3e69b5c127e8cfb754b361b187ffbb7ebcb9c1cd955
7
+ data.tar.gz: 0f0cd10a68520e1f7b559941b9d26dd7dfe3585e42b6c77ba3df6e73e1283f5ac4513a379117665b384a2348ee529b7a89c47b3ff8cedb8c08b08adc692022fd
@@ -0,0 +1,114 @@
1
+ command 'artifact list' do |c|
2
+ c.syntax = 'escualo artifact list'
3
+ c.description = 'Lists artifacts on host'
4
+ c.ssh_action do |args, options, ssh|
5
+ Escualo::Artifact.list(ssh).each do |artifact|
6
+ say artifact
7
+ end
8
+ end
9
+ end
10
+
11
+ command 'artifact destroy' do |c|
12
+ c.syntax = 'escualo artifact destroy <NAME>'
13
+ c.description = 'Destroys an artifact on host'
14
+ c.ssh_action do |args, options, ssh|
15
+ name = args.first
16
+
17
+ Escualo::Artifact.destroy(ssh, name)
18
+ say "#{name} destroyed successfully"
19
+ end
20
+ end
21
+
22
+ def say_created(kind, name)
23
+ say "#{kind.titleize} #{name} created successfully"
24
+ say "Now you can deploy this #{kind}"
25
+ end
26
+
27
+ command 'artifact create service' do |c|
28
+ c.syntax = 'escualo artifact create service <NAME> <PORT>'
29
+ c.description = 'Setup a micro-service deployment'
30
+ c.option '-f', '--force', TrueClass, 'Force creation even if already done'
31
+
32
+ c.ssh_action do |args, options, ssh|
33
+ name = args.first
34
+ port = args.second
35
+
36
+ do_unless Escualo::Artifact.present?(ssh, name),
37
+ "Service #{name} already created",
38
+ options do
39
+ launch_command = "exec bundle exec rackup -o 0.0.0.0 -p #{port} > rack.log"
40
+ install_command='bundle install --without development test'
41
+
42
+ step 'Creating init scripts...' do
43
+ Escualo::Artifact.create_scripts_dir ssh, name
44
+ Escualo::Artifact.create_init_script ssh,
45
+ name: name,
46
+ service: true,
47
+ install_command: install_command
48
+ Escualo::Artifact.create_codechange_script ssh, name
49
+ end
50
+
51
+ step 'Configuring upstart...' do
52
+ Escualo::Artifact.configure_upstart ssh, name: name, lanunch_comand: launch_command
53
+ end
54
+
55
+ step 'Configuring monit...' do
56
+ Escualo::Artifact.configure_monit ssh, name
57
+ end
58
+
59
+ step 'Creating push infrastructure' do
60
+ Escualo::Artifact.create_push_infra ssh, name: name, service: true
61
+ end
62
+
63
+ say_created 'service', name
64
+ end
65
+ end
66
+ end
67
+
68
+ command 'artifact create site' do |c|
69
+ c.syntax = 'escualo artifact create site <NAME>'
70
+ c.description = 'Setup an static site deployment'
71
+ c.option '-f', '--force', TrueClass, 'Force creation even if already done'
72
+
73
+ c.ssh_action do |args, options, ssh|
74
+ name = args.first
75
+
76
+ do_unless Escualo::Artifact.present?(ssh, name),
77
+ "Site #{name} already created",
78
+ options do
79
+ step 'Creating init scripts...' do
80
+ Escualo::Artifact.create_scripts_dir ssh, name
81
+ Escualo::Artifact.create_init_script ssh, name: name, static: true
82
+ end
83
+
84
+ step 'Creating push infrastructure' do
85
+ Escualo::Artifact.create_push_infra ssh, name: name, static: true
86
+ end
87
+ say_created 'site', name
88
+ end
89
+ end
90
+ end
91
+
92
+ command 'artifact create executable' do |c|
93
+ c.syntax = 'escualo artifact create executable <NAME>'
94
+ c.description = 'Setup an executable command deployment'
95
+ c.option '-f', '--force', TrueClass, 'Force creation even if already done'
96
+
97
+ c.ssh_action do |args, options, ssh|
98
+ name = args.first
99
+
100
+ do_unless Escualo::Artifact.present?(ssh, name),
101
+ "Executable #{name} already created",
102
+ options do
103
+ step 'Creating init scripts...' do
104
+ Escualo::Artifact.create_scripts_dir ssh, name
105
+ Escualo::Artifact.create_init_script ssh, name: name, executable: true
106
+ end
107
+
108
+ step 'Creating push infrastructure' do
109
+ Escualo::Artifact.create_push_infra ssh, name: name, executable: true
110
+ end
111
+ say_created 'executable', name
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,41 @@
1
+ command 'bootstrap' do |c|
2
+ c.syntax = 'escualo bootstrap'
3
+ c.description = 'Prepare environment to be an escualo host'
4
+ c.option '--swap', TrueClass, 'Setup swap?'
5
+ c.option '--monit-version VERSION', String, 'Monit version'
6
+ c.option '--monit-password PASSWORD', String, 'Monit password. Will be prompted otherwise'
7
+ c.option '-f', '--force', TrueClass, 'Force bootstrap even if already done?'
8
+
9
+ c.ssh_action do |_args, options, ssh|
10
+ unless options.monit_password
11
+ password = ask('Monit Password: ') { |q| q.echo = '*' }
12
+ options.default monit_password: password
13
+ end
14
+ options.default monit_version: '5.16'
15
+
16
+ do_unless Escualo::Env.present?(ssh, :ESCUALO_BASE_VERSION),
17
+ 'This host has already been bootstrapped',
18
+ options do
19
+ step 'Configuring variables...' do
20
+ Escualo::Env.setup ssh
21
+ Escualo::Env.set_builtins ssh
22
+ end
23
+
24
+ step 'Installing base software...' do
25
+ Escualo::Bootstrap.install_base ssh
26
+ end
27
+
28
+ step 'Installing and configuring monit...' do
29
+ Escualo::Bootstrap.setup_monit ssh, options
30
+ end
31
+
32
+ step 'Enabling swap...' do
33
+ Escualo::Bootstrap.enable_swap ssh
34
+ end if options.swap
35
+
36
+ step 'Installing gems...' do
37
+ Escualo::Bootstrap.install_gems ssh
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,17 @@
1
+ command 'deploy' do |c|
2
+ c.syntax = 'escualo deploy <name> <repo>'
3
+ c.description = 'Deploys repository to the given executable, service or site'
4
+ c.option '--tag GIT_TAG', String, 'Github tag to deploy'
5
+ c.action do |args, options|
6
+ Dir.mktmpdir do |dir|
7
+ step 'Cloning repository...' do
8
+ Escualo::Remote.clone dir, args.second, options
9
+ Escualo::Remote.attach dir, args.first
10
+ end
11
+
12
+ step 'Pushing to remote...' do
13
+ Escualo::Remote.push dir
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ command 'env list' do |c|
2
+ c.syntax = 'escualo env list'
3
+ c.description = 'List escualo variables on host'
4
+ c.ssh_action do |args, options, ssh|
5
+ say Escualo::Env.list ssh
6
+ end
7
+ end
8
+
9
+
10
+ def parse_args_variables(args)
11
+ args.map { |it| it.split('=') }.to_h
12
+ end
13
+
14
+ command 'env set' do |c|
15
+ c.syntax = 'escualo env set <NAME>=<VALUE> [<NAME>=<VALUE>,...<NAME>=<VALUE>]'
16
+ c.description = 'Sets one or more escualo variables on host'
17
+ c.ssh_action do |args, options, ssh|
18
+ Escualo::Env.set ssh, parse_args_variables(args)
19
+ end
20
+ end
21
+
22
+ command 'env unset' do |c|
23
+ c.syntax = 'escualo env unset <NAME> [<NAME>,...<NAME>]'
24
+ c.description = 'Unset escualo variables on host'
25
+ c.ssh_action do |args, options, ssh|
26
+ Escualo::Env.unset ssh, args
27
+ end
28
+ end
29
+
30
+ command 'env clean' do |c|
31
+ c.syntax = 'escualo env clean'
32
+ c.description = 'Unset all escualo variables on host'
33
+ c.ssh_action do |args, options, ssh|
34
+ Escualo::Env.clean ssh
35
+ end
36
+ end
@@ -0,0 +1,31 @@
1
+ $hostname = 'localhost'
2
+ $username = 'root'
3
+ $ssh_options = {}
4
+ $ssh_remote = false
5
+
6
+ global_option '-h', '--hostname HOSTNAME', String, 'The host to connect. Defaults to "localhost"' do |hostname|
7
+ $hostname = hostname
8
+ $ssh_remote = true
9
+ end
10
+
11
+ global_option '-u', '--username USERNAME', String, 'The username to connect. Defaults to "root"' do |username|
12
+ $username = username
13
+ $ssh_remote = true
14
+ end
15
+
16
+ global_option '--password PASSWORD', String, 'An optional remote password' do |password|
17
+ $ssh_options[:password] = password
18
+ $ssh_remote = true
19
+ end
20
+
21
+ global_option '-i', '--ssh-key PRIVATE_KEY', String, 'An optional private key' do |private_key|
22
+ $ssh_options[:keys] = [private_key]
23
+ $ssh_remote = true
24
+ end
25
+
26
+ global_option '--ssh-port PORT', String, 'The ssh port to connect. Defaults to 22' do |port|
27
+ $ssh_options[:port] = port
28
+ $ssh_remote = true
29
+ end
30
+
31
+ global_option '--verbose', TrueClass, 'Dumps extra output'
@@ -0,0 +1,42 @@
1
+ command 'plugin install' do |c|
2
+ c.syntax = 'escualo plugin install <plugin>'
3
+ c.description = "Install plugin on host. Valid plugins are #{Escualo::Plugin::PLUGINS.join(', ')}"
4
+ c.option '--nginx-conf FILENAME', String, 'ningix config file, only for nginx plugin'
5
+ c.option '--rabbit-admin-password PASSWORD', String, 'rabbitmq admin password, only for rabbit plugin'
6
+ c.option '-f', '--force', TrueClass, 'Force reinstalling even if already done'
7
+
8
+ c.ssh_action do |args, options, ssh|
9
+ plugin = args.first
10
+ say "Installing #{plugin}"
11
+
12
+ installer = Escualo::Plugin.load plugin
13
+
14
+ do_unless installer.check(ssh),
15
+ "Plugin #{plugin} is already installed",
16
+ options do
17
+
18
+ step "Installing plugin #{plugin}" do
19
+ log = installer.run ssh, options
20
+ end
21
+
22
+ if installer.check ssh
23
+ say 'Installed successfully!'
24
+ else
25
+ say "Something went wrong. Last output was: \n#{log}"
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ command 'plugin list' do |c|
32
+ c.syntax = 'escualo plugin list'
33
+ c.description = 'List installed plugins on host'
34
+
35
+ c.ssh_action do |_args, _options, ssh|
36
+ Escualo::Plugin::PLUGINS.each do |plugin|
37
+ if Escualo::Plugin.load(plugin).check ssh
38
+ say plugin
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,13 @@
1
+ command 'rake' do |c|
2
+ c.syntax = 'escualo rake <SERVICE_NAME> <TASK>'
3
+ c.description = 'Run rake task on host'
4
+ c.ssh_action do |args, options, ssh|
5
+ name = args.first
6
+ task = args.second
7
+ say ssh.shell.exec! %Q{
8
+ cd /var/www/#{name}
9
+ bundle exec rake #{task}
10
+ }
11
+ end
12
+ end
13
+
@@ -0,0 +1,32 @@
1
+ command 'remote attach' do |c|
2
+ c.syntax = 'escualo remote attach <name>'
3
+ c.description = "Adds the given artifact to current's repository"
4
+ c.option '--repo-path PATH', String, 'Sets the git dir'
5
+
6
+ c.action do |args, options|
7
+ options.default repo_path: Dir.pwd
8
+
9
+ Escualo::Remote.attach options.repo_path, args.first
10
+ end
11
+ end
12
+
13
+ command 'remote show' do |c|
14
+ c.syntax = 'escualo remote show'
15
+ c.description = "Show attached artifacts to current's repository"
16
+ c.option '--repo-path PATH', String, 'Sets the git dir'
17
+
18
+ c.action do |_args, options|
19
+ options.default repo_path: Dir.pwd
20
+
21
+ Escualo::Remote.remotes(options.repo_path).each { |it| say it }
22
+ end
23
+ end
24
+
25
+ command 'remote push' do |c|
26
+ c.syntax = 'escualo remote push'
27
+ c.description = 'Pushes artifact at current repository'
28
+ c.action do |_args, _options|
29
+ Escualo::Remote.push Dir.pwd
30
+ end
31
+ end
32
+
@@ -0,0 +1,33 @@
1
+ def run_commands_for!(script, extra='', ssh)
2
+ script.map { |it| "escualo #{it} #{extra}" }.each do |command|
3
+ puts command
4
+ puts ssh.exec! command
5
+ end
6
+ end
7
+
8
+ def ssh_options
9
+ [$hostname.try { |it| "--hostname #{it}" },
10
+ $username.try { |it| "--username #{it}" },
11
+ $password.try { |it| "--$password #{it}" },
12
+ $ssh_options[:keys].try { |it| "--ssh-key #{it}" },
13
+ $ssh_options[:port].try { |it| "--ssh-port #{it}" }
14
+ ].compact.join(' ')
15
+ end
16
+
17
+ command 'script' do |c|
18
+ c.syntax = 'escualo script <FILE>'
19
+ c.description = 'Runs a escualo configuration'
20
+ c.action do |args, options|
21
+ file = YAML.load_file args.first
22
+
23
+ step 'Running local commands...' do
24
+ run_commands_for! file['local'], ssh_options, Net::SSH::Connection::LocalSession.new
25
+ end
26
+
27
+ step 'Running remote commands...' do
28
+ Net::SSH.start($hostname, $username, $ssh_options.compact) do |ssh|
29
+ run_commands_for! file['remote'], ssh
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ command 'upload' do |c|
2
+ c.syntax = 'escualo upload <FILE> <DESTINATION>'
3
+ c.description = 'Upload file to host'
4
+ c.ssh_action do |args, options, ssh|
5
+ ssh.scp.upload! args.first, args.second
6
+ end
7
+ end
@@ -0,0 +1,63 @@
1
+ module Escualo
2
+ module Artifact
3
+ def self.destroy(ssh, name)
4
+ raise 'name must not be blank' if name.blank?
5
+ raise 'name must not contains wildcards' if name.include?('*')
6
+
7
+ ssh.exec! "rm -rf /var/scripts/#{name}"
8
+ ssh.exec! "rm -rf /var/repo/#{name}.git"
9
+ ssh.exec! "rm -f /etc/monit/conf.d/escualo-#{name}"
10
+ ssh.exec! "rm -f /etc/init/#{name}.conf"
11
+ end
12
+
13
+ def self.present?(ssh, name)
14
+ list(ssh).include? name
15
+ end
16
+
17
+ def self.create_scripts_dir(ssh, name)
18
+ ssh.exec! "mkdir -p /var/scripts/#{name}"
19
+ end
20
+
21
+ def self.create_init_script(ssh, options)
22
+ ssh.upload_template! "/var/scripts/#{options[:name]}/init",
23
+ 'init.sh',
24
+ options
25
+ ssh.exec! "chmod +x /var/scripts/#{options[:name]}/init"
26
+ end
27
+
28
+ def self.list(ssh)
29
+ ssh.exec!('ls /var/repo/').captures(/(.*)\.git/).map { $1 }
30
+ end
31
+
32
+ def self.create_push_infra(ssh, options)
33
+ name = options[:name]
34
+ ssh.exec! %Q{\
35
+ cd /var && \
36
+ mkdir -p www && \
37
+ mkdir -p repo && \
38
+ cd repo && \
39
+ rm -rf #{name}.git && \
40
+ mkdir #{name}.git && \
41
+ cd #{name}.git && \
42
+ git init --bare
43
+ }
44
+ ssh.upload_template! "/var/repo/#{name}.git/hooks/post-receive", 'post-receive.sh', options
45
+ ssh.exec! 'chmod +x post-receive'
46
+ end
47
+
48
+ def self.configure_monit(ssh, name)
49
+ ssh.exec! 'mkdir -p /etc/monit/conf.d/'
50
+ ssh.upload_template! "/etc/monit/conf.d/escualo-#{name}", 'monit.conf', name: name
51
+ ssh.exec! 'monit reload'
52
+ end
53
+
54
+ def self.create_codechange_script(ssh, name)
55
+ ssh.upload_template! "/var/scripts/#{name}/codechange", "codechange.sh", name: name
56
+ ssh.exec! "chmod +x /var/scripts/#{name}/codechange"
57
+ end
58
+
59
+ def self.configure_upstart(ssh, options)
60
+ ssh.upload_template! "/etc/init/#{name}.conf", 'upstart.conf', options
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,55 @@
1
+ module Escualo
2
+ module Bootstrap
3
+ def self.install_base(ssh)
4
+ ssh.exec! %Q{ \
5
+ apt-get install software-properties-common -y && \
6
+ apt-add-repository ppa:brightbox/ruby-ng && \
7
+ apt-get update && \
8
+ apt-get install -y \
9
+ autoconf \
10
+ bison \
11
+ build-essential \
12
+ libreadline6 \
13
+ libreadline6-dev \
14
+ curl \
15
+ git \
16
+ libssl-dev \
17
+ ruby2.0 \
18
+ ruby2.0-dev \
19
+ zlib1g \
20
+ zlib1g-dev \
21
+ libreadline-dev }
22
+ end
23
+
24
+ def self.enable_swap(ssh)
25
+ ssh.exec! %Q{ \
26
+ test -e /swapfile ||
27
+ fallocate -l 4G /swapfile && \
28
+ chmod 600 /swapfile && \
29
+ mkswap /swapfile && \
30
+ swapon /swapfile && \
31
+ swapon -s && \
32
+ echo '/swapfile none swap sw 0 0' >> /etc/fstab}
33
+ end
34
+
35
+ def self.setup_monit(ssh, options)
36
+ ssh.exec! %Q{
37
+ service monit stop && \
38
+ cd /tmp && \
39
+ wget https://mmonit.com/monit/dist/binary/5.16/monit-#{options.monit_version}-linux-x64.tar.gz && \
40
+ tar -xzf monit-#{options.monit_version}-linux-x64.tar.gz && \
41
+ cp monit-#{options.monit_version}/bin/monit /usr/bin/monit && \
42
+ ln -s /etc/monit/monitrc /etc/monitrc && \
43
+ service monit start && \
44
+ 'set httpd port 2812 and' > /etc/monit/conf.d/web-server && \
45
+ ' allow 0.0.0.0/0.0.0.0' >> /etc/monit/conf.d/web-server && \
46
+ ' allow admin:#{options.monit_password}' >> /etc/monit/conf.d/web-server && \
47
+ monit reload}
48
+ end
49
+
50
+ def self.install_gems(ssh)
51
+ ssh.exec! 'gem install bundler'
52
+ ssh.exec! 'gem install escualo'
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,60 @@
1
+ module Escualo
2
+ module Env
3
+ def self.setup(ssh)
4
+ source_escualorc = "'source ~/.escualorc'"
5
+ ssh.exec! %Q{
6
+ mkdir -p ~/.escualo/vars && \
7
+ echo 'for var in ~/.escualo/vars/*; do source $var; done' > ~/.escualorc && \
8
+ chmod u+x ~/.escualorc && \
9
+ grep -q #{source_escualorc} ~/.bashrc || echo #{source_escualorc} >> ~/.bashrc
10
+ }
11
+ end
12
+
13
+ def self.set_builtins(ssh)
14
+ set ssh, ESCUALO_BASE_VERSION: Escualo::BASE_VERSION
15
+ set ssh, Escualo::Env.locale_variables
16
+ set ssh, Escualo::Env.production_variables
17
+ end
18
+
19
+ def self.list(ssh)
20
+ ssh.exec!("cat ~/.escualo/vars/*").gsub("export ", '')
21
+ end
22
+
23
+ def self.clean(ssh)
24
+ ssh.exec!("rm ~/.escualo/vars/*")
25
+ set_builtins ssh
26
+ end
27
+
28
+ def self.present?(ssh, variable)
29
+ ssh.exec!("cat ~/.escualo/vars/#{variable}").present?
30
+ end
31
+
32
+ def self.set(ssh, variables)
33
+ variables.each do |key, value|
34
+ ssh.exec!("echo 'export #{key}=#{value}' > ~/.escualo/vars/#{key}")
35
+ end
36
+ end
37
+
38
+ def self.unset(ssh, variable_names)
39
+ variable_names.each do |name|
40
+ ssh.exec!("rm ~/.escualo/vars/#{name}")
41
+ end
42
+ end
43
+
44
+ def self.locale_variables
45
+ %w{LANG LC_ALL LC_NAME LC_PAPER LC_ADDRESS LC_NUMERIC LC_MONETARY LC_TELEPHONE LC_MEASUREMENT}.map do |it|
46
+ [it, 'en_US.UTF-8']
47
+ end.to_h
48
+ end
49
+
50
+ def self.production_variables
51
+ %w{RAILS_ENV NODE_ENV RACK_ENV}.map do |it|
52
+ [it, 'production']
53
+ end.to_h
54
+ end
55
+
56
+ def self.locale_export
57
+ locale_variables.map { |key, value| "#{key}=#{value}" }.join(' ')
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,11 @@
1
+ module Escualo::Plugin
2
+ class Docker
3
+ def run(ssh, options)
4
+ ssh.perform! 'apt-get install -y docker.io', options
5
+ end
6
+
7
+ def check(ssh)
8
+ ssh.exec!('docker -v').include? 'Docker version'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Escualo::Plugin
2
+ class Haskell
3
+ def run(ssh, options)
4
+ ssh.perform! 'apt-get install -y haskell-platform', options
5
+ end
6
+
7
+ def check(ssh)
8
+ ssh.exec!('ghc --version').include? 'The Glorious Glasgow Haskell Compilation System'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Escualo::Plugin
2
+ class Mongo
3
+ def run(ssh, options)
4
+ ssh.shell.perform! %Q{
5
+ echo 'deb http://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.2 multiverse' | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list && \
6
+ apt-get update && \
7
+ apt-get install -y --force-yes mongodb-org && \
8
+ echo '' >> /etc/init/mongodb && \
9
+ echo 'respawn' >> /etc/init/mongodb
10
+ }, options
11
+ end
12
+
13
+ def check(ssh)
14
+ ssh.shell.exec!('mongod --version').include? 'db version v3.2'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module Escualo::Plugin
2
+ class Nginx
3
+ def run(ssh, options)
4
+ config = options.nginx_conf.try { |it| File.read it }
5
+
6
+ ssh.perform! %Q{
7
+ sudo add-apt-repository ppa:nginx/stable && \
8
+ sudo apt-get update && \
9
+ sudo apt-get install nginx -y && \
10
+ #{config ? "/etc/nginx/nginx.conf < cat #{config} && " : ''} \
11
+ service nginx restart
12
+ }, options
13
+ end
14
+
15
+ def check(ssh)
16
+ ssh.exec!('nginx -v').include? 'nginx version: nginx/1'
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,15 @@
1
+ module Escualo::Plugin
2
+ class Node
3
+ def run(ssh, options)
4
+ ssh.shell.perform! %Q{
5
+ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.2/install.sh | bash && \
6
+ source ~/.bashrc && \
7
+ nvm install 4.2.4
8
+ }, options
9
+ end
10
+
11
+ def check(ssh)
12
+ ssh.shell.exec!('nvm use node').include? 'Now using node v4.2.4'
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module Escualo::Plugin
2
+ class Postgre
3
+ def run(ssh, options)
4
+ pg_hba_conf = '/etc/postgresql/9.3/main/pg_hba.conf'
5
+
6
+ ssh.shell.perform! %Q{
7
+ apt-get install postgresql libpq-dev -y && \
8
+ \
9
+ echo 'local all postgres peer' > #{pg_hba_conf} && \
10
+ echo 'local all postgres peer' >> #{pg_hba_conf} && \
11
+ echo 'local all all password' >> #{pg_hba_conf} && \
12
+ echo 'host all all 127.0.0.1/32 md5' >> #{pg_hba_conf}
13
+ }, options
14
+ end
15
+
16
+ def check(ssh)
17
+ ssh.shell.exec!('psql --version').include? 'psql (PostgreSQL) 9.3'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module Escualo::Plugin
2
+ class Rabbit
3
+ def run(ssh, options)
4
+ raise 'missing rabbit password' unless options.rabbit_admin_password
5
+
6
+ ssh.shell.perform! %Q{
7
+ echo "deb http://www.rabbitmq.com/debian testing main" >> /etc/apt/sources.list && \
8
+ wget https://www.rabbitmq.com/rabbitmq-signing-key-public.asc && \
9
+ apt-key add rabbitmq-signing-key-public.asc && \
10
+ apt-get update && \
11
+ apt-get install rabbitmq-server -y --force-yes && \
12
+ rabbitmq-plugins enable rabbitmq_management && \
13
+ rabbitmqctl add_user admin #{options.rabbit_admin_password} && \
14
+ rabbitmqctl set_user_tags admin administrator
15
+ }, options
16
+ end
17
+
18
+ def check(ssh)
19
+ ssh.exec!('rabbitmq-server').include? 'node with name "rabbit" already running'
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,17 @@
1
+ module Escualo
2
+ module Plugin
3
+ PLUGINS = %w(node haskell docker postgre nginx rabbit mongo)
4
+
5
+ def self.load(name)
6
+ "Escualo::Plugin::#{name.capitalize}".constantize.new
7
+ end
8
+ end
9
+ end
10
+
11
+ require_relative './plugin/docker'
12
+ require_relative './plugin/haskell'
13
+ require_relative './plugin/mongo'
14
+ require_relative './plugin/nginx'
15
+ require_relative './plugin/node'
16
+ require_relative './plugin/postgre'
17
+ require_relative './plugin/rabbit'
@@ -0,0 +1,30 @@
1
+ module Escualo
2
+ module Remote
3
+ def self.attach(dir, name)
4
+ remote_name = "escualo-#{name}-#{$hostname}"
5
+ remote_url = "ssh://#{$username}@#{$hostname}:#{$ssh_options[:port]}/var/repo/#{name}.git"
6
+ %x{cd #{dir} && git remote add #{remote_name} #{remote_url}}
7
+ end
8
+
9
+ def self.clone(dir, repo, options)
10
+ repo_url = "https://github.com/#{repo}"
11
+ %x{git clone #{repo_url} #{dir}}
12
+ if options.tag
13
+ %x{cd #{dir} && git checkout #{options.tag}}
14
+ end
15
+ end
16
+
17
+ def self.remotes(dir)
18
+ %x{cd #{dir} && git remote show}
19
+ .split
20
+ .select {|it| it.start_with? 'escualo-'}
21
+ end
22
+
23
+ def self.push(dir)
24
+ remotes(dir)
25
+ .each do |remote|
26
+ %x{cd #{dir} && git push #{remote} HEAD}
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ module Escualo
2
+ VERSION = '0.2.2'
3
+ BASE_VERSION = '3.1'
4
+ end
@@ -0,0 +1,27 @@
1
+ require 'fileutils'
2
+ require 'open3'
3
+
4
+ class Net::SSH::Connection::LocalSession
5
+ include Net::SSH::Connection::Perform
6
+ include Net::SSH::Connection::Upload
7
+
8
+ def exec!(command)
9
+ %x{#{command}}
10
+ end
11
+
12
+ def upload_file!(file, destination)
13
+ FileUtils.cp file, destination
14
+ end
15
+
16
+ def tell!(command)
17
+ Open3.popen2e command do |_input, output|
18
+ output.each do |line|
19
+ $stdout.print line
20
+ end
21
+ end
22
+ end
23
+
24
+ def shell
25
+ self
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ module Net::SSH::Connection::Perform
2
+ def perform!(command, options)
3
+ if options.verbose
4
+ tell! command
5
+ else
6
+ exec! command
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,55 @@
1
+ class Net::SSH::Connection::Session
2
+ include Net::SSH::Connection::Perform
3
+ include Net::SSH::Connection::Upload
4
+
5
+ def upload_file!(file, destination)
6
+ scp.upload! file, destination
7
+ end
8
+
9
+ def tell!(command)
10
+ channel = self.open_channel do |ch|
11
+ ch.exec command do |ch, success|
12
+ raise 'could not execute command' unless success
13
+ ch.on_data do |c, data|
14
+ $stdout.print data
15
+ end
16
+ ch.on_extended_data do |c, type, data|
17
+ $stderr.print data
18
+ end
19
+ end
20
+ end
21
+ channel.wait
22
+ end
23
+
24
+ def shell
25
+ Shell.new self
26
+ end
27
+
28
+ class Shell
29
+ attr_reader :ssh
30
+
31
+ def initialize(ssh)
32
+ @ssh = ssh
33
+ end
34
+
35
+ def perform!(command, options)
36
+ ssh.perform! wrap(command), options
37
+ end
38
+
39
+ def exec!(command)
40
+ ssh.exec! wrap(command)
41
+ end
42
+
43
+ def tell!(command)
44
+ ssh.tell! wrap(command)
45
+ end
46
+
47
+ private
48
+
49
+ def wrap(command)
50
+ "bash -i -s <<EOBASH
51
+ #{command}
52
+ EOBASH"
53
+ end
54
+ end
55
+ end
data/lib/ssh/upload.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Net::SSH::Connection::Upload
2
+ def upload_template!(destination, name, bindings)
3
+ Mumukit::Core::Template
4
+ .new(File.join(__dir__, '..', 'templates', "#{name}.erb"), bindings)
5
+ .with_tempfile!('template') do |file|
6
+ upload_file! file, destination
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ REVISION=$1
3
+
4
+ echo "[Escualo] Running codechange for revision $REVISION..."
5
+
6
+ cd /var/www/<%= @name %>
7
+
8
+ if [ -e .escualo/jobs ]; then
9
+ echo "[Escualo] [<%= @name %>] Found jobs, creating monitors..."
10
+
11
+ for job_path in .escualo/jobs/*; do
12
+ job=$(basename $job_path)
13
+ echo "[Escualo] [<%= @name %>] setting up Upstart service for job $job..."
14
+ cat > /etc/init/<%= @name %>-$job.conf <<EOJOB
15
+ description "<%= @name %>-$job configuration"
16
+ author "Escualo - via The Mumuki Project"
17
+
18
+ start on runlevel [2345]
19
+ stop on runlevel [!2345]
20
+
21
+ respawn
22
+
23
+ chdir /var/www/<%= @name %>
24
+
25
+ script
26
+ for var in /root/.escualo/vars/*; do . \\$var; done
27
+ chmod u+x .escualo/jobs/$job
28
+ echo \\$\\$ > $job.pid
29
+ $job_path
30
+ end script
31
+ EOJOB
32
+
33
+ echo "[Escualo] [<%= @name %>] setting up Monit for job $job..."
34
+ cat > /etc/monit/conf.d/escualo-<%= @name %>-$job <<EOMONIT
35
+
36
+ check process escualo-<%= @name %>-$job with pidfile /var/www/<%= @name %>/$job.pid
37
+ start "/sbin/start <%= @name %>-$job"
38
+ stop "/sbin/stop <%= @name %>-$job"
39
+ EOMONIT
40
+
41
+ done
42
+
43
+ monit reload
44
+ fi
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ REVISION=$1
3
+
4
+ cd /var/www/<%= @name %>
5
+
6
+ if [ -e .escualo/install/before ]; then
7
+ echo "[Escualo] [<%= @name %>] .escualo/install/before found. Running it..."
8
+ chmod u+x .escualo/install/before
9
+ .escualo/install/before
10
+ fi
11
+
12
+ <% if @service %>
13
+ echo "[Escualo] [<%= @name %>] installing dependencies..."
14
+ <%= @install_command %>
15
+
16
+ monit unmonitor escualo-<%= @name %>
17
+ service <%= @name %> stop
18
+
19
+ if [ -e .escualo/jobs ]; then
20
+ echo "[Escualo] [<%= @name %>] Jobs detected, stopping jobs..."
21
+
22
+ for job_path in .escualo/jobs/*; do
23
+ job=$(basename $job_path)
24
+ echo "[Escualo] [<%= @name %>] Stopping job $job..."
25
+
26
+ monit unmonitor escualo-<%= @name %>-$job
27
+ service <%= @name %>-$job stop
28
+ done
29
+ fi
30
+ <% end %>
31
+
32
+ <% if @executable %>
33
+ echo '[Escualo] [<%= @name %>] adding executable to /usr/bin...'
34
+ rm -f /usr/bin/<%= @name %>
35
+ ln -s /var/bin/<%= @name %>/<%= @name %> /usr/bin
36
+ <% end %>
37
+
38
+ if [ -e .escualo/install/after ]; then
39
+ echo "[Escualo] [<%= @name %>] .escualo/install/after found. Running it..."
40
+ chmod u+x .escualo/install/after
41
+ .escualo/install/after $REVISION
42
+ fi
43
+
44
+ <% if @service %>
45
+ service <%= @name %> start
46
+ monit monitor escualo-<%= @name %>
47
+
48
+ if [ -e .escualo/jobs ]; then
49
+ echo "[Escualo] [<%= @name %>] Starting jobs..."
50
+
51
+ for job_path in .escualo/jobs/*; do
52
+ job=$(basename $job_path)
53
+ echo "[Escualo] [<%= @name %>] Starting job $job..."
54
+
55
+ service <%= @name %>-$job start
56
+ monit monitor escualo-<%= @name %>-$job
57
+ done
58
+ fi
59
+ <% end %>
@@ -0,0 +1,11 @@
1
+ check host escualo-<%= @name %> with address $HOST
2
+ start "/sbin/start <%= @name %>"
3
+ stop "/sbin/stop <%= @name %>"
4
+ if failed
5
+ port $PORT
6
+ protocol HTTP
7
+ request "/"
8
+ status > 199
9
+ with timeout 30 seconds
10
+ then restart
11
+ EOF
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ echo "[Escualo] [<%= @name %>] Loading environment..."
3
+ source ~/.escualorc
4
+
5
+ echo "[Escualo] [<%= @name %>] Running live hook..."
6
+ while read oldrev newrev refname
7
+ do
8
+ branch=$(git rev-parse --symbolic --abbrev-ref $refname)
9
+
10
+ echo "[Escualo] [<%= @name %>] branch found: $branch"
11
+ if [ "master" == "$branch" ]; then
12
+ echo "[Escualo::LiveHook::Version] <%= Escualo::BASE_VERSION %>"
13
+ export ESCUALO_SERVICE_VERSION=<%= Escualo::BASE_VERSION %>
14
+
15
+ echo "[Escualo] [<%= @name %>] master branch detected, deploying..."
16
+ mkdir -p /var/www/<%= @name %>
17
+ git --work-tree=/var/www/<%= @name %> --git-dir=/var/repo/<%= @name %>.git checkout master -f
18
+
19
+ <% if @service %>
20
+ /var/scripts/<%= @name %>/codechange $newrev
21
+ <% end %>
22
+ /var/scripts/<%= @name %>/init $newrev
23
+ fi
24
+ done
@@ -0,0 +1,14 @@
1
+ description "<%= @name %> configuration"
2
+ author "Escualo - via The Mumuki Project"
3
+
4
+ start on runlevel [2345]
5
+ stop on runlevel [!2345]
6
+
7
+ respawn
8
+
9
+ chdir /var/www/<%= @name %>
10
+
11
+ script
12
+ for var in /root/.escualo/vars/*; do . \\$var; done
13
+ <%= @launch_command %>
14
+ end script
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: escualo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
@@ -14,44 +14,44 @@ dependencies:
14
14
  name: commander
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '4.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '4.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: net-ssh
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '2.9'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '2.9'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: net-scp
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: '1.2'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: '1.2'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mumukit-core
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -120,9 +120,41 @@ extra_rdoc_files: []
120
120
  files:
121
121
  - bin/escualo
122
122
  - lib/command.rb
123
+ - lib/commands/artifact.rb
124
+ - lib/commands/bootstrap.rb
125
+ - lib/commands/deploy.rb
126
+ - lib/commands/env.rb
127
+ - lib/commands/globals.rb
128
+ - lib/commands/plugin.rb
129
+ - lib/commands/rake.rb
130
+ - lib/commands/remote.rb
131
+ - lib/commands/script.rb
132
+ - lib/commands/upload.rb
123
133
  - lib/escualo.rb
134
+ - lib/escualo/artifact.rb
135
+ - lib/escualo/bootstrap.rb
136
+ - lib/escualo/env.rb
137
+ - lib/escualo/plugin.rb
138
+ - lib/escualo/plugin/docker.rb
139
+ - lib/escualo/plugin/haskell.rb
140
+ - lib/escualo/plugin/mongo.rb
141
+ - lib/escualo/plugin/nginx.rb
142
+ - lib/escualo/plugin/node.rb
143
+ - lib/escualo/plugin/postgre.rb
144
+ - lib/escualo/plugin/rabbit.rb
145
+ - lib/escualo/remote.rb
146
+ - lib/escualo/version.rb
124
147
  - lib/ssh.rb
148
+ - lib/ssh/local_session.rb
149
+ - lib/ssh/perform.rb
150
+ - lib/ssh/session.rb
151
+ - lib/ssh/upload.rb
125
152
  - lib/template.rb
153
+ - lib/templates/codechange.sh.erb
154
+ - lib/templates/init.sh.erb
155
+ - lib/templates/monit.conf.erb
156
+ - lib/templates/post-receive.sh.erb
157
+ - lib/templates/upstart.conf.erb
126
158
  homepage: http://github.com/mumuki/escualo.rb
127
159
  licenses:
128
160
  - MIT
@@ -132,6 +164,7 @@ post_install_message:
132
164
  rdoc_options: []
133
165
  require_paths:
134
166
  - lib
167
+ - bin
135
168
  required_ruby_version: !ruby/object:Gem::Requirement
136
169
  requirements:
137
170
  - - ">="