ops_preflight 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/preflight +5 -0
- data/bin/preflight-server +5 -0
- data/data/deploy.rb +141 -0
- data/data/preflight.yml +22 -0
- data/lib/ops_preflight/client.rb +50 -0
- data/lib/ops_preflight/config.rb +49 -0
- data/lib/ops_preflight/exit_code.rb +8 -0
- data/lib/ops_preflight/ops_works/base.rb +29 -0
- data/lib/ops_preflight/ops_works/deploy.rb +51 -0
- data/lib/ops_preflight/ops_works/fetch_environment.rb +34 -0
- data/lib/ops_preflight/s3_transfer.rb +43 -0
- data/lib/ops_preflight/server.rb +45 -0
- data/lib/ops_preflight/tasks.rb +58 -0
- data/lib/ops_preflight/version.rb +3 -0
- data/lib/ops_preflight.rb +17 -0
- data/ops_preflight.gemspec +25 -0
- metadata +152 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2013 Ryan Schlesinger
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# OpsPreflight
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'ops_preflight'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install ops_preflight
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/preflight
ADDED
data/data/deploy.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'mina/bundler'
|
2
|
+
require 'mina/rails'
|
3
|
+
require 'mina/git'
|
4
|
+
# require 'mina/rbenv' # for rbenv support. (http://rbenv.org)
|
5
|
+
# require 'mina/rvm' # for rvm support. (http://rvm.io)
|
6
|
+
require 'ops_preflight/tasks'
|
7
|
+
|
8
|
+
# Basic settings:
|
9
|
+
# domain - The hostname to SSH to.
|
10
|
+
# deploy_to - Path to deploy into.
|
11
|
+
# repository - Git repo to clone from. (needed by mina/git)
|
12
|
+
# branch - Branch name to deploy. (needed by mina/git)
|
13
|
+
|
14
|
+
set :user, ENV['USER'] # Username in the server to SSH to.
|
15
|
+
set :domain, ENV['DOMAIN']
|
16
|
+
set :app_name, ENV['APP_NAME']
|
17
|
+
set :deploy_to, lambda { "/home/#{settings.user!}/preflight-#{settings.app_name!}-#{settings.rails_env!}" }
|
18
|
+
set :repository, ENV['REPOSITORY']
|
19
|
+
set :branch, ENV['BRANCH']
|
20
|
+
|
21
|
+
# set :rbenv_path, '/usr/local/rbenv'
|
22
|
+
set :preflight_bucket, ENV['PREFLIGHT_BUCKET']
|
23
|
+
settings.delete(:rails_env)
|
24
|
+
|
25
|
+
set :run_db_migrate, ENV['RUN_DB_MIGRATE']
|
26
|
+
set :use_turbo_sprockets, ENV['USE_TURBO_SPROCKETS']
|
27
|
+
set :use_env_file, ENV['USE_ENV_FILE']
|
28
|
+
|
29
|
+
# Manually create these paths in shared/ (eg: shared/config/database.yml) in your server.
|
30
|
+
# They will be linked in the 'deploy:link_shared_paths' step.
|
31
|
+
set :shared_paths, lambda { generate_shared_paths }
|
32
|
+
|
33
|
+
# Optional settings:
|
34
|
+
# set :port, '30000' # SSH port number.
|
35
|
+
|
36
|
+
# This task is the environment that is loaded for most commands, such as
|
37
|
+
# `mina deploy` or `mina rake`.
|
38
|
+
task :environment do
|
39
|
+
# If you're using rbenv, use this to load the rbenv environment.
|
40
|
+
# Be sure to commit your .rbenv-version to your repository.
|
41
|
+
# queue %{export RBENV_ROOT=#{rbenv_path}}
|
42
|
+
# invoke :'rbenv:load'
|
43
|
+
|
44
|
+
# For those using RVM, use this to load an RVM version@gemset.
|
45
|
+
# invoke :'rvm:use[ruby-1.9.3-p125@default]'
|
46
|
+
|
47
|
+
unless settings.rails_env?
|
48
|
+
if ENV['RAILS_ENV']
|
49
|
+
set :rails_env, ENV['RAILS_ENV']
|
50
|
+
elsif ENV['RACK_ENV']
|
51
|
+
set :rails_env, ENV['RACK_ENV']
|
52
|
+
else
|
53
|
+
print_error(unindent(%[
|
54
|
+
Application environment must be specified.
|
55
|
+
Use deploy RAILS_ENV=<environment> or deploy RACK_ENV=<environment>
|
56
|
+
Preflight supports this with `preflight deploy <environment>`
|
57
|
+
]))
|
58
|
+
die(2)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
[:user, :domain, :app_name, :repository, :branch, :preflight_bucket, :use_turbo_sprockets, :use_env_file].each do |var|
|
63
|
+
if settings[var].nil?
|
64
|
+
print_error(unindent(%[
|
65
|
+
Setting #{var.to_s} must be specified.
|
66
|
+
]))
|
67
|
+
die(2)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
# Put any custom mkdir's in here for when `mina setup` is ran.
|
74
|
+
# For Rails apps, we'll make some of the shared paths that are shared between
|
75
|
+
# all releases.
|
76
|
+
task :setup => :environment do
|
77
|
+
queue! %[mkdir -p "#{deploy_to}/shared/log"]
|
78
|
+
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]
|
79
|
+
|
80
|
+
queue! %[mkdir -p "#{deploy_to}/shared/config"]
|
81
|
+
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]
|
82
|
+
|
83
|
+
if settings.use_turbo_sprockets! == 'true'
|
84
|
+
queue! %[mkdir -p "#{deploy_to}/shared/public/assets"]
|
85
|
+
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/public/assets"]
|
86
|
+
end
|
87
|
+
|
88
|
+
queue! %[touch "#{deploy_to}/shared/config/database.yml"]
|
89
|
+
|
90
|
+
queue %[echo "-----> Please add ForwardAgent yes to your ssh config for #{settings.domain!}"]
|
91
|
+
end
|
92
|
+
|
93
|
+
desc "Deploys the current version to the server."
|
94
|
+
task :deploy => :environment do
|
95
|
+
deploy do
|
96
|
+
# Put things that will set up an empty directory into a fully set-up
|
97
|
+
# instance of your project.
|
98
|
+
invoke :'git:clone'
|
99
|
+
invoke :'deploy:link_shared_paths'
|
100
|
+
invoke :'bundle:install'
|
101
|
+
|
102
|
+
if settings.use_env_file! == 'true'
|
103
|
+
invoke :'preflight:fetch_environment'
|
104
|
+
end
|
105
|
+
|
106
|
+
if settings.run_db_migrate! == 'true'
|
107
|
+
invoke :'rails:db_migrate'
|
108
|
+
end
|
109
|
+
|
110
|
+
if settings.use_turbo_sprockets! == 'true'
|
111
|
+
invoke :'rails:assets_precompile:force' # Defer to turbo sprockets
|
112
|
+
invoke :'preflight:assets_clean_expired'
|
113
|
+
else
|
114
|
+
invoke :'rails:assets_precompile'
|
115
|
+
end
|
116
|
+
|
117
|
+
to :launch do
|
118
|
+
invoke :'preflight:bundle'
|
119
|
+
invoke :'preflight:assets'
|
120
|
+
invoke :'preflight:deploy'
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def generate_shared_paths
|
126
|
+
path = ['config/database.yml', 'log']
|
127
|
+
|
128
|
+
if settings.use_turbo_sprockets! == 'true'
|
129
|
+
path << 'public/assets'
|
130
|
+
end
|
131
|
+
|
132
|
+
path
|
133
|
+
end
|
134
|
+
|
135
|
+
# For help in making your deploy script, see the Mina documentation:
|
136
|
+
#
|
137
|
+
# - http://nadarei.co/mina
|
138
|
+
# - http://nadarei.co/mina/tasks
|
139
|
+
# - http://nadarei.co/mina/settings
|
140
|
+
# - http://nadarei.co/mina/helpers
|
141
|
+
|
data/data/preflight.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
user: ec2-user
|
3
|
+
domain: preflight.example.com
|
4
|
+
app_name: example
|
5
|
+
|
6
|
+
repository: git@github.com:user/repo.git
|
7
|
+
|
8
|
+
preflight_bucket: org-preflight
|
9
|
+
|
10
|
+
run_db_migrate: false
|
11
|
+
use_turbo_sprockets: true
|
12
|
+
use_env_file: true
|
13
|
+
|
14
|
+
opsworks_app_name: appname
|
15
|
+
|
16
|
+
environments:
|
17
|
+
production:
|
18
|
+
branch: master
|
19
|
+
opsworks_stack_name: Production Example
|
20
|
+
staging:
|
21
|
+
branch: staging
|
22
|
+
opsworks_stack_name: Staging Example
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
class Client < Thor
|
3
|
+
include Thor::Actions
|
4
|
+
include ExitCode
|
5
|
+
|
6
|
+
namespace :default
|
7
|
+
|
8
|
+
source_root OpsPreflight.root_path
|
9
|
+
|
10
|
+
class_option :verbose, :aliases => '-v', :type => :boolean
|
11
|
+
class_option :simulate, :aliases => '-S', :type => :boolean
|
12
|
+
class_option :trace, :aliases => '-t', :type => :boolean
|
13
|
+
|
14
|
+
desc "init", "Initialize application to work with preflight"
|
15
|
+
def init
|
16
|
+
copy_file 'data/preflight.yml', 'config/preflight.yml'
|
17
|
+
say 'Please edit config/preflight.yml to finish setting up preflight.'
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "setup <rails_env>", "Set up the server's preflight environment"
|
21
|
+
def setup(rails_env)
|
22
|
+
run "bundle exec mina setup RAILS_ENV=#{rails_env} #{Config.new.client_args(rails_env)} #{mina_args}", :verbose => false
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "deploy <rails_env>", "Deploys to the configured app"
|
26
|
+
def deploy(rails_env)
|
27
|
+
run "bundle exec mina deploy RAILS_ENV=#{rails_env} #{Config.new.client_args(rails_env)} #{mina_args}", :verbose => false
|
28
|
+
end
|
29
|
+
|
30
|
+
# Fixes thor's banners when used with :default namespace
|
31
|
+
def self.banner(command, namespace = nil, subcommand = false)
|
32
|
+
"#{basename} #{command.formatted_usage(self, false, subcommand)}"
|
33
|
+
end
|
34
|
+
|
35
|
+
no_tasks do
|
36
|
+
def mina_args(*args)
|
37
|
+
args = "-f #{OpsPreflight.root_path('data', 'deploy.rb')}"
|
38
|
+
|
39
|
+
# mina's --verbose doesn't work
|
40
|
+
args << ' -v' if options[:verbose]
|
41
|
+
|
42
|
+
[:simulate, :trace].each do |opt|
|
43
|
+
args << " --#{opt.to_s}" if options[opt]
|
44
|
+
end
|
45
|
+
|
46
|
+
args
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
class Config
|
3
|
+
CONFIG_FILE = 'config/preflight.yml'
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
config
|
7
|
+
end
|
8
|
+
|
9
|
+
def client_args(rails_env)
|
10
|
+
str = ''
|
11
|
+
config.each do |var, value|
|
12
|
+
next if var == :environments
|
13
|
+
|
14
|
+
str << " #{var.to_s.upcase}='#{value}'"
|
15
|
+
end
|
16
|
+
|
17
|
+
if config[:environments] && config[:environments][rails_env.to_sym]
|
18
|
+
config[:environments][rails_env.to_sym].each do |var, value|
|
19
|
+
str << " #{var.to_s.upcase}='#{value}'"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
str
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
def config
|
28
|
+
@config ||= begin
|
29
|
+
new_config = YAML::load(ERB.new(File.read(CONFIG_FILE)).result)
|
30
|
+
|
31
|
+
symbolize_keys!(new_config)
|
32
|
+
symbolize_keys!(new_config[:environments])
|
33
|
+
|
34
|
+
new_config[:environments].each do |env, hash|
|
35
|
+
symbolize_keys!(hash)
|
36
|
+
end
|
37
|
+
|
38
|
+
new_config.freeze
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def symbolize_keys!(hash)
|
43
|
+
hash.keys.each do |key|
|
44
|
+
hash[(key.to_sym rescue key) || key] = hash.delete(key)
|
45
|
+
end
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
module OpsWorks
|
3
|
+
class Base
|
4
|
+
attr_accessor :stack_name
|
5
|
+
|
6
|
+
def initialize(stack_name)
|
7
|
+
require 'aws-sdk'
|
8
|
+
|
9
|
+
@stack_name = stack_name
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
def opsworks
|
14
|
+
@opsworks ||= AWS::OpsWorks.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def stack_id
|
18
|
+
@stack_id ||= begin
|
19
|
+
resp = opsworks.client.describe_stacks
|
20
|
+
stack = resp[:stacks].find {|stack| stack[:name] == stack_name }
|
21
|
+
|
22
|
+
raise "OpsWorks stack not found!" if stack.nil?
|
23
|
+
|
24
|
+
stack[:stack_id]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
module OpsWorks
|
3
|
+
require 'ops_preflight/ops_works/base'
|
4
|
+
|
5
|
+
class Deploy < Base
|
6
|
+
attr_accessor :app_name
|
7
|
+
|
8
|
+
def initialize(stack_name, app_name)
|
9
|
+
super stack_name
|
10
|
+
|
11
|
+
@app_name = app_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(release_num = nil)
|
15
|
+
instances = instance_ids
|
16
|
+
puts "Triggering deploy of v#{release_num} to #{instances.size} instance#{'s' if instances.size != 1}"
|
17
|
+
|
18
|
+
resp = opsworks.client.create_deployment({
|
19
|
+
:stack_id => stack_id,
|
20
|
+
:app_id => app_id,
|
21
|
+
:instance_ids => instances,
|
22
|
+
:command => {
|
23
|
+
:name => 'deploy'
|
24
|
+
},
|
25
|
+
:comment => release_num.nil? ? 'Preflight Deployment' : "Preflight Release v#{release_num}"
|
26
|
+
})
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
def app_id
|
31
|
+
@app_id ||= begin
|
32
|
+
resp = opsworks.client.describe_apps(:stack_id => stack_id)
|
33
|
+
app = resp[:apps].find {|app| app[:name] == app_name}
|
34
|
+
|
35
|
+
raise "OpsWorks app not found!" if app.nil?
|
36
|
+
|
37
|
+
app[:app_id]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def instance_ids
|
42
|
+
resp = opsworks.client.describe_instances(:stack_id => stack_id)
|
43
|
+
ids = []
|
44
|
+
resp[:instances].each {|instance| ids << instance[:instance_id] if instance[:status] == 'online' }
|
45
|
+
|
46
|
+
ids
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
module OpsWorks
|
3
|
+
require 'ops_preflight/ops_works/base'
|
4
|
+
|
5
|
+
class FetchEnvironment < Base
|
6
|
+
attr_accessor :app_name
|
7
|
+
attr_accessor :environment
|
8
|
+
|
9
|
+
def initialize(environment, stack_name, app_name)
|
10
|
+
super stack_name
|
11
|
+
|
12
|
+
@environment = environment
|
13
|
+
@app_name = app_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
resp = opsworks.client.describe_stacks(:stack_ids => [stack_id])
|
18
|
+
|
19
|
+
require 'multi_json'
|
20
|
+
|
21
|
+
json = MultiJson.load(resp[:stacks].first[:custom_json])
|
22
|
+
|
23
|
+
str = ''
|
24
|
+
json['env_vars'][app_name][environment].each do |var, value|
|
25
|
+
str << "#{var.upcase}=#{value}\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
File.open(".env.#{environment}", 'wb') do |f|
|
29
|
+
f.write str
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
class S3Transfer
|
3
|
+
attr_accessor :bucket
|
4
|
+
attr_accessor :file
|
5
|
+
|
6
|
+
def initialize(bucket, file)
|
7
|
+
@bucket = bucket
|
8
|
+
@file = file
|
9
|
+
end
|
10
|
+
|
11
|
+
def upload
|
12
|
+
basename = File.basename(file)
|
13
|
+
|
14
|
+
remote_file = directory.files.head(basename)
|
15
|
+
remote_file.destroy if remote_file
|
16
|
+
|
17
|
+
directory.files.create(
|
18
|
+
:key => basename,
|
19
|
+
:body => File.open(file),
|
20
|
+
:public => false
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def download
|
25
|
+
basename = File.basename(file)
|
26
|
+
|
27
|
+
remote_file = directory.files.get(basename)
|
28
|
+
File.open(file, 'w') do |local_file|
|
29
|
+
local_file.write(remote_file.body)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def connection
|
35
|
+
require 'fog'
|
36
|
+
Fog::Storage::AWS.new :use_iam_profile => true
|
37
|
+
end
|
38
|
+
|
39
|
+
def directory
|
40
|
+
connection.directories.get(bucket)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module OpsPreflight
|
2
|
+
class Server < Thor
|
3
|
+
include ExitCode
|
4
|
+
|
5
|
+
namespace :default
|
6
|
+
|
7
|
+
desc "upload", "Upload preflight files to S3"
|
8
|
+
option :bucket, :aliases => '-b', :required => true, :type => :string, :banner => "<s3_bucket>"
|
9
|
+
option :file, :aliases => '-f', :required => true, :type => :string, :banner => "<file>"
|
10
|
+
def upload
|
11
|
+
raise Thor::Error, "Specified file not found: #{options[:file]}" unless File.exists?(options[:file])
|
12
|
+
|
13
|
+
require 'ops_preflight/s3_transfer.rb'
|
14
|
+
S3Transfer.new(options[:bucket], options[:file]).upload
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "download", "Downloads preflight files from S3"
|
18
|
+
option :bucket, :aliases => '-b', :required => true, :type => :string, :banner => "<s3_bucket>"
|
19
|
+
option :file, :aliases => '-f', :required => true, :type => :string, :banner => "<file>"
|
20
|
+
def download
|
21
|
+
require 'ops_preflight/s3_transfer.rb'
|
22
|
+
S3Transfer.new(options[:bucket], options[:file]).download
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "deploy <stack_name> <app_name>", "Deploys the application to opsworks"
|
26
|
+
option :release, :type => :string, :banner => '<release number>'
|
27
|
+
def deploy(stack_name, app_name)
|
28
|
+
require 'ops_preflight/ops_works/deploy.rb'
|
29
|
+
|
30
|
+
OpsWorks::Deploy.new(stack_name, app_name).call(options[:release])
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "fetch_environment <environment> <stack_name> <app_name>", 'Fetches environment variables from opsworks'
|
34
|
+
def fetch_environment(environment, stack_name, app_name)
|
35
|
+
require 'ops_preflight/ops_works/fetch_environment.rb'
|
36
|
+
|
37
|
+
OpsWorks::FetchEnvironment.new(environment, stack_name, app_name).call
|
38
|
+
end
|
39
|
+
|
40
|
+
# Fixes thor's banners when used with :default namespace
|
41
|
+
def self.banner(command, namespace = nil, subcommand = false)
|
42
|
+
"#{basename} #{command.formatted_usage(self, false, subcommand)}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
set :opsworks_stack_name, ENV['OPSWORKS_STACK_NAME']
|
2
|
+
set :opsworks_app_name, ENV['OPSWORKS_APP_NAME']
|
3
|
+
set :rake_assets_clean_expired, lambda { "#{rake} assets:clean_expired RAILS_GROUPS=assets" }
|
4
|
+
|
5
|
+
namespace :preflight do
|
6
|
+
task :check_env_vars do
|
7
|
+
[:opsworks_stack_name, :opsworks_app_name].each do |var|
|
8
|
+
if settings[var].nil?
|
9
|
+
print_error(unindent(%[
|
10
|
+
Setting #{var.to_s} must be specified.
|
11
|
+
]))
|
12
|
+
die(2)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc 'Fetches the application environment vars'
|
18
|
+
task :fetch_environment => :check_env_vars do
|
19
|
+
queue %[
|
20
|
+
echo "-----> Preflight: Fetch Environment"
|
21
|
+
#{echo_cmd %[bundle exec preflight-server fetch_environment #{settings.rails_env!} '#{settings.opsworks_stack_name!}' '#{settings.opsworks_app_name!}']}
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Cleans up expired assets'
|
26
|
+
task :assets_clean_expired do
|
27
|
+
queue %{
|
28
|
+
echo "-----> Preflight: Clean expired assets"
|
29
|
+
#{echo_cmd %[#{rake_assets_clean_expired}]}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Prepares the bundle for deploy'
|
34
|
+
task :bundle => :environment do
|
35
|
+
queue %[
|
36
|
+
echo "-----> Preflight: Uploading Bundle"
|
37
|
+
#{echo_cmd %[tar -zcvf tmp/preflight-#{settings.app_name!}-bundle-#{settings.rails_env!}.tgz -C #{deploy_to}/#{shared_path} bundle > /dev/null]} &&
|
38
|
+
#{echo_cmd %[bundle exec preflight-server upload -b #{settings.preflight_bucket!} -f ./tmp/preflight-#{settings.app_name!}-bundle-#{settings.rails_env!}.tgz]}
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'Precompiles assets for deploy'
|
43
|
+
task :assets => :environment do
|
44
|
+
queue %[
|
45
|
+
echo "-----> Preflight: Uploading Assets"
|
46
|
+
#{echo_cmd %[tar -zcvf tmp/preflight-#{settings.app_name!}-assets-#{settings.rails_env!}.tgz -C #{deploy_to}/#{shared_path}/public assets > /dev/null]} &&
|
47
|
+
#{echo_cmd %[bundle exec preflight-server upload -b #{settings.preflight_bucket!} -f ./tmp/preflight-#{settings.app_name!}-assets-#{settings.rails_env!}.tgz]}
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'Triggers a deploy'
|
52
|
+
task :deploy => [:environment, :check_env_vars] do
|
53
|
+
queue %[
|
54
|
+
echo "-----> Preflight: Deploy"
|
55
|
+
#{echo_cmd %[bundle exec preflight-server deploy '#{settings.opsworks_stack_name!}' '#{settings.opsworks_app_name!}' --release="$version"]}
|
56
|
+
]
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'thor'
|
3
|
+
|
4
|
+
module OpsPreflight
|
5
|
+
ROOT = File.expand_path('../../', __FILE__)
|
6
|
+
|
7
|
+
require "ops_preflight/version"
|
8
|
+
|
9
|
+
autoload :ExitCode, 'ops_preflight/exit_code.rb'
|
10
|
+
autoload :Server, 'ops_preflight/server.rb'
|
11
|
+
autoload :Client, 'ops_preflight/client.rb'
|
12
|
+
autoload :Config, 'ops_preflight/config.rb'
|
13
|
+
|
14
|
+
def self.root_path(*a)
|
15
|
+
File.join ROOT, *a
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ops_preflight/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "ops_preflight"
|
8
|
+
gem.version = OpsPreflight::VERSION
|
9
|
+
gem.authors = ["Ryan Schlesinger"]
|
10
|
+
gem.email = ["ryan@instanceinc.com"]
|
11
|
+
gem.description = %q{Preflight and deploy applications}
|
12
|
+
gem.summary = %q{Preflight by packaging the bundle, precompiled assets, or anything else needed to deploy an application.}
|
13
|
+
gem.homepage = "https://github.com/aceofsales/ops_preflight"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_runtime_dependency('thor', '~> 0.17.0')
|
21
|
+
gem.add_runtime_dependency('fog', '~> 1.10.0')
|
22
|
+
gem.add_runtime_dependency('mina', '~> 0.2.1')
|
23
|
+
gem.add_runtime_dependency('aws-sdk', '~> 1.8.5')
|
24
|
+
gem.add_runtime_dependency('multi_json', '~> 1.0')
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ops_preflight
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1.pre
|
5
|
+
prerelease: 6
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ryan Schlesinger
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.17.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.17.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: fog
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.10.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.10.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mina
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.2.1
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: aws-sdk
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.5
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.5
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: multi_json
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '1.0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.0'
|
94
|
+
description: Preflight and deploy applications
|
95
|
+
email:
|
96
|
+
- ryan@instanceinc.com
|
97
|
+
executables:
|
98
|
+
- preflight
|
99
|
+
- preflight-server
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- bin/preflight
|
109
|
+
- bin/preflight-server
|
110
|
+
- data/deploy.rb
|
111
|
+
- data/preflight.yml
|
112
|
+
- lib/ops_preflight.rb
|
113
|
+
- lib/ops_preflight/client.rb
|
114
|
+
- lib/ops_preflight/config.rb
|
115
|
+
- lib/ops_preflight/exit_code.rb
|
116
|
+
- lib/ops_preflight/ops_works/base.rb
|
117
|
+
- lib/ops_preflight/ops_works/deploy.rb
|
118
|
+
- lib/ops_preflight/ops_works/fetch_environment.rb
|
119
|
+
- lib/ops_preflight/s3_transfer.rb
|
120
|
+
- lib/ops_preflight/server.rb
|
121
|
+
- lib/ops_preflight/tasks.rb
|
122
|
+
- lib/ops_preflight/version.rb
|
123
|
+
- ops_preflight.gemspec
|
124
|
+
homepage: https://github.com/aceofsales/ops_preflight
|
125
|
+
licenses: []
|
126
|
+
post_install_message:
|
127
|
+
rdoc_options: []
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
hash: -1041487492741843345
|
139
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>'
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 1.3.1
|
145
|
+
requirements: []
|
146
|
+
rubyforge_project:
|
147
|
+
rubygems_version: 1.8.25
|
148
|
+
signing_key:
|
149
|
+
specification_version: 3
|
150
|
+
summary: Preflight by packaging the bundle, precompiled assets, or anything else needed
|
151
|
+
to deploy an application.
|
152
|
+
test_files: []
|