escualo 0.2.1 → 0.2.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
  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
  - - ">="