taperole 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/CONTRIBUTING.md +8 -0
- data/README.md +33 -4
- data/Rakefile +6 -0
- data/Vagrantfile +6 -7
- data/bin/tape +2 -89
- data/lib/taperole/commands/ansible.rb +56 -0
- data/lib/taperole/commands/installer.rb +19 -0
- data/lib/taperole/commands/tape.rb +32 -0
- data/lib/taperole/core/ansible_runner.rb +86 -0
- data/lib/taperole/core/installer.rb +87 -0
- data/lib/taperole/core/notifier.rb +47 -0
- data/lib/taperole/helpers/files.rb +76 -0
- data/lib/taperole/helpers/logging.rb +37 -0
- data/lib/taperole/notifiers/slack.rb +83 -0
- data/lib/taperole/version.rb +3 -0
- data/lib/taperole.rb +24 -0
- data/requirements.yml +1 -1
- data/roles/backend_checkout/tasks/main.yml +1 -0
- data/roles/delayed_job/tasks/main.yml +0 -15
- data/roles/deployer_user/tasks/keys.yml +6 -6
- data/roles/deployer_user/tasks/main.yml +0 -3
- data/roles/monit_install/tasks/main.yml +6 -0
- data/roles/monit_install/templates/monitrc.j2 +290 -0
- data/roles/nginx/tasks/main.yml +3 -4
- data/roles/nginx/templates/nginx_unicorn.j2 +1 -0
- data/roles/node/tasks/main.yml +2 -1
- data/roles/ruby/tasks/main.yml +3 -11
- data/roles/unicorn_install/tasks/main.yml +0 -3
- data/roles/unicorn_install/templates/unicorn.rb.j2 +1 -1
- data/roles/unicorn_install/templates/unicorn_init.j2 +1 -1
- data/roles/unicorn_install/templates/unicorn_monit.j2 +1 -1
- data/spec/commands/installer_spec.rb +117 -0
- data/spec/spec_helper.rb +24 -0
- data/taperole.gemspec +8 -1
- data/templates/base/deploy.example.yml +1 -0
- data/templates/base/hosts.example +1 -1
- data/templates/base/omnibox.example.yml +15 -0
- data/templates/base/rake.example.yml +18 -0
- data/templates/base/tape_vars.example.yml +9 -8
- data/templates/static_html/omnibox.example.yml +13 -0
- data/test/base_docker_box/Dockerfile +1 -1
- data/test/rails/Dockerfile +3 -3
- data/test/rails/start_rails.sh +1 -0
- data/test/rails/tape_vars.yml +2 -2
- data/vendor/ANXS.postgresql/.travis.yml +27 -12
- data/vendor/ANXS.postgresql/README.md +1 -1
- data/vendor/ANXS.postgresql/Vagrantfile +7 -2
- data/vendor/ANXS.postgresql/meta/.galaxy_install_info +1 -1
- data/vendor/ANXS.postgresql/meta/main.yml +1 -1
- data/vendor/ANXS.postgresql/tasks/configure.yml +10 -10
- data/vendor/ANXS.postgresql/tasks/databases.yml +27 -27
- data/vendor/ANXS.postgresql/tasks/install_yum.yml +2 -2
- data/vendor/ANXS.postgresql/tasks/users.yml +4 -4
- data/vendor/ANXS.postgresql/tasks/users_privileges.yml +3 -3
- data/vendor/ANXS.postgresql/tests/Dockerfile-centos6 +20 -0
- data/vendor/ANXS.postgresql/tests/Dockerfile-ubuntu14.04 +17 -0
- data/vendor/ANXS.postgresql/tests/playbook.yml +1 -1
- data/vendor/ANXS.postgresql/tests/vars.yml +2 -0
- data/vendor/Stouts.backup/.bumpversion.cfg +1 -1
- data/vendor/Stouts.backup/.travis.yml +0 -1
- data/vendor/Stouts.backup/CONTRIBUTORS +2 -0
- data/vendor/Stouts.backup/README.md +1 -0
- data/vendor/Stouts.backup/defaults/main.yml +3 -3
- data/vendor/Stouts.backup/meta/.galaxy_install_info +1 -1
- data/vendor/Stouts.backup/runtests.sh +65 -0
- data/vendor/Stouts.backup/tasks/backup.yml +3 -0
- data/vendor/Stouts.backup/tasks/configure.yml +13 -12
- data/vendor/Stouts.backup/tasks/install.deb.yml +6 -8
- data/vendor/Stouts.backup/tasks/install.red.yml +28 -0
- data/vendor/Stouts.backup/tasks/remove.yml +3 -3
- data/vendor/Stouts.backup/templates/cron.j2 +1 -1
- data/vendor/Stouts.backup/templates/duply.sh.j2 +219 -218
- data/vendor/Stouts.backup/templates/pre.j2 +6 -0
- data/vendor/Stouts.backup/templates/restore.j2 +6 -0
- data/vendor/Stouts.backup/vars/Debian.yml +3 -0
- data/vendor/Stouts.backup/vars/Ubuntu.yml +1 -0
- metadata +67 -10
- data/lib/tape/ansible_runner.rb +0 -130
- data/lib/tape/info.rb +0 -9
- data/lib/tape/installer.rb +0 -160
- data/lib/tape/notifiers/slack.rb +0 -79
- data/lib/tape/overwriter.rb +0 -14
- data/lib/tape/qemu_provisioner.rb +0 -167
- data/lib/tape.rb +0 -127
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21ca9a88b00c6e0ed2f77b29937b871038b3f911
|
4
|
+
data.tar.gz: 4768be3843152356b7add30fbe8e5e3dedfcaad2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3c6f367b84e1b0b339fd4f768cf079e36279e3e35b310924de4d04836a4637a4706b4cb635bc1d09c895518a40f78ca04755250610b04618a2636531c117fd9
|
7
|
+
data.tar.gz: 5e1b9437c2ebfc85bdb591af65f4040ead65ec91977c7d3678c416ee86a1af4449fec373754284e33a580c0568a2e86a6b99c8a1f2790372e4cebacfd7c96a77
|
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -5,6 +5,14 @@
|
|
5
5
|
###Workflow
|
6
6
|
We use [Waffle.io](https://waffle.io/smashingboxes/tape) to manage our workflow for this project. Please respect the workflow and move PRs that are ready to be mereged into the 'Ready' column.
|
7
7
|
|
8
|
+
####Testing
|
9
|
+
|
10
|
+
There are two main ways we test taperole. The first is basic unit tests, via rspec. Those can be run via:
|
11
|
+
|
12
|
+
`rake test`
|
13
|
+
|
14
|
+
The second way is a kind of integration test. We use tape to stand up a basic vanilla rails app (leveraging docker) and then check that a curl returns the correct thing. There isn't an easy way to run this locally, but it is set up on travis to run automatically.
|
15
|
+
|
8
16
|
###PR Structure
|
9
17
|
|
10
18
|
Please give details regarding your PR in the following format. It really helps with review and quickens the speed at which your changes are merged in
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Infrastructure Management
|
4
4
|
|
5
5
|
## Deploying & provisioning with tape
|
6
|
-
**Use Unbuntu trusty64 (
|
6
|
+
**Use Unbuntu trusty64 (16 x64)**
|
7
7
|
|
8
8
|
**Enable ssh access via root user**
|
9
9
|
|
@@ -45,9 +45,30 @@ All default configurations found in `vars/defaults.yml` can be overridden in you
|
|
45
45
|
**Default Ruby Version** 2.3.0
|
46
46
|
|
47
47
|
### Backups
|
48
|
-
Backups are handled via [duply](http://duply.net/) and occur every night at 4am under the root user. You can configure your backup schedule and target where you want your backups stored at within your `taperole/tape_vars.yml` file.
|
48
|
+
Backups are handled via [duply](http://duply.net/) and are configured via the [Stouts.backup](https://github.com/Stouts/Stouts.backup) ansible galaxy role. Bacups occur every night at 4am under the root user. You can configure your backup schedule and target where you want your backups stored at within your `taperole/tape_vars.yml` file.
|
49
49
|
|
50
|
-
|
50
|
+
The default location for backups is the `/var/lib/postgresql/backups` directory.
|
51
|
+
|
52
|
+
All servers in your [production] group will have backups enabled by default.
|
53
|
+
|
54
|
+
Detailed configurations can be made in your tape_vars.yml file.
|
55
|
+
|
56
|
+
```
|
57
|
+
# Store Backups on S3
|
58
|
+
backup_dir: s3+http://[aws_access_key:aws_secret_access_key]@bucket_name[/folder]
|
59
|
+
|
60
|
+
# Store Backups on Seperate server via rsync
|
61
|
+
backup_dir: s3+http://[aws_access_key:aws_secret_access_key]@bucket_name[/folder]
|
62
|
+
|
63
|
+
# Adjust Cron Job Schedule (default is every night at 4am)
|
64
|
+
backup_schedule: "* */4 * * *"
|
65
|
+
|
66
|
+
# Change Which Servers are backed up
|
67
|
+
backup_hosts:
|
68
|
+
- production
|
69
|
+
- staging
|
70
|
+
- qa
|
71
|
+
```
|
51
72
|
|
52
73
|
### Custom roles
|
53
74
|
You can add app specific ansible roles to `<app_root>/roles`.
|
@@ -93,7 +114,7 @@ localhost:2222 ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key
|
|
93
114
|
The port number might be different if other vagrant machines are running, run `vagrant ssh-config` to find the correct configuration.
|
94
115
|
You can specify a port using the `ansible_ssh_port` in your hosts inventory file.
|
95
116
|
|
96
|
-
3. Update `tape_vars.yml` with information to a
|
117
|
+
3. Update `tape_vars.yml` with information to a rails app you want to deploy
|
97
118
|
4. `tape ansible everything -l vagrant`
|
98
119
|
|
99
120
|
### With Docker
|
@@ -235,6 +256,14 @@ This will git pull the latest changes from the tracking branch you specified and
|
|
235
256
|
|
236
257
|
This command runs all Ansible roles specified in the deploy.yml playbook.
|
237
258
|
|
259
|
+
### Rake tasks
|
260
|
+
|
261
|
+
To run ad-hoc rake tasks, you can use the following:
|
262
|
+
|
263
|
+
```
|
264
|
+
tape ansible rake --task users:rank
|
265
|
+
```
|
266
|
+
|
238
267
|
## Slack integration
|
239
268
|
|
240
269
|
Tape includes built-in support for posting messages to slack at the beginning and end of deployments.
|
data/Rakefile
ADDED
data/Vagrantfile
CHANGED
@@ -2,25 +2,24 @@
|
|
2
2
|
# vi: set ft=ruby :
|
3
3
|
|
4
4
|
Vagrant.configure 2 do |config|
|
5
|
-
config.vm.box =
|
5
|
+
config.vm.box = "ubuntu/xenial64"
|
6
6
|
|
7
|
-
name = %x[basename `git rev-parse --show-toplevel`].chomp
|
7
|
+
name = %x[basename `git rev-parse --show-toplevel`].chomp.gsub(/[^0-9a-z ]/i, '')
|
8
8
|
config.vm.define "#{name}_vagrant_box"
|
9
|
+
config.vm.hostname = "#{name}"
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
private_ip = "192.168.13.37"
|
12
|
+
config.vm.network(:private_network, :ip => private_ip)
|
12
13
|
|
13
|
-
# TODO free me from the bonds of this ip
|
14
14
|
config.vm.network 'forwarded_port', guest: 443, host: 8080
|
15
15
|
config.vm.network 'private_network', type: 'dhcp'
|
16
16
|
|
17
|
-
config.ssh.insert_key = false
|
18
17
|
config.ssh.shell = 'bash -c "BASH_ENV=/etc/profile exec bash"'
|
19
18
|
|
20
19
|
config.vm.provision :shell, inline: <<-SCRIPT
|
21
20
|
sudo su
|
22
21
|
mkdir -p ~/.ssh/
|
23
|
-
cp /home/
|
22
|
+
cp /home/ubuntu/.ssh/authorized_keys ~/.ssh/
|
24
23
|
chmod 600 ~/.ssh/authorized_keys
|
25
24
|
SCRIPT
|
26
25
|
end
|
data/bin/tape
CHANGED
@@ -1,92 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
3
|
+
require 'taperole'
|
4
4
|
|
5
|
-
|
6
|
-
require 'ostruct'
|
7
|
-
require 'tape'
|
8
|
-
|
9
|
-
options = OpenStruct.new
|
10
|
-
opt_parser = OptionParser.new do |opts|
|
11
|
-
opts.banner = "Usage: tape <module> <action> [options]"
|
12
|
-
|
13
|
-
opts.on("-v", "--[no-]verbose", "Be loud") {|v| options.verbose = v}
|
14
|
-
opts.on("--ask-vault-pass", "Ask for Ansible vault password") { options.vault = true }
|
15
|
-
|
16
|
-
opts.on("-i", "--inventory [INVENTORY_FILE]",
|
17
|
-
String, "Do actions with the given inventory file") do |i|
|
18
|
-
options.inventory_file = i
|
19
|
-
end
|
20
|
-
|
21
|
-
opts.on('-n', "--name [NAME]",
|
22
|
-
String, "The name of the machine to operate on") do |n|
|
23
|
-
options.name = n
|
24
|
-
end
|
25
|
-
|
26
|
-
opts.on('-p', "--port [PORT]",
|
27
|
-
Integer, "The port that the machine is listening on for SSH connections") do |p|
|
28
|
-
options.port = p
|
29
|
-
end
|
30
|
-
|
31
|
-
opts.on('-bBOOK', "--book=PLAYBOOK",
|
32
|
-
String, "A custom playbook to run") do |p|
|
33
|
-
options.book = p
|
34
|
-
end
|
35
|
-
|
36
|
-
opts.on("-h", "--help", "Show this help") do
|
37
|
-
STDERR.puts opts
|
38
|
-
exit 0
|
39
|
-
end
|
40
|
-
|
41
|
-
opts.on("-l", "--limit [PATTERN]",
|
42
|
-
String, "Limits ansible runs to hosts matching PATTERN") do |p|
|
43
|
-
options.host_pattern = p
|
44
|
-
end
|
45
|
-
|
46
|
-
opts.on("-t", "--tags [TAGS]",
|
47
|
-
String, "only run plays and tasks tagged with these values") do |t|
|
48
|
-
options.tags = t
|
49
|
-
end
|
50
|
-
|
51
|
-
opts.on("-r", "--role=ROLE_NAME",
|
52
|
-
String, "name of the role to operate on") do |r|
|
53
|
-
options.role = r
|
54
|
-
end
|
55
|
-
|
56
|
-
opts.separator ''
|
57
|
-
opts.separator "MODULES"
|
58
|
-
TapeBoxer.registered_modules.values.each do |exec_module|
|
59
|
-
opts.separator " #{exec_module.name.to_s.upcase}"
|
60
|
-
exec_module.klass.actions.values.each do |action|
|
61
|
-
opts.separator " #{action.name}: #{action.description}"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
opt_parser.parse!(ARGV)
|
68
|
-
|
69
|
-
fail_without = ->(&block){
|
70
|
-
val = block.call
|
71
|
-
|
72
|
-
if val
|
73
|
-
return val
|
74
|
-
else
|
75
|
-
STDERR.puts(opt_parser.help)
|
76
|
-
exit 1
|
77
|
-
end
|
78
|
-
}
|
79
|
-
|
80
|
-
module_name = fail_without.call{ ARGV.shift }.to_sym
|
81
|
-
action_name = fail_without.call{ ARGV.shift }.to_sym
|
82
|
-
|
83
|
-
exec_module = fail_without.call{TapeBoxer.registered_modules[module_name]}
|
84
|
-
|
85
|
-
begin
|
86
|
-
exec_module.klass.new(options).execute_action(action_name)
|
87
|
-
rescue TapeBoxer::InvalidAction,
|
88
|
-
TapeBoxer::ActionError, TapeBoxer::UnspecifiedOption => e
|
89
|
-
|
90
|
-
STDERR.puts(e.message)
|
91
|
-
exit 2
|
92
|
-
end
|
5
|
+
Taperole::Commands::Tape.start(ARGV)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Taperole
|
2
|
+
module Commands
|
3
|
+
class Ansible < Thor
|
4
|
+
include Taperole::AnsibleRunner
|
5
|
+
include Taperole::Helpers::Logging
|
6
|
+
|
7
|
+
class_option :limit,
|
8
|
+
type: :string,
|
9
|
+
aliases: :l,
|
10
|
+
desc: 'Limits ansible runs to hosts matching the given pattern'
|
11
|
+
class_option :task,
|
12
|
+
type: :string,
|
13
|
+
aliases: :T,
|
14
|
+
desc: 'Name of the rake task to execute'
|
15
|
+
class_option :inventory,
|
16
|
+
aliases: :i,
|
17
|
+
type: :string,
|
18
|
+
desc: 'Do actions with the given inventory file'
|
19
|
+
class_option :name,
|
20
|
+
aliases: :n,
|
21
|
+
type: :string,
|
22
|
+
desc: 'The name of the machine to operate on'
|
23
|
+
class_option :port,
|
24
|
+
aliases: :p,
|
25
|
+
type: :numeric,
|
26
|
+
desc: 'The port that the machine is listening on for SSH connections'
|
27
|
+
class_option :tags,
|
28
|
+
aliases: :t,
|
29
|
+
type: :string,
|
30
|
+
desc: 'Only run plays and tasks tagged with these values'
|
31
|
+
class_option :role,
|
32
|
+
aliases: :r,
|
33
|
+
type: :string,
|
34
|
+
desc: 'Name of the role to operate on'
|
35
|
+
|
36
|
+
class_option :'ask-vault-pass', type: :boolean, desc: 'Ask for Ansible vault password'
|
37
|
+
|
38
|
+
class_option :book,
|
39
|
+
aliases: :b,
|
40
|
+
type: :string,
|
41
|
+
desc: 'A custom playbook to run'
|
42
|
+
|
43
|
+
desc 'everything', 'Initial setup of a server'
|
44
|
+
def everything
|
45
|
+
Taperole::Notifier.register_notifiers(options)
|
46
|
+
valid_preconfigs ? ansible(options: options) : puts("Not a Rails or JS app")
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'deploy', 'Deploy the latest version of the app'
|
50
|
+
def deploy
|
51
|
+
Taperole::Notifier.register_notifiers(options)
|
52
|
+
ansible_deploy(args: '-t be_deploy,fe_deploy', options: options)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Taperole
|
2
|
+
module Commands
|
3
|
+
class Installer < Thor
|
4
|
+
include Taperole::Installer
|
5
|
+
include Taperole::Helpers::Logging
|
6
|
+
|
7
|
+
option :vagrant, type: :boolean
|
8
|
+
desc 'install', 'Creates all necessary hosts and config files'
|
9
|
+
def install
|
10
|
+
install_tape
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'uninstall', 'Cleans up files generated by the installer'
|
14
|
+
def uninstall
|
15
|
+
uninstall_tape
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module Taperole
|
4
|
+
module Commands
|
5
|
+
class Tape < Thor
|
6
|
+
include Taperole::Helpers::Files
|
7
|
+
include Taperole::Helpers::Logging
|
8
|
+
|
9
|
+
class_option :verbose, type: :boolean
|
10
|
+
class_option :debug, type: :boolean
|
11
|
+
class_option :quiet, type: :boolean
|
12
|
+
|
13
|
+
map %w[--version -v] => :__print_version
|
14
|
+
|
15
|
+
desc "--version, -v", "print the version"
|
16
|
+
def __print_version
|
17
|
+
puts Taperole::VERSION
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'ansible [COMMAND]', 'run tapes ansible commands'
|
21
|
+
subcommand 'ansible', Ansible
|
22
|
+
|
23
|
+
desc 'installer [COMMAND]', 'install and uninstall tape'
|
24
|
+
subcommand 'installer', Installer
|
25
|
+
|
26
|
+
desc 'overwrite [ROLE]', 'Overwrite a taperole ansible role'
|
27
|
+
def overwrite_role(role)
|
28
|
+
FileUtils.cp_r("#{tape_dir}/roles/#{role}", "taperole/roles/")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Taperole
|
2
|
+
module AnsibleRunner
|
3
|
+
include Taperole::Helpers::Files
|
4
|
+
|
5
|
+
protected
|
6
|
+
|
7
|
+
def valid_preconfigs
|
8
|
+
if rails_app?
|
9
|
+
valid_gems
|
10
|
+
elsif fe_app?
|
11
|
+
true
|
12
|
+
else
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid_gems
|
18
|
+
has_gem_in_gemfile?('unicorn')
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_gem_in_gemfile?(name)
|
22
|
+
if open('Gemfile').grep(/#{name}/).empty?
|
23
|
+
logger.error "💥 ERROR: Add #{name} to your Gemfile!💥 ".red
|
24
|
+
false
|
25
|
+
else
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def ansible(args: '', options: {})
|
31
|
+
exec_ansible("#{tapefiles_dir}/omnibox.yml", args, options)
|
32
|
+
end
|
33
|
+
|
34
|
+
def ansible_deploy(args: '', options: {})
|
35
|
+
exec_ansible("#{tapefiles_dir}/deploy.yml", args, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def ansible_custom_playbook(args: '', options: {})
|
39
|
+
exec_ansible("#{tapefiles_dir}/#{options[:book]}", args, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ansible_rake_task(options: {})
|
43
|
+
exec_ansible("#{tapefiles_dir}/rake.yml", "--extra-vars \"task=#{options[:task]}\"", options)
|
44
|
+
end
|
45
|
+
|
46
|
+
def exec_ansible(playbook, args, options)
|
47
|
+
enforce_roles_path!
|
48
|
+
cmd = "ANSIBLE_CONFIG=#{local_dir}/.tape/ansible.cfg ansible-playbook -i"
|
49
|
+
cmd += " #{inventory_file(options)} #{playbook} #{args} #{hosts_flag(options)}"
|
50
|
+
cmd += " -e tape_dir=#{tape_dir}"
|
51
|
+
cmd += ' --ask-vault-pass' if options[:vault]
|
52
|
+
cmd += ' -vvvv' if options[:verbose]
|
53
|
+
cmd += " -t #{options[:tags]}" if options[:tags]
|
54
|
+
logger.info "Executing: #{cmd}" if options[:verbose]
|
55
|
+
Taperole::Notifier.notify_observers(:start)
|
56
|
+
if Kernel.system(cmd)
|
57
|
+
Taperole::Notifier.notify_observers(:success)
|
58
|
+
else
|
59
|
+
Taperole::Notifier.notify_observers(:fail)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def enforce_roles_path!
|
64
|
+
Dir.mkdir('.tape') unless Dir.exist?('.tape')
|
65
|
+
|
66
|
+
File.open("#{local_dir}/.tape/ansible.cfg", 'w') do |f|
|
67
|
+
f.puts '[defaults]'
|
68
|
+
f.puts "roles_path=.tape/roles:#{tape_dir}/roles:#{tape_dir}/vendor"
|
69
|
+
f.puts "inventory=#{tapefiles_dir}/hosts"
|
70
|
+
f.puts "retries-dir=/dev/null"
|
71
|
+
f.puts "retry_files_enabled = False"
|
72
|
+
f.puts '[ssh_connection]'
|
73
|
+
f.puts 'ssh_args=-o ForwardAgent=yes'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def hosts_flag(options)
|
78
|
+
limit = options[:limit]
|
79
|
+
"-l #{limit}" if limit
|
80
|
+
end
|
81
|
+
|
82
|
+
def inventory_file(options)
|
83
|
+
options[:inventory_file] || "#{tapefiles_dir}/hosts"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Taperole
|
4
|
+
module Installer
|
5
|
+
include Taperole::Helpers::Files
|
6
|
+
include Thor::Actions
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def install_tape
|
11
|
+
add_tape_to_gitignore
|
12
|
+
mkdir tapefiles_dir
|
13
|
+
create_tape_files
|
14
|
+
create_roles_dir
|
15
|
+
create_inventory_file
|
16
|
+
create_ssh_keys_dir
|
17
|
+
handle_vagrantfile
|
18
|
+
end
|
19
|
+
|
20
|
+
def uninstall_tape
|
21
|
+
rm "#{tapefiles_dir}/omnibox.yml"
|
22
|
+
rm "#{tapefiles_dir}/deploy.yml"
|
23
|
+
rm "#{tapefiles_dir}/tape_vars.yml"
|
24
|
+
rm "#{tapefiles_dir}/rake.yml"
|
25
|
+
rm "#{tapefiles_dir}/roles"
|
26
|
+
rm "#{tapefiles_dir}/hosts"
|
27
|
+
rm "#{local_dir}/dev_keys"
|
28
|
+
rm "#{local_dir}/Vagrantfile"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def add_tape_to_gitignore
|
34
|
+
File.open('.gitignore', 'r+') { |f| f.puts '.tape' unless f.read =~ /^\.tape$/ }
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_tape_files
|
38
|
+
if fe_app? && !rails_app?
|
39
|
+
logger.info '🔎 JS/HTML app detected'.red
|
40
|
+
copy_static_app_examples
|
41
|
+
elsif rails_app?
|
42
|
+
logger.info '🔎 Rails app detected'.red
|
43
|
+
copy_basic_examples
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def copy_static_app_examples
|
48
|
+
%w(omnibox deploy tape_vars).each do |base_filename|
|
49
|
+
copy_example(
|
50
|
+
"templates/static_html/#{base_filename}.example.yml",
|
51
|
+
"#{tapefiles_dir}/#{base_filename}.yml"
|
52
|
+
)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def copy_basic_examples
|
57
|
+
%w(omnibox deploy tape_vars rake).each do |base_filename|
|
58
|
+
copy_example(
|
59
|
+
"templates/base/#{base_filename}.example.yml",
|
60
|
+
"#{tapefiles_dir}/#{base_filename}.yml"
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_roles_dir
|
66
|
+
mkdir "#{tapefiles_dir}/roles"
|
67
|
+
`touch #{tapefiles_dir}/roles/.keep`
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_inventory_file
|
71
|
+
copy_example 'templates/base/hosts.example', "#{tapefiles_dir}/hosts"
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_ssh_keys_dir
|
75
|
+
mkdir "#{local_dir}/dev_keys"
|
76
|
+
end
|
77
|
+
|
78
|
+
def handle_vagrantfile
|
79
|
+
if options[:vagrant].nil?
|
80
|
+
options[:vagrant] = ask('Are you going to use vagrant? (y/n): ')
|
81
|
+
end
|
82
|
+
if options[:vagrant]
|
83
|
+
copy_example 'Vagrantfile', 'Vagrantfile'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Taperole
|
5
|
+
class Notifier
|
6
|
+
include ::Singleton
|
7
|
+
|
8
|
+
attr_accessor :observers
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@observers = []
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
include Taperole::Helpers::Files
|
16
|
+
|
17
|
+
def register_notifiers(options)
|
18
|
+
if config["slack_webhook_url"]
|
19
|
+
slack_notifier = Taperole::Notifiers::Slack.new(
|
20
|
+
config["slack_webhook_url"],
|
21
|
+
deploy_info(options)
|
22
|
+
)
|
23
|
+
instance.observers.push(slack_notifier)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def config
|
28
|
+
@config ||= YAML.load_file("#{tapefiles_dir}/tape_vars.yml")
|
29
|
+
end
|
30
|
+
|
31
|
+
def deploy_info(options)
|
32
|
+
{
|
33
|
+
app_name: config["app_name"],
|
34
|
+
user: `whoami`.chomp,
|
35
|
+
hosts: options[:limit] || 'default',
|
36
|
+
repo: config["be_app_repo"] || ''
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def notify_observers(state)
|
41
|
+
instance.observers.each do |observer|
|
42
|
+
observer.update(state)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Taperole
|
2
|
+
module Helpers
|
3
|
+
module Files
|
4
|
+
def fe_app?
|
5
|
+
!Dir["#{local_dir}/package.json"].empty?
|
6
|
+
end
|
7
|
+
|
8
|
+
def rails_app?
|
9
|
+
!Dir["#{local_dir}/config.ru"].empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def tape_dir
|
13
|
+
File.realpath(File.join(__dir__, '../../../'))
|
14
|
+
end
|
15
|
+
|
16
|
+
def local_dir
|
17
|
+
Dir.pwd
|
18
|
+
end
|
19
|
+
|
20
|
+
def tapefiles_dir
|
21
|
+
local_dir + '/taperole'
|
22
|
+
end
|
23
|
+
|
24
|
+
def tapecfg_dir
|
25
|
+
local_dir + '/.tape'
|
26
|
+
end
|
27
|
+
|
28
|
+
def rm(file)
|
29
|
+
logger.info 'Deleting '.red + file
|
30
|
+
FileUtils.rm_r file
|
31
|
+
end
|
32
|
+
|
33
|
+
def mkdir(name)
|
34
|
+
file_text = "#{::Pathname.new(name).basename}: "
|
35
|
+
begin
|
36
|
+
FileUtils.mkdir name
|
37
|
+
success(file_text)
|
38
|
+
rescue Errno::EEXIST
|
39
|
+
exists(file_text)
|
40
|
+
rescue StandardError => e
|
41
|
+
error(file_text)
|
42
|
+
raise e
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def copy_example(file, cp_file)
|
47
|
+
file_text = "#{::Pathname.new(cp_file).basename}: "
|
48
|
+
begin
|
49
|
+
if File.exist?(cp_file.to_s)
|
50
|
+
exists(file_text)
|
51
|
+
else
|
52
|
+
FileUtils.cp("#{tape_dir}/#{file}", cp_file.to_s)
|
53
|
+
success(file_text)
|
54
|
+
end
|
55
|
+
rescue StandardError => e
|
56
|
+
error(file_text)
|
57
|
+
raise e
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def success(file_text)
|
64
|
+
logger.info file_text + '✔'.green
|
65
|
+
end
|
66
|
+
|
67
|
+
def error(file_text)
|
68
|
+
logger.info file_text + '✘'.red
|
69
|
+
end
|
70
|
+
|
71
|
+
def exists(file_text)
|
72
|
+
logger.info file_text + '✘ (Exists)'.yellow
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Taperole
|
4
|
+
module Helpers
|
5
|
+
module Logging
|
6
|
+
def initialize(*_args)
|
7
|
+
super
|
8
|
+
logger.level = logger_level
|
9
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
10
|
+
"#{msg}\n"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def logger
|
15
|
+
Logging.logger
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.logger
|
19
|
+
@logger ||= Logger.new(STDOUT)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def logger_level
|
25
|
+
if options[:debug]
|
26
|
+
Logger::DEBUG
|
27
|
+
elsif options[:verbose]
|
28
|
+
Logger::INFO
|
29
|
+
elsif options[:quiet]
|
30
|
+
Logger::ERROR
|
31
|
+
else
|
32
|
+
Logger::INFO
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|