rdeis 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/README.md +32 -0
- data/bin/rdeis +7 -0
- data/gemconversion +34 -0
- data/lib/rdeis/base.rb +23 -0
- data/lib/rdeis/bootstrap.rb +96 -0
- data/lib/rdeis/config.rb +102 -0
- data/lib/rdeis/deis.rb +167 -0
- data/lib/rdeis/deploy.rb +195 -0
- data/lib/rdeis/domains.rb +5 -0
- data/lib/rdeis/git.rb +58 -0
- data/lib/rdeis/parse.rb +64 -0
- data/lib/rdeis/storage.rb +71 -0
- data/lib/rdeis/version.rb +3 -0
- data/lib/rdeis.rb +15 -0
- data/lib/ssh.rb +42 -0
- data/rdeis.gemspec +27 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1cc0d69fdcf8dd2e9943afc4547d314c6dfaf95f
|
4
|
+
data.tar.gz: 6a128b021f283c44c30ed925effff21fc4f5523f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 271d64396b5396e1c647e02a833a24947ad1f57fdea58deb9487491559ebacd263c5a52c62980fea1eeed5e4bc18a0259c1e87ca85d1dcad10530ae81517f81b
|
7
|
+
data.tar.gz: 046e6e26c9886d317021e5aa3c124ba07659b5b71105746415ceb97e85b8b15ae417d8d6ed9dfaf996f3c62ce5e0cafe31f6d6c4c728a2f8a90d3a65d427829c
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Deployment to a Deis Cluster
|
2
|
+
|
3
|
+
A gem that will use `deis` to deploy to your environment.
|
4
|
+
|
5
|
+
This is an early version, so there is currently no removals and presumes that only one version of the repo will existing per environment. You can change the environment if you are planning on using this in CI style setup.
|
6
|
+
|
7
|
+
This will also automatically convert gem files that have protected github repos over to use token based url
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
`gem install rdeis`
|
13
|
+
|
14
|
+
## Usage
|
15
|
+
|
16
|
+
Mirrors the `deis` binary as closely as possible, so the base commands are:
|
17
|
+
|
18
|
+
- `rdeis config`
|
19
|
+
- `rdeis config set`
|
20
|
+
- `rdeis config unset`
|
21
|
+
- `rdeis config list`
|
22
|
+
- `rdeis domains`
|
23
|
+
- `rdeis domains add`
|
24
|
+
- `rdeis domains remove`
|
25
|
+
- `rdeis domains list`
|
26
|
+
- `rdeis deploy`
|
27
|
+
- `rdeis help`
|
28
|
+
- `rdeis scale`
|
29
|
+
|
30
|
+
|
31
|
+
During the first use of the gem, it will ask some questions in order to generate a environment configuration file (github tokens and the like)
|
32
|
+
|
data/bin/rdeis
ADDED
data/gemconversion
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
file = "./Gemfile"
|
4
|
+
ignore = "./gitignore"
|
5
|
+
if File.exists?(file)
|
6
|
+
contents = File.open(file, "r") {|f| f.read }
|
7
|
+
# convert values over
|
8
|
+
contents = contents.gsub("'", '"').gsub("git@github.com:", "https://#{ENV['GITHUB_TOKEN']}:x-oauth-basic@github.com/")
|
9
|
+
# write back to file
|
10
|
+
File.open(file, "w"){ |f| f.write(contents) }
|
11
|
+
# add this file to the gitignore
|
12
|
+
if File.exists?(ignore)
|
13
|
+
puts "adding to ignore file"
|
14
|
+
igoring = File.open(ignore, "r"){|g| g.read }
|
15
|
+
File.open(ignore, "w"){|g| g.write(ignoring.gsub("gemconversion", "") + "\ngemconversion" ) }
|
16
|
+
end
|
17
|
+
# run the bundle
|
18
|
+
install = `bundle install 2>&1 | grep 'Your bundle is complete!' | wc -l`.to_i
|
19
|
+
# check the status
|
20
|
+
status = `git status | grep "modified.*Gemfile" | wc -l`.to_i
|
21
|
+
# create the commit
|
22
|
+
commit = 0
|
23
|
+
commit = `git commit Gemfile Gemfile.lock -m '[rdeis] Automated Gemfile conversion - #{Time.now.to_s}' 2>&1 | grep 'Error' | wc -l`.to_i if install == 1 && status > 0
|
24
|
+
|
25
|
+
if status == 0
|
26
|
+
$stdout.puts "Already converted & commited"
|
27
|
+
elsif install == 1 && commit == 0
|
28
|
+
$stdout.puts "Converted & commited"
|
29
|
+
else
|
30
|
+
abort("Error: install / commit failed (#{install}/#{commit})")
|
31
|
+
end
|
32
|
+
else
|
33
|
+
abort("Error: Gemfile not found")
|
34
|
+
end
|
data/lib/rdeis/base.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module DEIS
|
2
|
+
class Base
|
3
|
+
include Thor::Shell
|
4
|
+
attr_accessor :verbose, :environment, :proxy, :cluster, :path, :output
|
5
|
+
YES = "\u2713"
|
6
|
+
NO = "\u274C"
|
7
|
+
|
8
|
+
def log(cmd)
|
9
|
+
say "[#{@proxy} #{Time.now}] #{cmd}", :black if @verbose
|
10
|
+
end
|
11
|
+
|
12
|
+
# run commands either locally or remotely
|
13
|
+
def run(command)
|
14
|
+
self.log(command)
|
15
|
+
if @proxy
|
16
|
+
return @ssh.exec!(command)
|
17
|
+
else
|
18
|
+
return `#{command}`.strip
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module DEIS
|
2
|
+
class Bootstrap < Base
|
3
|
+
include Thor::Shell
|
4
|
+
|
5
|
+
attr_accessor :proxy, :token, :ssh, :deploy_to
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@repo = DEIS::Git.name
|
9
|
+
@verbose = options[:verbose]
|
10
|
+
@environment = options[:environment]
|
11
|
+
say( "Checking local environment..", :green)
|
12
|
+
end
|
13
|
+
|
14
|
+
def proxy
|
15
|
+
if yes?("Do you need to connect to another machine to run deis commands? (y/n): ", :yellow)
|
16
|
+
@proxy = ask("Enter the hostname / ip / ssh config name of this host: ", :yellow)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def github_token
|
21
|
+
# if local env doesnt have it and no proxy host, just ask
|
22
|
+
if ENV[DEIS::Git.github_token_varname].nil? && @proxy.nil?
|
23
|
+
@token = ask("Please enter your github auth token: ", :yellow)
|
24
|
+
# if proxy is set, then check for the var on the proxy:key => "value",
|
25
|
+
elsif ENV[DEIS::Git.github_token_varname].nil? && ! @proxy.nil?
|
26
|
+
cmd = DEIS::Git.github_token_cmd
|
27
|
+
say("[#{Time.now.to_s}] "+cmd+"\n", :black) if @verbose
|
28
|
+
remote = @ssh.exec!(cmd).to_s.strip
|
29
|
+
if ! remote.nil? && remote.length > 0 && (yes?("Found #{remote} on #{@proxy}, set as local version? (y/n): ", :yellow) )
|
30
|
+
@token = remote
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@token = ask("Please enter a github auth token for deployment: ", :yellow)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def deploy_path
|
39
|
+
if @proxy.nil?
|
40
|
+
@deploy_to = ask("Please enter local folder to deploy to: ", :yellow)
|
41
|
+
else
|
42
|
+
@deploy_to = ask("Please enter containing folder on #{@proxy} to deploy to: ", :yellow)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# add a hush login file so we dont get the MOTD ouput in our shell commands
|
47
|
+
def hush
|
48
|
+
if yes? ("Does the deploy location run a Message of the Day? ")
|
49
|
+
run("if [[ ! -f $HOME/.hushlogin ]]; then > $HOME/.hushlogin ; fi ")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def all
|
54
|
+
@proxy = nil
|
55
|
+
@token = nil
|
56
|
+
file = DEIS::Storage::BASE_PATH.gsub("$HOME", ENV['HOME'])+".profile"
|
57
|
+
if ! File.exists?(file)
|
58
|
+
self.proxy
|
59
|
+
@ssh = SSH.new({:host => @proxy, :user => nil}) if ! @proxy.nil?
|
60
|
+
self.hush
|
61
|
+
self.github_token
|
62
|
+
self.deploy_path
|
63
|
+
self.save
|
64
|
+
@ssh.close
|
65
|
+
say "Bootstrap Completed", :blue
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def save
|
70
|
+
# the base file location for the env vars we need
|
71
|
+
file = DEIS::Storage::ENV_VAR_PATH
|
72
|
+
replaced = DEIS::Storage::BASE_PATH.gsub("$HOME", ENV['HOME'])
|
73
|
+
FileUtils.mkdir_p(replaced) if ! File.directory?(replaced)
|
74
|
+
out = "# [rdeis #{DEIS::VERSION}] Auto generated at #{Time.now.to_s}\n"
|
75
|
+
out = out+"export RDEIS_PROXY=\"#{@proxy}\"\n" if ! @proxy.nil?
|
76
|
+
out = out+"export RDEIS_PATH=\"#{@deploy_to.gsub('$', '\$') }\"\n" if ! @deploy_to.nil?
|
77
|
+
out = out+"export #{DEIS::Git.github_token_varname}=\"#{@token}\"\n" if ! @token.nil?
|
78
|
+
# write locally
|
79
|
+
File.open(file.gsub("$HOME", ENV['HOME']), "w"){ |f| f.write(out) }
|
80
|
+
# run remote, keep the $HOME notation as we want that evaluated in the cmd
|
81
|
+
run("mkdir -p #{DEIS::Storage::BASE_PATH} ; echo -e '#{out}' > #{file}") if ! @proxy.nil?
|
82
|
+
# remove any existing references from the various shell options on the local machine
|
83
|
+
shell=`echo $SHELL | sed -E "s#/bin/##i"`.strip
|
84
|
+
profile = ["#{ENV['HOME']}/.#{shell}rc", "#{ENV['HOME']}/.#{shell}_profile", "#{ENV['HOME']}/.profile"].select{|f| File.exists?(f)}.first
|
85
|
+
if ! profile.nil?
|
86
|
+
content = File.open(profile, "r"){ |f| f.read }.gsub(". #{file}", "") + "\n. #{file}"
|
87
|
+
File.open(profile, "w") { |f| f.write(content) }
|
88
|
+
else
|
89
|
+
say "Could not save environment setup", :red
|
90
|
+
end
|
91
|
+
# add include to the remote profile
|
92
|
+
run("echo -e '. #{file}\n' >> ~/.profile") if ! @proxy.nil?
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
data/lib/rdeis/config.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
module DEIS
|
2
|
+
class Config < Storage
|
3
|
+
include Thor::Shell
|
4
|
+
attr_accessor :verbose, :environment
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@repo = DEIS::Git.name
|
8
|
+
@verbose = options[:verbose]
|
9
|
+
@environment = options[:environment]
|
10
|
+
@set_selector = self.class.to_s.downcase.gsub("deis::", "")
|
11
|
+
@remove_selector = "removed_"+@set_selector
|
12
|
+
end
|
13
|
+
|
14
|
+
# output data using thors print_table & say
|
15
|
+
def list(vars)
|
16
|
+
data = DEIS::Storage.get(@repo, @environment, @set_selector)
|
17
|
+
# if vars have been set then we filter the config data to matching keys
|
18
|
+
if ! vars.nil? && vars.length > 0
|
19
|
+
keys = []
|
20
|
+
DEIS::Parse.var_array(vars).each { |f| keys.push(f[:k]) }
|
21
|
+
data = data.select!{ |k,v| keys.include? (k) }
|
22
|
+
end
|
23
|
+
|
24
|
+
self.results("#{@set_selector} for #{@repo} -> #{@environment}", "No data found" ,data, :green)
|
25
|
+
to_remove = DEIS::Storage.get(@repo, @environment, @remove_selector)
|
26
|
+
self.results("\n\n#{@set_selector} to be removed", nil, to_remove, :blue)
|
27
|
+
end
|
28
|
+
|
29
|
+
# set config vars for the repo
|
30
|
+
def set(vars)
|
31
|
+
if vars.nil? || vars.length == 0
|
32
|
+
say "Please provide a value", :red
|
33
|
+
else
|
34
|
+
set = {}
|
35
|
+
DEIS::Parse.var_array(vars).each do |var|
|
36
|
+
set[var[:k]] = var[:v]
|
37
|
+
DEIS::Storage.subset(@repo, @environment, @set_selector, var[:k], var[:v])
|
38
|
+
end
|
39
|
+
self.results("Setting #{@set_selector} for #{@repo} -> #{@environment}", "Error setting #{@set_selector}", set, :green)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def add(vars)
|
44
|
+
self.set(vars)
|
45
|
+
end
|
46
|
+
|
47
|
+
# remove vars
|
48
|
+
def unset(vars)
|
49
|
+
if vars.nil? || vars.length == 0
|
50
|
+
say "Please enter a key to unset", :red
|
51
|
+
else
|
52
|
+
unset = {}
|
53
|
+
DEIS::Parse.var_array(vars).each do |var|
|
54
|
+
unset[var[:k]] = "\u2713"
|
55
|
+
DEIS::Storage.subunset(@repo, @environment, @set_selector, var[:k])
|
56
|
+
end
|
57
|
+
self.results("Removing #{@set_selector} for #{@repo} -> #{@environment}", "Error removing #{@set_selector}", unset, :green)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def remove(vars)
|
62
|
+
self.unset(vars)
|
63
|
+
end
|
64
|
+
|
65
|
+
# vars should just be the file name
|
66
|
+
def export(vars)
|
67
|
+
raw = DEIS::Storage.load(@repo, @environment)
|
68
|
+
if ! vars.nil? && vars.length > 0 && (file = vars.first)
|
69
|
+
File.open(file, "w"){|f| f.write( raw.to_json ) }
|
70
|
+
say "Data for #{@repo} -> #{@environment} written to #{file}", :green
|
71
|
+
else
|
72
|
+
say "Please specify a file path to export to", :red
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# import from a file
|
77
|
+
def import(vars)
|
78
|
+
if !vars.nil? && vars.length > 0 && (file = vars.first) && (content = File.open(file, "r"){ |f| f.read } )
|
79
|
+
content = JSON.parse(content)
|
80
|
+
DEIS::Storage.save(@repo, @environment, content)
|
81
|
+
say "Data imported from #{file} into #{@repo} -> #{@environment}", :green
|
82
|
+
else
|
83
|
+
say "Please specify a valid file", :red
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def results(message, error_message, data, colour)
|
88
|
+
if ! data.nil? && data.length > 0
|
89
|
+
say message, colour
|
90
|
+
say "----------------------------------", colour
|
91
|
+
print_table data
|
92
|
+
say "----------------------------------", colour
|
93
|
+
elsif ! error_message.nil?
|
94
|
+
say message, colour
|
95
|
+
say error_message, :red
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
data/lib/rdeis/deis.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
module DEIS
|
2
|
+
class Deis < Thor
|
3
|
+
include Thor::Shell
|
4
|
+
class_option :verbose, :type => :boolean, :default => false
|
5
|
+
class_option :environment , :type => :string, :default => "staging", :aliases => "-e"
|
6
|
+
|
7
|
+
desc "config <export|import|list|set|unset> <varstring>", "set or unset a variable"
|
8
|
+
long_desc <<-LONGDESC
|
9
|
+
Modifies the the LOCAL configuration variables in the current environment (set with --environment or -e). When deployed, these will become environment variables for your application.
|
10
|
+
|
11
|
+
Examples:
|
12
|
+
|
13
|
+
`rdeis config list`
|
14
|
+
`rdeis config`
|
15
|
+
|
16
|
+
Returns all config items for this environment. List is the default action for config.
|
17
|
+
|
18
|
+
`redis export $destination_file -e $environment`
|
19
|
+
|
20
|
+
Export all data for the set $environment into the $file path specified. This will be in a JSON format
|
21
|
+
|
22
|
+
`redis import $origin_file -e $environment`
|
23
|
+
|
24
|
+
Import and replace current setup for $environment with the data contained in $origin_file
|
25
|
+
|
26
|
+
`rdeis config list TEST`
|
27
|
+
|
28
|
+
Filters the list to just the value for TEST (if present)
|
29
|
+
|
30
|
+
`rdeis config set FOO=BAR TEST=1`
|
31
|
+
|
32
|
+
This sets two variables, FOO & TEST, to BAR & 1 respectively and matches the syntax for the `deis` binary
|
33
|
+
|
34
|
+
`rdeis config unset FOO TEST`
|
35
|
+
|
36
|
+
This will unset two variables, FOO & TEST, as long as they exist in the configuration settings.
|
37
|
+
|
38
|
+
You will need to deploy for changes to effect the running environment.
|
39
|
+
|
40
|
+
LONGDESC
|
41
|
+
def config(action="list", *vars)
|
42
|
+
self.bootstrap
|
43
|
+
if DEIS::Config.method_defined? action
|
44
|
+
config = DEIS::Config.new(options)
|
45
|
+
config.send(action, vars)
|
46
|
+
else
|
47
|
+
say "invalid option", :red
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
desc "domains <add|remove|list> <domain>", "add, remove or list domains"
|
54
|
+
long_desc <<-LONGDESC
|
55
|
+
Modifies the the LOCAL domains in the current environment (set with --environment or -e). Once deployed, this will be the domains that route to your application.
|
56
|
+
|
57
|
+
Examples:
|
58
|
+
|
59
|
+
`rdeis domains list`
|
60
|
+
`rdeis domains`
|
61
|
+
|
62
|
+
Returns all domains for this environment. List is the default action.
|
63
|
+
|
64
|
+
`rdeis domains add test.example.com foo.bar.com`
|
65
|
+
|
66
|
+
This adds two domains to the setup for this application.
|
67
|
+
|
68
|
+
`rdeis domains remove foo.bar.com`
|
69
|
+
|
70
|
+
This will unset foo.bar.com, as long as they exist in the settings.
|
71
|
+
|
72
|
+
You will need to deploy for changes to effect the running environment.
|
73
|
+
|
74
|
+
|
75
|
+
LONGDESC
|
76
|
+
def domains(action="list", *domains)
|
77
|
+
self.bootstrap
|
78
|
+
if DEIS::Domains.method_defined? action
|
79
|
+
domain = DEIS::Domains.new(options)
|
80
|
+
domain.send(action, domains)
|
81
|
+
else
|
82
|
+
say "invalid option", :red
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "deploy <all|create|config|domains|gems|git|remotes>", "deploy this repo"
|
87
|
+
option :proxy, :type => :string, :aliases => "-P", :banner => "<Hostname|IP> of proxy host, for vpc etc"
|
88
|
+
option :cluster, :type => :string, :default => "staging", :banner => "<name> of the cluster to deploy to"
|
89
|
+
option :path, :type => :string, :aliases => "-p", :banner => "<FILE_PATH> to deploy to"
|
90
|
+
long_desc <<-LONGDESC
|
91
|
+
Deploy to the deis cluster that is configured. This will run over the actions to checkout the git repo to a set location, create the deis application, use your local config and domain values on the deis application, find and add the deis remote to local version and the run a push to that remote
|
92
|
+
|
93
|
+
Examples
|
94
|
+
|
95
|
+
`rdeis deploy`
|
96
|
+
`rdeis deploy all`
|
97
|
+
|
98
|
+
This will run all elements of the checkout
|
99
|
+
|
100
|
+
`rdeis create`
|
101
|
+
|
102
|
+
Runs just a deis create $application --cluster=$cluster
|
103
|
+
|
104
|
+
`rdeis config`
|
105
|
+
|
106
|
+
Deploys the local config to the deis application
|
107
|
+
|
108
|
+
`rdeis domains`
|
109
|
+
|
110
|
+
Deploys the local domain list to the deis application
|
111
|
+
|
112
|
+
`rdeis gems`
|
113
|
+
|
114
|
+
Modifies your local gem file and convert and git@github based gems to run from oauth basic token access from an ENV variable
|
115
|
+
|
116
|
+
`rdeis git`
|
117
|
+
|
118
|
+
Create and clone the repo at --path
|
119
|
+
|
120
|
+
`rdeis remotes`
|
121
|
+
|
122
|
+
Find and setup deis remotes on current directory
|
123
|
+
|
124
|
+
LONGDESC
|
125
|
+
def deploy(action="all")
|
126
|
+
self.bootstrap
|
127
|
+
if DEIS::Deploy.method_defined? action
|
128
|
+
deploy = DEIS::Deploy.new(options)
|
129
|
+
deploy.send(action)
|
130
|
+
else
|
131
|
+
say "invalid option", :red
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
desc "scale <varstring>", "Scale a proc"
|
136
|
+
long_desc <<-LONGDESC
|
137
|
+
Scale a proc up or down based on value you enter.
|
138
|
+
|
139
|
+
Examples:
|
140
|
+
|
141
|
+
`rdeis scale web=1`
|
142
|
+
Would turn on 1 instance of the web proc
|
143
|
+
|
144
|
+
LONGDESC
|
145
|
+
def scale(*vars)
|
146
|
+
self.bootstrap
|
147
|
+
if DEIS::Deploy.method_defined? "scale"
|
148
|
+
deploy = DEIS::Deploy.new(options)
|
149
|
+
deploy.send("scale", vars)
|
150
|
+
else
|
151
|
+
say "invalid option", :red
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
desc "bootstrap <type>", "first run install setup funcs"
|
156
|
+
def bootstrap(action="all")
|
157
|
+
if DEIS::Bootstrap.method_defined? action
|
158
|
+
bootstrap = DEIS::Bootstrap.new(options)
|
159
|
+
bootstrap.send(action)
|
160
|
+
else
|
161
|
+
say "invalid option", :red
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
data/lib/rdeis/deploy.rb
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
module DEIS
|
2
|
+
require 'shellwords'
|
3
|
+
class Deploy < Storage
|
4
|
+
include Thor::Shell
|
5
|
+
attr_accessor :verbose, :environment, :proxy, :cluster, :path, :output
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@repo = DEIS::Git.name
|
9
|
+
@verbose = options["verbose"]
|
10
|
+
@environment = options["environment"]
|
11
|
+
@cluster = options["cluster"]
|
12
|
+
# location data that fetch from env as well as options from thor
|
13
|
+
@proxy = if ! options["proxy"].nil? then options["proxy"] elsif ! ENV['RDEIS_PROXY'].nil? then ENV['RDEIS_PROXY'] else nil end
|
14
|
+
@base_path = if ! options["path"].nil? then options["path"] elsif ! ENV['RDEIS_PATH'].nil? then ENV['RDEIS_PATH'] else ENV['HOME'] end
|
15
|
+
# git data
|
16
|
+
@ref = DEIS::Git.ref
|
17
|
+
@branch = DEIS::Git.branch
|
18
|
+
@remote = DEIS::Git.remote
|
19
|
+
|
20
|
+
@name = @repo+"-"+@environment
|
21
|
+
@deploy_to = @base_path.to_s + "/"+ @name + "/"
|
22
|
+
@ssh = SSH.new({:host => @proxy, :user => nil}) if ! @proxy.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
# deis create wrapper
|
26
|
+
def create
|
27
|
+
output ={"CREATE" => ""}
|
28
|
+
# check it exists
|
29
|
+
exists = run("deis apps 2>&1 | grep '#{@name}' | wc -l").to_i
|
30
|
+
output[" exists"] = if exists == 1 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
31
|
+
# try to make it if it doesnt
|
32
|
+
created = run("cd #{@deploy_to} && deis create #{@name} --cluster=#{@environment} 2>&1 | grep 'not found\\\|400' | wc -l").to_i if exists == 0
|
33
|
+
output[" created"] = if created == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
34
|
+
|
35
|
+
print_table output
|
36
|
+
if exists == 0 && created != 0
|
37
|
+
say "Could not create application.", :red
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# deis config:set / unset wrapper
|
43
|
+
def config
|
44
|
+
self.setter("config")
|
45
|
+
end
|
46
|
+
|
47
|
+
# deis domains:add / remote wrapper
|
48
|
+
def domains
|
49
|
+
self.setter("domains", "remove", "add")
|
50
|
+
end
|
51
|
+
|
52
|
+
# generalised setter for config &
|
53
|
+
def setter(name="config", rm="unset", add="set")
|
54
|
+
output = {"#{name.upcase}" => ""}
|
55
|
+
|
56
|
+
removed = DEIS::Storage.get(@repo, @environment, "removed_#{name}")
|
57
|
+
remove =DEIS::Parse.JSON_to_unset(removed) if removed.length > 0
|
58
|
+
remove_res = run("cd #{@deploy_to} && deis #{name}:#{rm} #{remove} | grep 'not found\\\|400' | wc -l").to_i if !remove.nil? && remove.length > 0
|
59
|
+
output[" unset"] = if remove_res == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
60
|
+
|
61
|
+
to_add = DEIS::Storage.get(@repo, @environment, name)
|
62
|
+
set = DEIS::Parse.JSON_to_set(to_add) if to_add.length > 0
|
63
|
+
set_res = run("cd #{@deploy_to} && deis #{name}:#{add} #{set} | grep 'not found\\\|400' | wc -l").to_i if !set.nil? && set.length > 0
|
64
|
+
|
65
|
+
output[" set"] = if set_res == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
66
|
+
print_table output
|
67
|
+
# if there were things to set, that ran, but failed, throw
|
68
|
+
if !set.nil? && ! set_res.nil? && set_res > 0
|
69
|
+
say "#{name.upcase} failed to set.. please check manually", :red
|
70
|
+
say "This may have failed due to values for #{name.upcase} already being set", :red
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# adjust the gem files & rebuild
|
77
|
+
def gems
|
78
|
+
output = {"GEMS" => ""}
|
79
|
+
# make sure we have token in env
|
80
|
+
token = run(DEIS::Git.github_token_cmd).to_s.strip
|
81
|
+
token = if token.length == 0 then nil else token end
|
82
|
+
output[" github token"] = if ! token.nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
83
|
+
# check gemfile to see if we need a github token
|
84
|
+
file = Dir.pwd + "/Gemfile"
|
85
|
+
contents = File.open(file, "r") { |f| f.read } if File.exists?(file)
|
86
|
+
needed = ! contents.index("git@github.com").nil? if ! contents.nil?
|
87
|
+
output[" git token needed"] = if ! needed.nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
88
|
+
|
89
|
+
# check to see if the token is being used already
|
90
|
+
conversion_needed = contents.index(DEIS::Git.github_token_varname)
|
91
|
+
output[" conversion needed"] = if conversion_needed.nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
92
|
+
# if the conversion is needed, upload the pre run ruby script that will convert and commit on the remote deploy end
|
93
|
+
if conversion_needed.nil? && ! contents.nil? && ! token.nil?
|
94
|
+
upload_file = File.expand_path(File.dirname(__FILE__)) + "/../../gemconversion"
|
95
|
+
upload = File.open(upload_file, "r") { |f| f.read }
|
96
|
+
install = run("cd #{@deploy_to} && echo -e #{Shellwords.escape(upload)} > gemconversion ; chmod 0777 gemconversion; ls | grep gemconversion | wc -l").to_i
|
97
|
+
else
|
98
|
+
install = 1
|
99
|
+
output[" converted"] = DEIS::Deploy::YES
|
100
|
+
end
|
101
|
+
print_table output
|
102
|
+
# if need a token, and no token is set, fail
|
103
|
+
if ! needed.nil? && token.nil?
|
104
|
+
say "Github token needed, but not found", :red
|
105
|
+
exit 1
|
106
|
+
end
|
107
|
+
# convert gem message
|
108
|
+
if install != 1
|
109
|
+
say "Failed to upload Gemfile conversion", :red
|
110
|
+
exit 1
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
# run the git checkout & clone setup
|
116
|
+
def git
|
117
|
+
output = {"GIT" => ""}
|
118
|
+
# check for directory
|
119
|
+
directory = run( "ls -l #{@deploy_to} 2> /dev/null | wc -l").to_i
|
120
|
+
if directory == 0
|
121
|
+
created = run( "mkdir -p #{@deploy_to}")
|
122
|
+
output[" directory"] = if created then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
123
|
+
else
|
124
|
+
output[" directory"] = DEIS::Deploy::YES
|
125
|
+
end
|
126
|
+
|
127
|
+
# check if git & initialise
|
128
|
+
is_git = run( "cd #{@deploy_to} && #{DEIS::Git.is_git_cmd}").to_i
|
129
|
+
if is_git > 0
|
130
|
+
git_init_remote = run("cd #{@deploy_to} && #{DEIS::Git.init_with_remote_cmd(@remote)}").to_i
|
131
|
+
output[" init and remote"] = if git_init_remote == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
132
|
+
else
|
133
|
+
output[" init and remote"] = DEIS::Deploy::YES
|
134
|
+
end
|
135
|
+
# checkout to the correct branch from the remote
|
136
|
+
checkout = run ("cd #{@deploy_to} && #{DEIS::Git.checkout_to_ref_cmd('origin/'+@ref)}")
|
137
|
+
output[" checkout to #{@ref[0..8]}"] = if checkout then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
138
|
+
print_table output
|
139
|
+
end
|
140
|
+
|
141
|
+
# parse the remotes that have been created and add to local version if proxy is set
|
142
|
+
# this is to allow easier pushes
|
143
|
+
def remotes
|
144
|
+
output = {"REMOTES" => ""}
|
145
|
+
remote = run("cd #{@deploy_to} && " + 'git remote -v | grep "deis.*(push)" | sed -E "s#deis|\(push\)##g"').to_s.strip
|
146
|
+
# presume the remote is an ssh protocol, as that is what deis currently sets it as
|
147
|
+
output[" found"] = if ! remote.index("ssh://").nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
148
|
+
|
149
|
+
if ! remote.nil? && remote.length > 0
|
150
|
+
self.log(remote)
|
151
|
+
# run this locally only, adding to the
|
152
|
+
local_command = "cd #{Dir.pwd} && git remote add #{@name} #{remote} 2>/dev/n"
|
153
|
+
self.log(local_command)
|
154
|
+
`#{local_command}`
|
155
|
+
end
|
156
|
+
print_table output
|
157
|
+
end
|
158
|
+
|
159
|
+
# run a git push to the deis remote
|
160
|
+
def push
|
161
|
+
output = {"PUSH" => ""}
|
162
|
+
# make sure the profile is loaded, cd to the right place & run the converstion script.
|
163
|
+
conversion = run(". $HOME/.profile && cd #{@deploy_to} && ./gemconversion | grep Error | wc -l").to_i
|
164
|
+
output[" Gem conversion"] = if conversion == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
165
|
+
# push the branch to deis
|
166
|
+
deis = run("cd #{@deploy_to} && git push deis #{@branch} | grep Error | wc -l") if conversion == 0
|
167
|
+
output[" Deis push"] = if deis.to_i == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
|
168
|
+
print_table output
|
169
|
+
end
|
170
|
+
|
171
|
+
def scale(vars)
|
172
|
+
output = {"SCALE" => ""}
|
173
|
+
if ! vars.nil? && vars.length > 0
|
174
|
+
procs = DEIS::Parse.var_array(vars) if ! vars.nil? && vars.length > 0
|
175
|
+
procs.each{ |r| output[" #{r[:k]}=#{r[:v]}"] = if run("cd #{@deploy_to} 2>&1 /dev/null && deis scale #{r[:k]}=#{r[:v]} 2>&1 | grep 'done in\\\|#{r[:k]}.*up ' | wc -l").to_i == 2 then DEIS::Deploy::YES else DEIS::Deploy::NO end } if ! procs.nil? && procs.length > 0
|
176
|
+
end
|
177
|
+
print_table output
|
178
|
+
end
|
179
|
+
|
180
|
+
# runs everyhing in order
|
181
|
+
def all
|
182
|
+
self.git
|
183
|
+
self.create
|
184
|
+
self.config
|
185
|
+
self.domains
|
186
|
+
self.remotes
|
187
|
+
self.gems
|
188
|
+
self.push
|
189
|
+
self.scale([DEIS::Parse.first_proc])
|
190
|
+
say "Complete", :blue
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
end
|
195
|
+
end
|
data/lib/rdeis/git.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module DEIS
|
2
|
+
class Git
|
3
|
+
|
4
|
+
def self.is_git?
|
5
|
+
res = `#{DEIS::Git.is_git_cmd}`.to_i
|
6
|
+
if res == 0 then true else false end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.is_git_cmd
|
10
|
+
"git status 2>&1 | grep 'fatal: Not a git' | wc -l"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.name
|
14
|
+
remote = DEIS::Git.remote
|
15
|
+
if remote.nil? || remote.length == 0
|
16
|
+
return "na"
|
17
|
+
else
|
18
|
+
`echo #{remote} | grep "/.*\.git" -o | sed -E "s#/##" | sed -E "s#.git##" 2>/dev/null`.strip
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.remote
|
23
|
+
`c=$(git remote show | wc -l ) ; if [ "$c" -gt 0 ]; then git remote show -n origin | grep " Fetch URL:" | grep ": .*" -o | sed -E "s#: ##" 2>/dev/null ; fi`.strip
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.ref
|
27
|
+
`git rev-parse --verify HEAD 2>/dev/null`.strip
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.branch
|
31
|
+
`git rev-parse --abbrev-ref HEAD`.strip
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.init_with_remote_cmd(remote)
|
35
|
+
"git init && git remote add origin #{remote} 2>&1 | grep 'fatal:' -o | wc -l"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.checkout_to_ref_cmd(ref)
|
39
|
+
"git fetch origin && git checkout -f #{ref} 2>&1 | grep 'error:' | wc -l"
|
40
|
+
end
|
41
|
+
|
42
|
+
# find env based token
|
43
|
+
def self.github_token
|
44
|
+
v = self.github_token_varname
|
45
|
+
ENV[v]
|
46
|
+
end
|
47
|
+
|
48
|
+
# more advanced version that reads config files
|
49
|
+
def self.github_token_cmd
|
50
|
+
"cat #{DEIS::Storage::BASE_PATH}.profile | grep #{DEIS::Git.github_token_varname}=.* -o | sed -E 's##{DEIS::Git.github_token_varname}=##' | sed -E 's#\"##g'"
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.github_token_varname
|
54
|
+
"GITHUB_TOKEN"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/rdeis/parse.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
module DEIS
|
2
|
+
class Parse
|
3
|
+
|
4
|
+
# vars is an array from the cli taking the form of:
|
5
|
+
# KEY=VALUE
|
6
|
+
# KEY1=V1 KEY2=V2
|
7
|
+
# KEY1 KEY2
|
8
|
+
def self.var_array(vars)
|
9
|
+
parsed = []
|
10
|
+
if ! vars.nil? && vars.length > 0
|
11
|
+
vars.each{ |pair| parsed.push ( {:k =>DEIS::Parse.key(pair), :v=>DEIS::Parse.value(pair) } ) }
|
12
|
+
end
|
13
|
+
# reverse so the last value of the key is used, then sort alpabetically, ignoring case
|
14
|
+
parsed.reverse.uniq {|r| r[:k]}.sort{|a ,b | a[:k].downcase <=> b[:k].downcase}
|
15
|
+
end
|
16
|
+
|
17
|
+
# finds just the key from a string like KEY=VALUE
|
18
|
+
def self.key(pair)
|
19
|
+
# start by assuming there might be no value or = symbol
|
20
|
+
index = pair.length - 1
|
21
|
+
index = pair.index("=") - 1 if ! pair.index("=").nil?
|
22
|
+
# return the sub string
|
23
|
+
pair[0..index]
|
24
|
+
end
|
25
|
+
|
26
|
+
# finds just the value from a string like KEY=VALUE
|
27
|
+
def self.value(pair)
|
28
|
+
#if theres no = then presume no value, just key, so default to nil
|
29
|
+
index = pair.index("=")
|
30
|
+
length = pair.length - 1
|
31
|
+
if ! index.nil?
|
32
|
+
pair[index+1..length]
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.JSON_to_set(json)
|
39
|
+
cmd = ""
|
40
|
+
json.each{|k,v| cmd += if v.to_s.length > 0 && v.to_s != "null" then "#{k}=\"#{v}\" " else "#{k} " end}
|
41
|
+
cmd + " 2>&1"
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.JSON_to_unset(json)
|
45
|
+
cmd = ""
|
46
|
+
json.each{|k,v| cmd += "#{k} "}
|
47
|
+
cmd + " 2>&1"
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.first_proc
|
51
|
+
file = Dir.pwd+"/Procfile"
|
52
|
+
procs = []
|
53
|
+
if File.exists?(file)
|
54
|
+
File.open(file, "r") {|f| f.read}.split("\n").each do |r|
|
55
|
+
key = r.split(":").first
|
56
|
+
procs.push(key)
|
57
|
+
end
|
58
|
+
return "#{procs.first}=1"
|
59
|
+
end
|
60
|
+
nil
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module DEIS
|
2
|
+
require "json"
|
3
|
+
class Storage < Base
|
4
|
+
BASE_PATH = "$HOME/.deis/gem/#{DEIS::VERSION}/"
|
5
|
+
ENV_VAR_PATH = DEIS::Storage::BASE_PATH+".profile"
|
6
|
+
|
7
|
+
def self.file(repo, env)
|
8
|
+
BASE_PATH.gsub("$HOME", ENV['HOME'])+repo+"/#{env}.json"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.load(repo, env)
|
12
|
+
data = {}
|
13
|
+
data = JSON.parse( File.open( DEIS::Storage.file(repo, env) , "r" ) { | f | f.read } ) if File.exists? (DEIS::Storage.file(repo, env))
|
14
|
+
data
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.save(repo, env, data)
|
18
|
+
working_dir = DEIS::Storage::BASE_PATH.gsub("$HOME", ENV['HOME'])
|
19
|
+
FileUtils.mkdir_p(working_dir+repo) unless Dir.exists?(working_dir+repo)
|
20
|
+
File.open( DEIS::Storage.file(repo, env) , "w" ){ |f| f.write ( data.to_json ) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.get(repo, env, key=nil)
|
24
|
+
current = DEIS::Storage.load(repo, env)
|
25
|
+
# key asked for and is present
|
26
|
+
if ! key.nil? && current.has_key?(key)
|
27
|
+
current[key]
|
28
|
+
# key asked for but not present
|
29
|
+
elsif !key.nil?
|
30
|
+
{}
|
31
|
+
# key not asked for
|
32
|
+
else
|
33
|
+
current
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# only handles top level, not sub levels
|
38
|
+
def self.set(repo, env, key, value)
|
39
|
+
current = DEIS::Storage.load(repo, env)
|
40
|
+
# overwrite the value existing
|
41
|
+
current[key] = value
|
42
|
+
DEIS::Storage.save(repo, env, current)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.subset(repo, env, key, subkey, value)
|
46
|
+
current = DEIS::Storage.load(repo, env)
|
47
|
+
current[key] = {} if ! current.has_key?(key)
|
48
|
+
current[key][subkey] = value
|
49
|
+
# if it exists in the unset, remove it
|
50
|
+
DEIS::Storage.save(repo, env, current)
|
51
|
+
# remove from items that need to be removed
|
52
|
+
DEIS::Storage.subunset(repo, env, "removed_#{key}", subkey) if key.index("removed_").nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
# only have the option to remove low level, not top level
|
56
|
+
def self.subunset(repo, env, key, subkey)
|
57
|
+
current = DEIS::Storage.load(repo, env)
|
58
|
+
if current.has_key?(key) && current[key].has_key?(subkey)
|
59
|
+
tmp = current[key]
|
60
|
+
val = tmp[subkey]
|
61
|
+
tmp.delete(subkey)
|
62
|
+
current[key] = tmp
|
63
|
+
# save
|
64
|
+
DEIS::Storage.save(repo, env, current)
|
65
|
+
#also need to store removals for actions to be performed on the server, if check to stop recursive loops
|
66
|
+
DEIS::Storage.subset(repo, env, "removed_#{key}", subkey, val) if key.index("removed_").nil?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/lib/rdeis.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rdeis/version"
|
2
|
+
require "thor"
|
3
|
+
require "ssh"
|
4
|
+
|
5
|
+
module DEIS
|
6
|
+
require "rdeis/base"
|
7
|
+
require "rdeis/git"
|
8
|
+
require "rdeis/parse"
|
9
|
+
require "rdeis/storage"
|
10
|
+
require "rdeis/bootstrap"
|
11
|
+
require "rdeis/config"
|
12
|
+
require "rdeis/domains"
|
13
|
+
require "rdeis/deploy"
|
14
|
+
require "rdeis/deis"
|
15
|
+
end
|
data/lib/ssh.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
|
4
|
+
class SSH
|
5
|
+
|
6
|
+
def initialize(config)
|
7
|
+
@config = config
|
8
|
+
@ssh = Net::SSH.start(@config[:host], @config[:user])
|
9
|
+
end
|
10
|
+
|
11
|
+
def exec!(command)
|
12
|
+
|
13
|
+
stdout_data = ""
|
14
|
+
stderr_data = ""
|
15
|
+
exit_code = nil
|
16
|
+
@ssh.open_channel do |channel|
|
17
|
+
channel.send_channel_request "shell" do |ch, success|
|
18
|
+
unless success
|
19
|
+
abort "FAILED to connect"
|
20
|
+
end
|
21
|
+
channel.on_data {|c,data| stdout_data+=data.to_s }
|
22
|
+
channel.on_extended_data {|c,data| stderr_data+=data.to_s }
|
23
|
+
channel.on_request("exit-status") {|c,data| exit_code = data.read_long }
|
24
|
+
ch.send_data "#{command}\n"
|
25
|
+
ch.send_data "exit\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@ssh.loop
|
29
|
+
if exit_code > 0
|
30
|
+
return false
|
31
|
+
else
|
32
|
+
return stdout_data.strip
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def close
|
38
|
+
@ssh.close
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
data/rdeis.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "rdeis/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rdeis"
|
8
|
+
spec.version = DEIS::VERSION
|
9
|
+
spec.authors = ["Charles Marshall"]
|
10
|
+
spec.email = ["cm56marshall@gmail.com"]
|
11
|
+
spec.summary = %q{ }
|
12
|
+
spec.description = %q{ }
|
13
|
+
spec.homepage = "https://github.com/charlesmarshall/deis_deploy/tree/#{DEIS::VERSION}"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
spec.required_ruby_version = '>= 2.0'
|
20
|
+
|
21
|
+
spec.add_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_dependency "thor", "~> 0.19"
|
23
|
+
spec.add_dependency "net-ssh", "~> 2.9"
|
24
|
+
|
25
|
+
spec.post_install_message = ""
|
26
|
+
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdeis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charles Marshall
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.19'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.19'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: net-ssh
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.9'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.9'
|
55
|
+
description: " "
|
56
|
+
email:
|
57
|
+
- cm56marshall@gmail.com
|
58
|
+
executables:
|
59
|
+
- rdeis
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- Gemfile
|
65
|
+
- README.md
|
66
|
+
- bin/rdeis
|
67
|
+
- gemconversion
|
68
|
+
- lib/rdeis.rb
|
69
|
+
- lib/rdeis/base.rb
|
70
|
+
- lib/rdeis/bootstrap.rb
|
71
|
+
- lib/rdeis/config.rb
|
72
|
+
- lib/rdeis/deis.rb
|
73
|
+
- lib/rdeis/deploy.rb
|
74
|
+
- lib/rdeis/domains.rb
|
75
|
+
- lib/rdeis/git.rb
|
76
|
+
- lib/rdeis/parse.rb
|
77
|
+
- lib/rdeis/storage.rb
|
78
|
+
- lib/rdeis/version.rb
|
79
|
+
- lib/ssh.rb
|
80
|
+
- rdeis.gemspec
|
81
|
+
homepage: https://github.com/charlesmarshall/deis_deploy/tree/0.0.2
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message: ''
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '2.0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.2.2
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: ''
|
105
|
+
test_files: []
|