Class: DEIS::Deploy

Inherits:
Storage show all
Includes:
Thor::Shell
Defined in:
lib/rdeis/deploy.rb

Constant Summary

Constants inherited from Storage

Storage::BASE_PATH, Storage::ENV_VAR_PATH

Constants inherited from Base

Base::NO, Base::YES

Instance Attribute Summary collapse

Attributes inherited from Base

#ssh

Instance Method Summary collapse

Methods inherited from Storage

file, get, load, removal_complete, save, set, subset, subunset

Methods inherited from Base

#local_profile, #local_shell, #local_shell_env_include, #log, #remote_profile, #run

Constructor Details

#initialize(options) ⇒ Deploy

Returns a new instance of Deploy.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/rdeis/deploy.rb', line 7

def initialize(options)
  @repo = DEIS::Git.name
  @verbose = options["verbose"]
  @environment = options["environment"]
  @cluster = options["cluster"]
  # location data that fetch from env as well as options from thor
  @proxy = if ! options["proxy"].nil? then options["proxy"] elsif ! ENV['RDEIS_PROXY'].nil? then ENV['RDEIS_PROXY'] else nil end
  @base_path = if ! options["path"].nil? then options["path"] elsif ! ENV['RDEIS_PATH'].nil? then ENV['RDEIS_PATH'] else ENV['HOME'] end
  # git data
  @ref = DEIS::Git.ref
  @branch = DEIS::Git.branch
  @remote = DEIS::Git.remote

  @name = @repo.gsub("_", "-")+"-"+@environment
  @deploy_to = @base_path.to_s + "/"+ @name + "/"
  @ssh = SSH.new({:host => @proxy, :user => nil}) if ! @proxy.nil?
end

Instance Attribute Details

#clusterObject

Returns the value of attribute cluster.



5
6
7
# File 'lib/rdeis/deploy.rb', line 5

def cluster
  @cluster
end

#environmentObject

Returns the value of attribute environment.



5
6
7
# File 'lib/rdeis/deploy.rb', line 5

def environment
  @environment
end

#outputObject

Returns the value of attribute output.



5
6
7
# File 'lib/rdeis/deploy.rb', line 5

def output
  @output
end

#pathObject

Returns the value of attribute path.



5
6
7
# File 'lib/rdeis/deploy.rb', line 5

def path
  @path
end

#proxyObject

Returns the value of attribute proxy.



5
6
7
# File 'lib/rdeis/deploy.rb', line 5

def proxy
  @proxy
end

#verboseObject

Returns the value of attribute verbose.



5
6
7
# File 'lib/rdeis/deploy.rb', line 5

def verbose
  @verbose
end

Instance Method Details

#allObject

runs everyhing in order



197
198
199
200
201
202
203
204
205
206
207
# File 'lib/rdeis/deploy.rb', line 197

def all
  self.git
  self.create
  self.config
  self.domains
  self.remotes
  self.gems
  self.push
  self.scale([DEIS::Parse.first_proc])
  say "Complete", :blue
end

#config(mode = "rm,add") ⇒ Object

deis config:set / unset wrapper



43
44
45
# File 'lib/rdeis/deploy.rb', line 43

def config(mode="rm,add")
  self.setter("config", "unset", "set", mode)
end

#createObject

deis create wrapper



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rdeis/deploy.rb', line 26

def create
  output ={"CREATE" => ""}
  # check it exists
  exists = run("deis apps 2>&1 | grep '#{@name}' | wc -l").to_i
  output[" exists"] = if exists == 1 then DEIS::Deploy::YES else DEIS::Deploy::NO end
  # try to make it if it doesnt
  created = run("cd #{@deploy_to} && deis create #{@name} --cluster=#{@environment} 2>&1 | grep 'not found\\\|400' | wc -l").to_i if exists == 0
  output[" created"]  = if created == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end

  print_table output
  if exists == 0 && created != 0
    say "Could not create application.", :red
    exit
  end
end

#domains(mode = "rm,add") ⇒ Object

deis domains:add / remote wrapper



48
49
50
# File 'lib/rdeis/deploy.rb', line 48

def domains(mode="rm,add")
  self.setter("domains", "remove", "add", mode)
end

#gemsObject

adjust the gem files & rebuild



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/rdeis/deploy.rb', line 82

def gems
  output = {"GEMS" => ""}
  # make sure we have token in env
  token = run(DEIS::Git.github_token_cmd).to_s.strip
  token = if token.length == 0 then nil else token end
  output[" github token"] = if ! token.nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end
  # check gemfile to see if we need a github token
  file = Dir.pwd + "/Gemfile"
  contents = File.open(file, "r") { |f| f.read } if File.exists?(file)
  needed = ! contents.index("[email protected]").nil? if ! contents.nil?
  output[" git token needed"] = if ! needed.nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end

  # check to see if the token is being used already
  conversion_needed = contents.index(DEIS::Git.github_token_varname)
  output[" conversion needed"] = if conversion_needed.nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end
  # if the conversion is needed, upload the pre run ruby script that will convert and commit on the remote deploy end
  if conversion_needed.nil? && ! contents.nil? && ! token.nil?
    upload_file = File.expand_path(File.dirname(__FILE__)) + "/../../gemconversion"
    upload = File.open(upload_file, "r") { |f| f.read }
    install = run("cd #{@deploy_to} && echo -e #{Shellwords.escape(upload)} > gemconversion ; chmod 0777 gemconversion; ls | grep gemconversion | wc -l").to_i
  else
    install = 1
    output[" converted"] = DEIS::Deploy::YES
  end
  print_table output
  # if need a token, and no token is set, fail
  if ! needed.nil? && token.nil?
    say "Github token needed, but not found", :red
    exit 1
  end
  # convert gem message
  if install != 1
    say "Failed to upload Gemfile conversion", :red
    exit 1
  end

end

#gitObject

run the git checkout & clone setup



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/rdeis/deploy.rb', line 121

def git
  output = {"GIT" => ""}
  # check for directory
  directory = run( "ls -l #{@deploy_to} 2> /dev/null | wc -l").to_i
  if directory == 0
    created = run( "mkdir -p #{@deploy_to}")
    output[" directory"] = if created then DEIS::Deploy::YES else DEIS::Deploy::NO end
  else
    output[" directory"] = DEIS::Deploy::YES
  end

  # check if git & initialise
  is_git = run( "cd #{@deploy_to} && #{DEIS::Git.is_git_cmd}").to_i
  if is_git > 0
    git_init_remote = run("cd #{@deploy_to} && #{DEIS::Git.init_with_remote_cmd(@remote)}").to_i
    output[" init and remote"] = if git_init_remote == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
  else
    output[" init and remote"] = DEIS::Deploy::YES
  end
  # checkout to the correct branch from the remote
  checkout = run ("cd #{@deploy_to} && #{DEIS::Git.checkout_to_ref_cmd(@ref, @branch)}")
  output[" checkout to #{@ref[0..8]}"] = if checkout then DEIS::Deploy::YES else DEIS::Deploy::NO end
  print_table output
  if ! checkout || checkout.nil?
    say "Failed to checkout correctly", :red
    exit
  end
end

#pushObject

run a git push to the deis remote



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/rdeis/deploy.rb', line 169

def push
  output = {"PUSH" => ""}
  # make sure the profile is loaded, cd to the right place & run the converstion script.
  conversion = run(". #{self.remote_profile} && cd #{@deploy_to} && ./gemconversion | grep 'Converted and commited' | wc -l").to_i
  output[" Gem conversion"] = if conversion == 1 then DEIS::Deploy::YES else DEIS::Deploy::NO end
  # push the branch to deis
  remote_ref = run("cd #{@deploy_to} && #{DEIS::Git.ref_cmd}")
  remote_branch = run("cd #{@deploy_to} && #{DEIS::Git.branch_cmd}")
  deis = run("cd #{@deploy_to} && git push deis #{remote_branch} | grep Error | wc -l") if conversion == 1
  output[" Deis push"] =  if deis.to_i == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
  print_table output
  if conversion != 1
    say "Gem conversion & commit failed.", :red
    say "This could be due to environment settings being missing; please make sure ruby is installed and env set in .profile", :red
    exit
  end
end

#remotesObject

parse the remotes that have been created and add to local version if proxy is set this is to allow easier pushes



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/rdeis/deploy.rb', line 152

def remotes
  output = {"REMOTES" => ""}
  remote = run("cd #{@deploy_to} && " + 'git remote -v | grep "deis.*(push)" | sed -E "s#deis|\(push\)##g"').to_s.strip
  # presume the remote is an ssh protocol, as that is what deis currently sets it as
  output[" found"] = if ! remote.index("ssh://").nil? then DEIS::Deploy::YES else DEIS::Deploy::NO end

  if ! remote.nil? && remote.length > 0
    self.log(remote)
    # run this locally only, adding to the
    local_command = "cd #{Dir.pwd} && git remote add #{@name} #{remote} 2>/dev/null"
    self.log(local_command)
    `#{local_command}`
  end
  print_table output
end

#scale(vars) ⇒ Object



187
188
189
190
191
192
193
194
# File 'lib/rdeis/deploy.rb', line 187

def scale(vars)
  output = {"SCALE" => ""}
  if ! vars.nil? && vars.length > 0
    procs = DEIS::Parse.var_array(vars) if ! vars.nil? && vars.length > 0
    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' | wc -l").to_i > 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end } if ! procs.nil? && procs.length > 0
  end
  print_table output
end

#setter(name = "config", rm = "unset", add = "set", mode = "rm,add") ⇒ Object

generalised setter for config &



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rdeis/deploy.rb', line 53

def setter(name="config", rm="unset", add="set", mode="rm,add")
  output = {"#{name.upcase}" => ""}
  if ! mode.index("rm").nil?
    removed = DEIS::Storage.get(@repo, @environment, "removed_#{name}")
    remove =DEIS::Parse.JSON_to_unset(removed) if removed.length > 0
    remove_res = run("cd #{@deploy_to} && deis #{name}:#{rm} #{remove} | grep 'not found\\\|400' | wc -l").to_i if !remove.nil? && remove.length > 0
    # remove the removal flagged data, as its now deleted
    DEIS::Storage.removal_complete(@repo, @environment, "removed_#{name}") if remove_res == 0
    output[" unset"] = if remove_res == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
  end

  if ! mode.index("add").nil?
    to_add = DEIS::Storage.get(@repo, @environment, name)
    set = DEIS::Parse.JSON_to_set(to_add) if to_add.length > 0
    set_res = run("cd #{@deploy_to} && deis #{name}:#{add} #{set} | grep 'not found\\\|400' | wc -l").to_i if !set.nil? && set.length > 0

    output[" set"] = if set_res == 0 then DEIS::Deploy::YES else DEIS::Deploy::NO end
  end
  print_table output
  # if there were things to set, that ran, but failed, throw
  if !set.nil? && ! set_res.nil? && set_res > 0
    say "#{name.upcase} failed to set.. please check manually", :red
    say "This may have failed due to values for #{name.upcase} already being set", :red
  end

end