deis_deploy 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0a57435f77ae92b00838d768f60061cccf920521
4
+ data.tar.gz: f0e6faa2afb1d9ced144a619f69bb6a7a7f7dce4
5
+ SHA512:
6
+ metadata.gz: 9ef4db92538d47ce0afdfc5f5c1bc2855b1377d0f696591ccc8fafbcc611fabe8f8ef6252b0db7285282d229a7cda559e5d08d7ea86d0fa6b3dc8d4f0b1088ce
7
+ data.tar.gz: 316c93427808d327e6357ef06dc7837a51bdf6061cd529d8b245bc43d535af95709eebee7e4da468f99bcc6413c2fdeecd3e9adaa8623cc43712e4d8be22dd24
@@ -0,0 +1 @@
1
+ *.gem
@@ -0,0 +1 @@
1
+ 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ # DEIS DEPLOYMENT #
2
+
3
+ Gem to make deploying to deis much easier.
4
+
5
+ ## Install & Setup ##
6
+
7
+ <code>gem install deis_deploy</code>
8
+
9
+ ## Usage ##
10
+
11
+ <code>cd $REPO_DIR</code>
12
+ <code>deisConfig name</code>
13
+ this will give you app a name, optional
14
+ <code>deisConfig set $ENV $VARNAME $VALUE</code>
15
+ sets a variable for this application
16
+ <code>deisConfig list</code>
17
+ this will show all config values
18
+ <code>deisConfig domain $ENV $DOMAIN</code>
19
+ <code>deisConfig domains $ENV</code>
20
+ lists all domains
21
+ <code>deisDeploy staging</code>
22
+ deploys to staging cluster
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require "deis_deploy"
7
+ DEIS::Config.start(ARGV)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+ lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
5
+
6
+ require "deis_deploy"
7
+ DEIS::Deploy.start(ARGV)
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "deis_deploy/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "deis_deploy"
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 = ""
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 "colorize", "~> 0.7"
22
+ spec.add_dependency "bundler", "~> 1.5"
23
+ spec.add_dependency "thor", "~> 0.19"
24
+ spec.add_dependency "faker", "~> 1.4"
25
+ spec.add_dependency "net-ssh", "~> 2.9"
26
+
27
+ spec.post_install_message = ""
28
+
29
+ end
@@ -0,0 +1,27 @@
1
+ require "deis_deploy/version"
2
+ require "utils"
3
+ require "ssh"
4
+ require "deis_deploy/strings"
5
+
6
+ module DEIS
7
+ require "thor"
8
+ require "faker"
9
+ require 'fileutils'
10
+ require 'json'
11
+ # utils
12
+
13
+ require "deis_deploy/git"
14
+ require "deis_deploy/file_locations"
15
+ require "deis_deploy/validations"
16
+
17
+ # thor
18
+ require "deis_deploy/deploy"
19
+ require "deis_deploy/config"
20
+ # formatting vars
21
+ FORMAT_OK = "\e[0;32m%#-40s\t%5s\e[0m\n"
22
+ FORMAT_ERROR = "\e[33;40m%#-40s\t%5s\e[0m\n"
23
+ FORMAT_FATAL = "\e[0;31m%#-40s\t%5s\e[0m\n"
24
+
25
+ end
26
+
27
+ String::log_level = ENV['DEIS_GEM_LOG_LEVEL'].to_i if ! ENV['DEIS_GEM_LOG_LEVEL'].nil?
@@ -0,0 +1,280 @@
1
+ module DEIS
2
+
3
+ class Config < Thor
4
+ extend Utils
5
+ include Utils
6
+
7
+ desc "set <env> <varname> <value>", "Set <var> to <value> for <env>"
8
+ def set(env, varname, value)
9
+ DEIS::Validations.config
10
+ stored = DEIS::Config.data
11
+ current = if stored.nil? then {} else stored end
12
+ name = DEIS::Config.full_name(env)
13
+ "Setting #{varname} to #{value} in #{env}".info
14
+ "Using name: #{name}".log
15
+ sub_config = if !current[name].nil? && !current[name]["config"].nil? then current[name]["config"] else {:RACK_EV => env, :RAILS_ENV => env} end
16
+ sub_config[varname] = value
17
+ current[name] = {
18
+ :deis_name => "#{name}",
19
+ :dir => "#{name}-#{Time.now.to_i}",
20
+ :remote => DEIS::Git.remote,
21
+ :repo => DEIS::Git.repo,
22
+ :env => env,
23
+ :config => sub_config,
24
+ :removed_config => []
25
+ }
26
+ # log output
27
+ DEIS::Config.save(current)
28
+ "Complete (run 'deisDeploy #{env}' to deploy changes)".important
29
+ end
30
+
31
+ desc "domain <env> <domain_without_schema>", "Add a custom domain"
32
+ def domain(env="staging", domain)
33
+ DEIS::Validations.config
34
+ stored = DEIS::Config.data
35
+ current = if stored.nil? then {} else stored end
36
+ name = DEIS::Config.full_name(env)
37
+ "Adding domain #{domain} to #{env}".info
38
+ "Using name: #{name}".log
39
+ if current.has_key?(name)
40
+ current[name]["url"] = {} if current[name]["url"].nil?
41
+ current[name]["url"][env] = [] if current[name]["url"][env].nil?
42
+ current[name]["url"][env].push(domain)
43
+ DEIS::Config.save(current)
44
+ "Complete (run 'deisDeploy #{env}' to deploy changes)".important
45
+ else
46
+ "No config values set, create those first".fatal
47
+ exit 1
48
+ end
49
+ end
50
+
51
+ desc "domains <env>", "List all domains in <env>"
52
+ def domains(env="staging")
53
+ DEIS::Validations.config
54
+ stored = DEIS::Config.data
55
+ name = DEIS::Config.full_name(env)
56
+ current = if stored.nil? then {} else stored end
57
+ "Listing domains in #{env}..".info
58
+ if current.has_key?(name) && current[name].has_key?("url") && current[name]["url"].has_key?(env)
59
+ "Found domains".log
60
+ printf(DEIS::FORMAT_OK, "Domain", "")
61
+ printf(DEIS::FORMAT_OK, "-------------------------------", "")
62
+ current[name]["url"][env].each{|v| printf(DEIS::FORMAT_OK, "#{v}", "") }
63
+ else
64
+ "No domains found".info
65
+ end
66
+ "Complete".important
67
+ end
68
+
69
+ desc "list <env>", "List all config vars in <env>"
70
+ def list(env="staging")
71
+ DEIS::Validations.config
72
+ stored = DEIS::Config.data
73
+ name = DEIS::Config.full_name(env)
74
+ "Getting config data for #{name}\n".info
75
+ if !stored.nil? && !name.nil? && !stored[name].nil? && !stored[name]["config"].nil?
76
+ "Found data for #{name}".log
77
+ printf(DEIS::FORMAT_OK, "Name", "Value")
78
+ printf(DEIS::FORMAT_OK, "-------------------------------", "---------")
79
+ stored[name]['config'].each {|k,v| printf(DEIS::FORMAT_OK, "#{k}", "#{v}") }
80
+ else
81
+ "No data".info
82
+ end
83
+ "checking for config data that will be removed..".log
84
+ if !stored.nil? && !name.nil? && !stored[name].nil? && !stored[name]["removed_config"].nil? && stored[name]["removed_config"].size > 0
85
+ "\nThe following config items are waiting to be removed".info
86
+ printf(DEIS::FORMAT_OK, "Name", "Value")
87
+ printf(DEIS::FORMAT_OK, "-------------------------------", "---------")
88
+ stored[name]['removed_config'].each {|r| printf(DEIS::FORMAT_OK, "#{r['k']}", "#{r['v']}") }
89
+ end
90
+
91
+ "Complete".important
92
+ end
93
+
94
+ desc "rm <env> <varname>", "Remove the <varname> from the config"
95
+ def rm(env, varname)
96
+ DEIS::Validations.config
97
+ "Removing #{varname} from #{env}".info
98
+ stored = DEIS::Config.data
99
+ if !stored.nil?
100
+ name = DEIS::Config.full_name(env)
101
+ "Found data store for #{name}".log
102
+ if !stored[name].nil? && !stored[name]["config"].nil? && stored[name]["config"].has_key?(varname)
103
+ value = stored[name]["config"][varname]
104
+ "Value was #{value}".log
105
+ stored[name]["removed_config"] = [] if ! stored[name].has_key?("removed_config")
106
+ stored[name]["removed_config"].push( {:k => varname, :v => value} )
107
+ stored[name]["config"].tap{|r| r.delete(varname) }
108
+ DEIS::Config.save(stored)
109
+ end
110
+ end
111
+ "Complete (run 'deisDeploy deis_unset_config #{env}' to deploy changes)".important
112
+ end
113
+
114
+
115
+ desc "name <name>", "set the name of the app if its not been done before"
116
+ def name(name)
117
+ DEIS::Validations.config
118
+ file = DEIS::Config.name_storage+DEIS::Git.repo+".json"
119
+ if File.exists?(file)
120
+ "Cannot set name, use rename instead".fatal
121
+ exit
122
+ end
123
+ data = [ {:name => name, :active => true} ].to_json
124
+ File.open(file, "w") {|f| f.write( data ) }
125
+ "Complete".important
126
+ end
127
+
128
+ desc "names", "View all names used for this repo"
129
+ def names
130
+ DEIS::Validations.config
131
+ file = DEIS::Config.name_storage+DEIS::Git.repo+".json"
132
+ printf(DEIS::FORMAT_OK, "Name", "")
133
+ printf(DEIS::FORMAT_OK, "-------------------------------", "")
134
+ JSON.parse( File.open(file, "r"){|f| f.read} ).each{ |row| printf(DEIS::FORMAT_OK, row['name'], "")}
135
+ end
136
+
137
+ # fetch all names
138
+ def self.names(repo=nil)
139
+ repo = DEIS::Git.repo if repo.nil?
140
+ file = DEIS::Config.name_storage+repo+".json"
141
+ if File.exists?(file)
142
+ return JSON.parse( File.open(file, "r"){|f| f.read} )
143
+ else
144
+ return []
145
+ end
146
+ end
147
+
148
+ def self.save_names(names, repo=nil)
149
+ repo = DEIS::Git.repo if repo.nil?
150
+ file = DEIS::Config.name_storage+repo+".json"
151
+ if names.class == Array
152
+ names = names.to_json
153
+ end
154
+ File.open(file, "w") {|f| f.write( names ) }
155
+ end
156
+
157
+ desc "rename <env> <new_name>", "generate a new name"
158
+ def rename(env, newname=nil)
159
+ DEIS::Validations.config
160
+ repo = DEIS::Git.repo
161
+ "Warning, this may break deployed versions of this app.".warning
162
+ newname = DEIS::Config.new_name(repo) if newname.nil?
163
+ # find the current name
164
+ currentname = DEIS::Config.full_name(env)
165
+ current_short_name = DEIS::Config.name
166
+ "#{currentname}".log
167
+ names = DEIS::Config.names(repo)
168
+ exists = names.select{ |row| row['name'] == newname}
169
+ if exists.nil? || exists.size == 0
170
+ "Renaming #{current_short_name} to #{newname}".log
171
+ # adjust the name file
172
+ names = names.select!{|row| row['name'] != current_short_name}
173
+ names = [] if names.nil?
174
+ names = names.push({:name => newname, :active => true})
175
+ # adjust config file
176
+ stored = DEIS::Config.data
177
+ if stored.has_key?(currentname)
178
+ key = DEIS::Config.full_name(env, repo, newname)
179
+ stored[key] = stored[currentname]
180
+ stored[key]['deis_name'] = newname
181
+ stored.delete(currentname)
182
+ DEIS::Config.save(stored)
183
+ DEIS::Config.save_names(names.to_json, repo)
184
+ "Renamed to #{newname}".info
185
+ "Complete".important
186
+ end
187
+ else
188
+ "Cannot rename, #{newname} has already been used".fatal
189
+ end
190
+ end
191
+
192
+ # save the config array to a file
193
+ def self.save(array)
194
+ file = DEIS::Config.config_storage+"#{DEIS::Git.repo}.json"
195
+ data = array.to_json
196
+ File.open(file, "w") {|f| f.write( data ) }
197
+ end
198
+
199
+ #
200
+ def self.deis_end_point
201
+ self.target_host("deis_router_end_point")
202
+ end
203
+
204
+ # check for / generate a name and store that name in the config file
205
+ def self.name
206
+ repo = DEIS::Git.repo
207
+ names = DEIS::Config.names(repo)
208
+ if names.size > 0
209
+ name = DEIS::Config.existing_name(repo)
210
+ "Found existing name: #{name}".log
211
+ else
212
+ name = DEIS::Config.generate_name(repo)
213
+ "Created name: #{name}".log
214
+ end
215
+ return name
216
+ end
217
+
218
+ def self.existing_name(repo=nil)
219
+ repo = DEIS::Git.repo if repo.nil?
220
+ names = DEIS::Config.names(repo)
221
+ name = nil
222
+ if names && names.size > 0
223
+ content = names.select{|r| r["active"]}
224
+ name = if !content.nil? then content.first["name"] end
225
+ end
226
+ name
227
+ end
228
+
229
+ def self.new_name(repo=nil)
230
+ Faker::App.name.downcase.gsub(" ", "-")
231
+ end
232
+ def self.generate_name(repo)
233
+ name = DEIS::Config.new_name(repo)
234
+ names = DEIS::Config.names(repo)
235
+ data = names.push({:name => name, :active => true} ).to_json
236
+ DEIS::Config.save_names(data, repo)
237
+ name
238
+ end
239
+
240
+ def self.full_name(env="staging", repo=nil, name=nil)
241
+ repo = DEIS::Git.repo if repo.nil?
242
+ name = self.name if name.nil?
243
+ repo+"-"+name+"-"+env
244
+ end
245
+
246
+ def self.name_storage
247
+ self.file_store(DEIS::NAMES_STORE)
248
+ end
249
+ # make and return the directory path for data storage
250
+ def self.config_storage
251
+ self.file_store(DEIS::CONFIG_STORE)
252
+ end
253
+
254
+ # fetch & parse json file containing the data for this app
255
+ def self.data
256
+ self.config_data
257
+ end
258
+
259
+
260
+ # find and return current config
261
+ def self.current(env="staging")
262
+ name = DEIS::Config.full_name(env)
263
+ "found config name: #{name}".log
264
+ if DEIS::Config.data.has_key?(name)
265
+ return DEIS::Config.data[name]
266
+ end
267
+ return nil
268
+ end
269
+
270
+ def self.save_current(env, config, name=nil)
271
+ name = DEIS::Config.full_name(env) if name.nil?
272
+ stored = DEIS::Config.data
273
+ current = if stored.nil? then {} else stored end
274
+ current[name] = config
275
+ DEIS::Config.save(current)
276
+ end
277
+
278
+ end
279
+
280
+ end
@@ -0,0 +1,172 @@
1
+ module DEIS
2
+
3
+ class Deploy < Thor
4
+ extend Utils
5
+ include Utils
6
+
7
+ desc "staging", "Deploy to staging"
8
+ def staging
9
+ env = "staging"
10
+ name = DEIS::Config.name
11
+ host = self.target_host(env)
12
+ "Deploying '#{name}' to '#{env}' on '#{host}'".info
13
+ # fetch config data for this name
14
+ config = DEIS::Config.current(env)
15
+ # run validations
16
+ DEIS::Validations.deploy(env, host, config)
17
+ if ! config.nil?
18
+ # clone repo to $HOME/APPS/$FULL_NAME (swap if exists - add to saved config data)
19
+ # fetch
20
+ # checkout to matching branch
21
+ self.checkout(env,host, config)
22
+ # deis create $name
23
+ self.deis_create(env, host, config)
24
+ # add domain
25
+ self.deis_domain(env, host, config)
26
+ # create deis config command and run it
27
+ self.deis_unset_config(env, host, config)
28
+ self.deis_config(env, host, config)
29
+
30
+ # git push deis $branch
31
+ self.push(env, host, config)
32
+ end
33
+ end
34
+
35
+ desc "push <env> <host> <config>", "Push to deis for building"
36
+ def push(env, host=nil, config=nil)
37
+ host = self.target_host(env) if host.nil?
38
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
39
+ "Deploying..".info
40
+ ssh = SSH.new({:host => host, :user => nil})
41
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
42
+ ref = DEIS::Git.ref
43
+ branch = DEIS::Git.branch
44
+ # actually deploys it
45
+ res = ssh.exec!("cd #{location} && git push deis #{branch}:#{ref}")
46
+ "Failed to deploy".fatal if res == false
47
+ up = ssh.exec!("cd #{location} && deis scale web=1 | grep 'web\..* up' | wc -l").to_i if res != false
48
+ "Complete".important if ! up.nil? && up > 0
49
+ ssh.close
50
+ end
51
+
52
+ desc "deis_domain <env> <host> <config>", "Set a domain on the app"
53
+ def deis_domain(env, host=nil, config=nil)
54
+ host = self.target_host(env) if host.nil?
55
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
56
+ "Adding domain..".info
57
+ ssh = SSH.new({:host => host, :user => nil})
58
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
59
+ if config.has_key?("url") && config["url"].has_key?(env)
60
+ domains = config['url'][env]
61
+ domains.each do |domain|
62
+ exists = ssh.exec!("cd #{location} && deis domains | grep #{domain} -o | wc -l").to_i
63
+ res = ssh.exec!("cd #{location} && deis domains:add #{domain} | grep 400 | wc -l").to_i if exists == 0
64
+ "Domain #{domain} already in use".warning if ! res.nil? && res > 0
65
+ "Added #{domain}".info if ! res.nil? && res == 0
66
+ end
67
+ else
68
+ "No custom url to add".info
69
+ end
70
+ ssh.close
71
+
72
+ end
73
+
74
+ desc "deis_unset_config <env> <host> <config>", "Remove a series of values from deis app data"
75
+ def deis_unset_config(env, host=nil, config=nil)
76
+ host = self.target_host(env) if host.nil?
77
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
78
+ name = DEIS::Config.full_name(env)
79
+ "Checking for old config data to remove..".info
80
+ ssh = SSH.new({:host => host, :user => nil})
81
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
82
+ # run the unset calls
83
+ config['removed_config'].each{|r| ssh.exec!( "cd #{location} && deis config:unset #{r['k']}" ) }
84
+ ssh.close
85
+ config['removed_config'] = []
86
+ DEIS::Config.save_current(env, config, name)
87
+ "Removed".info
88
+ end
89
+
90
+ desc "deis_config <env> <host> <config>", "Sets config on deis for this app"
91
+ def deis_config(env, host=nil, config=nil)
92
+ host = self.target_host(env) if host.nil?
93
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
94
+ "Setting config data..".info
95
+ # presume you have a working ssh config so we dont need to worry about the ssh user
96
+ ssh = SSH.new({:host => host, :user => nil})
97
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
98
+ # generate deis config string from the config data
99
+ config_cmd = self.data_to_deis_config_set(config['config'])
100
+ res = ssh.exec!("cd #{location} && #{config_cmd}") unless config_cmd.nil?
101
+ ssh.close
102
+ if res.nil? && ! config_cmd.nil?
103
+ "Config command failed".fatal
104
+ exit 1
105
+ elsif config_cmd.nil?
106
+ "No config data to set".info
107
+ end
108
+ end
109
+
110
+ desc "deis create <env> <host> <config>", "Tries to create a deis application based on the data"
111
+ def deis_create(env, host=nil, config=nil)
112
+ host = self.target_host(env) if host.nil?
113
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
114
+
115
+ "Creating deis app".info
116
+ # presume you have a working ssh config so we dont need to worry about the ssh user
117
+ ssh = SSH.new({:host => host, :user => nil})
118
+ location = "#{DEIS::REMOTE_APP_DIR}#{config['dir']}"
119
+ # check if already created the app
120
+ app_exists = ssh.exec!("deis apps | grep #{config['deis_name']} | wc -l").to_i
121
+ creation_failed = 0
122
+ # if the app does exist, create it
123
+ if app_exists == 0
124
+ creation_failed = ssh.exec!("cd #{location} && deis create #{config['deis_name']} --cluster=#{config['env']} | grep 400 | wc -l").to_i
125
+ else
126
+ "Application alrady exists..".info
127
+ end
128
+ # if creation failed, die
129
+ if creation_failed >= 1
130
+ "Failed to create deis app".fatal
131
+ "\nThis could be due to cluster being missing, the application name may be in use or other issues.".warning
132
+ exit 1
133
+ end
134
+ # make sure this dir uses this app name
135
+ matches = ssh.exec!("sleep 1; cd #{location} && deis info | grep '#{config['deis_name']} Application' -o | wc -l").to_i
136
+ if matches != 1
137
+ "Application names do not match".fatal
138
+ exit 1
139
+ end
140
+ ssh.close
141
+
142
+ end
143
+
144
+ desc "checkout <env> <host> <config>", "runs a git clone, fetch & checkout"
145
+ def checkout(env, host=nil, config=nil)
146
+ host = self.target_host(env) if host.nil?
147
+ config = DEIS::Config.current(env) if config.nil? || config.class != Hash
148
+ # presume you have a working ssh config so we dont need to worry about the ssh user
149
+ ssh = SSH.new({:host => host, :user => nil})
150
+ # check base location exists
151
+ base = ssh.exec!("ls -lart #{DEIS::REMOTE_APP_DIR} | wc -l").to_i
152
+ # create if it doesnt
153
+ ssh.exec!("mkdir -p #{DEIS::REMOTE_APP_DIR}") if base == 0
154
+ # check location
155
+ location = ssh.exec!("ls -lart #{DEIS::REMOTE_APP_DIR}#{config['dir']} | wc -l").to_i
156
+ # clone if it doesn't exist
157
+ ssh.exec!("cd #{DEIS::REMOTE_APP_DIR} && git clone #{config['remote']} #{config['deis_name']}") if location == 0
158
+ # find current ref head
159
+ ref = DEIS::Git.branch
160
+ "current git ref: #{ref}".log
161
+ # checkout to that ref head
162
+ res = nil
163
+ res = ssh.exec!("cd #{DEIS::REMOTE_APP_DIR}#{config['dir']} && git fetch && git checkout #{ref}") unless ref.nil?
164
+ ssh.close
165
+ res
166
+ end
167
+
168
+
169
+
170
+ end
171
+
172
+ end
@@ -0,0 +1,7 @@
1
+ module DEIS
2
+ CONFIG_STORE = "#{ENV['HOME']}/.deis/Gem/config/"
3
+ NAMES_STORE = "#{ENV['HOME']}/.deis/Gem/names/"
4
+ HOSTS_STORE = "#{ENV['HOME']}/.deis/Gem/hosts/"
5
+ # remote locations
6
+ REMOTE_APP_DIR = "$HOME/APPS/"
7
+ end
@@ -0,0 +1,33 @@
1
+ module DEIS
2
+ class Git
3
+
4
+ def self.is_git?
5
+ res = `git status 2>&1 | grep 'fatal: Not a git' | wc -l`.to_i
6
+ "is git: #{res} (#{res.class})".log
7
+ if res == 0 then true else false end
8
+ end
9
+
10
+ def self.repo
11
+ remote = DEIS::Git.remote
12
+ "remote: #{remote}".log
13
+ if remote.nil? || remote.length == 0
14
+ return "na"
15
+ else
16
+ `echo #{remote} | grep "/.*\.git" -o | sed -E "s#/##" | sed -E "s#.git##" 2>/dev/null`.strip
17
+ end
18
+ end
19
+
20
+ def self.remote
21
+ `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
22
+ end
23
+
24
+ def self.ref
25
+ `git rev-parse --verify HEAD 2>/dev/null`.strip
26
+ end
27
+
28
+ def self.branch
29
+ `git rev-parse --abbrev-ref HEAD`.strip
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ require 'colorize'
2
+ class String
3
+ ##
4
+ # data logging
5
+ ##
6
+
7
+ # add a log level value to string class for output handling
8
+ # 0 = fatal only
9
+ # 1 = fatal & warnings
10
+ # 2 = fatal, warnings & important
11
+ # 3 = fatal, warnings, important & info
12
+ # 4 = fatal, warnings, important, info & log
13
+ @@log_level = 3
14
+ def self.log_level
15
+ return @@log_level
16
+ end
17
+ def self.log_level=(lvl)
18
+ @@log_level = lvl.to_i
19
+ end
20
+
21
+ # functions to output various log types
22
+ def log
23
+ if @@log_level >= 4
24
+ puts "\e[2m[#{Time.now}]: #{self}\e[22m"
25
+ end
26
+ end
27
+
28
+ def info
29
+ if @@log_level >= 3
30
+ puts self.colorize(:green)
31
+ end
32
+ end
33
+
34
+ def important
35
+ if @@log_level >= 2
36
+ puts ""
37
+ puts self.colorize(:blue)
38
+ puts ""
39
+ end
40
+ end
41
+
42
+ def warning
43
+ if @@log_level >= 1
44
+ puts self.colorize(:red)
45
+ end
46
+ end
47
+
48
+ def fatal
49
+ if @@log_level >= 0
50
+ puts self.colorize(:background => :red, :color => :white)
51
+ end
52
+ end
53
+
54
+
55
+ end
@@ -0,0 +1,33 @@
1
+ module DEIS
2
+ class Validations
3
+
4
+ def self.config
5
+ DEIS::Validations.git
6
+ end
7
+
8
+ def self.deploy(env, host, config)
9
+ # make sure a cluster exists
10
+ DEIS::Validations.cluster(env, host)
11
+ end
12
+
13
+ def self.cluster(env, host)
14
+ ssh = SSH.new({:host => host, :user => nil})
15
+ cluster = ssh.exec!("deis clusters | grep #{env} | wc -l").to_i
16
+ ssh.close
17
+ if cluster == 1 then true else false end
18
+ end
19
+
20
+ def self.git
21
+ if ! DEIS::Git.is_git?
22
+ "Not a git repository, exiting".fatal
23
+ exit 1
24
+ end
25
+ if DEIS::Git.remote.nil?
26
+ "Git remote could not be found, exiting".fatal
27
+ exit 1
28
+ end
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module DEIS
2
+ VERSION="0.0.1"
3
+ end
@@ -0,0 +1,51 @@
1
+ require 'net/ssh'
2
+ class SSH
3
+
4
+ def initialize(config)
5
+ @config = config
6
+ "SSH: #{@config[:user]}@#{@config[:host]}".log
7
+ @ssh = Net::SSH.start(@config[:host], @config[:user])
8
+ end
9
+
10
+ def exec!(command)
11
+ # I am not awesome enough to have made this method myself
12
+ # I've just modified it a bit
13
+ # Originally submitted by 'flitzwald' over here: http://stackoverflow.com/a/3386375
14
+ stdout_data = ""
15
+ stderr_data = ""
16
+ exit_code = nil
17
+ "#{command.strip}".log
18
+ @ssh.open_channel do |channel|
19
+ channel.exec(command) do |ch, success|
20
+ unless success
21
+ abort "FAILED: couldn't execute command (ssh.channel.exec)"
22
+ end
23
+ channel.on_data do |ch,data|
24
+ stdout_data+=data
25
+ end
26
+
27
+ channel.on_extended_data do |ch,type,data|
28
+ stderr_data+=data
29
+ end
30
+
31
+ channel.on_request("exit-status") do |ch,data|
32
+ exit_code = data.read_long
33
+ end
34
+ end
35
+ end
36
+ @ssh.loop
37
+ stdout_data.strip.log
38
+ stderr_data.strip.log
39
+ if exit_code > 0
40
+ return false
41
+ else
42
+ return stdout_data.strip
43
+ end
44
+ end
45
+
46
+
47
+ def close
48
+ @ssh.close
49
+ end
50
+
51
+ end
@@ -0,0 +1,41 @@
1
+ module Utils
2
+ require "thor"
3
+ include Thor::Shell
4
+
5
+ def target_host(env)
6
+ file = DEIS::HOSTS_STORE+env
7
+ if ! File.exists?(file)
8
+ host = ask "Hostname / IP for #{env}: ".colorize(:yellow)
9
+ self.file_store(DEIS::HOSTS_STORE)
10
+ File.open(file, "w"){|f| f.write(host) }
11
+ end
12
+ File.read(file)
13
+ end
14
+
15
+ def file_store(dir)
16
+ FileUtils.mkdir_p(dir) unless Dir.exists?(dir)
17
+ dir
18
+ end
19
+
20
+ def config_data
21
+ "looking for data file".log
22
+ name = DEIS::Git.repo
23
+ file = DEIS::Config.config_storage+"#{name}.json"
24
+ "data file: #{file}".log
25
+ if File.exists?(file) && ( content = File.read(file) ) && (json = JSON.parse(content))
26
+ return json
27
+ end
28
+ return nil
29
+ end
30
+
31
+
32
+ def data_to_deis_config_set(config)
33
+ if config.length > 0
34
+ string = "deis config:set "
35
+ config.each{|k,v| string += "#{k}=\"#{v.strip}\" "}
36
+ return string.strip
37
+ end
38
+ nil
39
+ end
40
+
41
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: deis_deploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Charles Marshall
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.19'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.19'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faker
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.4'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: net-ssh
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.9'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.9'
83
+ description: " "
84
+ email:
85
+ - cm56marshall@gmail.com
86
+ executables:
87
+ - deisConfig
88
+ - deisDeploy
89
+ extensions: []
90
+ extra_rdoc_files: []
91
+ files:
92
+ - ".gitignore"
93
+ - ".ruby-version"
94
+ - Gemfile
95
+ - README.md
96
+ - bin/deisConfig
97
+ - bin/deisDeploy
98
+ - deis_deploy.gemspec
99
+ - lib/deis_deploy.rb
100
+ - lib/deis_deploy/config.rb
101
+ - lib/deis_deploy/deploy.rb
102
+ - lib/deis_deploy/file_locations.rb
103
+ - lib/deis_deploy/git.rb
104
+ - lib/deis_deploy/strings.rb
105
+ - lib/deis_deploy/validations.rb
106
+ - lib/deis_deploy/version.rb
107
+ - lib/ssh.rb
108
+ - lib/utils.rb
109
+ homepage: ''
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message: ''
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '2.0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.2.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: ''
133
+ test_files: []