Class: Starter

Inherits:
Object
  • Object
show all
Defined in:
lib/vpsmatrix/starter.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.start(args) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/vpsmatrix/starter.rb', line 16

def self.start args
  if ARGV[0]=~/^-/
    switches = ARGV.shift
    if switches == '-hv' || switches == '-vh'
      puts "vpsx #{Vpsmatrix::VERSION}"
      usage
    elsif
    switches == '-v'
      puts "vpsx #{Vpsmatrix::VERSION}"
      exit
    else
      usage
    end
  end

  @environment = args.shift
  @action = args.shift

  #environments = %w{demo prod}
  #fail "\nUnknown environment. Available environments: #{environments.join(', ')}" unless environments.include?(@environment)
  #actions = %w{deploy init}
  #fail "\nUknown action. Available actions: #{actions.join(', ')}" unless actions.include?(@action)
  case @action
    when "deploy"
      Starter.new.send("#{@environment}_#{@action}")
    when "config"
      Starter.new.send(@action)
    else
      usage
  end
end

.usageObject



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/vpsmatrix/starter.rb', line 229

def self.usage
  puts
  puts 'Usage:'
  puts 'vpsx [-options] [environment action]'
  puts
  puts '  Available environments: demo'
  puts '  Available actions:      deploy'
  puts
  puts 'Options:'
  puts ' -h print this help'
  puts ' -v print version'
  puts
  puts 'Example:'
  puts '  rails new fooapp'
  puts '  cd fooapp'
  puts '  rails g scaffold foo'
  puts '  vpsx demo deploy'
  exit
end

Instance Method Details

#configObject

Configure how app is



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/vpsmatrix/starter.rb', line 78

def config
  @app_config = Conf.new
  api_key = 

  resolve_vps(api_key)
  resolve_upload_strategy

  app_name = `pwd`.split("/").last.gsub("\n", "")
  @app_config.write("app_name", app_name)
  ## create service user
  # API will check existing "service" user in VPS -> for communication between user's VPSs
  # if not it will be created with ssh keys -> these keys will be saved to ~/.vpsx.yml (used for all other VPS)
  # take private ssh key from existing server

  # TODO check if user exists
  ssh_key_for_git = create_app_user(api_key)
  puts ssh_key_for_git

  resolve_database
  resolve_domain

  ## TODO solve this
  ## ask user for any ENV variables he may need? Like mailgun? mail server? redis? anything else?
  # pass ENV variables to set settings of projects
end

#demo_deployObject

desc ‘demo deploy’, ‘run demo deploy to deploy app to VPS Matrix demo server’



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/vpsmatrix/starter.rb', line 136

def demo_deploy

  unless Conf.new.content['ssh_key']
    Conf.new.write 'ssh_key', SecureRandom.hex
  end

  @app_name = Dir.pwd.split(File::SEPARATOR).last
  unless Conf.new.content['api_key'] && Conf.new.content['api_key'].length == 32
    # ask for it to server
    # TODO check if server returns api_key
    api_key = send_get_request "https://api.vpsmatrix.net/uploads/get_api_key"
    if api_key.response.code == '200'
      Conf.new.write 'api_key', api_key.response.body
    end
  end

  #register_email
  read_files
  stream_file
end

#loginObject

Login user; create if not existing; add api_key to ~/.vpsx.yml for future use



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/vpsmatrix/starter.rb', line 50

def 
  # check ~/.vpsx.yml for api key
  @config = Conf.new("home")
  return @config.content['api_key'] if Conf.new("home").content['api_key']

  puts "Getting api key"
  email = prompt(nil, "Insert email: ")
  p email
  password = prompt(nil, "Insert password (provide new if new user): ")
  res = send_put_request "#{API_TEST_SERVER}/login", {email: email, password: password}
  json = JSON.parse(res.body)
  case
    when json["result"] == "ok"
      # save api_key to ~/.vpsx.yml
      puts json["api_key"]
      @config.write 'api_key', json["api_key"]
      @config.content['api_key']
    when json["result"] == "new_account"
      puts "Confirm your e-mail and run this script again"
      # TODO find way how to get back after user confirmed mail (run login again?)
      abort
    else
      puts "There is something very bad, call help."
      abort
  end
end

#prod_deployObject



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/vpsmatrix/starter.rb', line 104

def prod_deploy
  # TODO should be more sofisticated -> now in case of problems during .vpsx.yml creation there is no possibility to go back to questionnaire
  # TODO do some checks of validity of .vpsx.yml !!!
  return puts("There is no config file. Run vpsx config first.") && abort unless File.exist?(".vpsx.yml") # && is_valid?

  @app_config = Conf.new
  api_key =  # use api for all the rest of communication

  # send to API and install on chosen VPS
  puts 'Deploying app'
  uri = URI.parse("#{Vpsmatrix::API_TEST_SERVER}/uploads/deploy_to_production")

  Net::HTTP.start(uri.host, 3000, :read_timeout => 500) do |http|
    req = Net::HTTP::Put.new(uri)
    req.add_field("Content-Type","multipart/form-data;")
    req.add_field('Transfer-Encoding', 'chunked')
    req['authorization'] = "Token token=#{api_key}"
    req.set_form_data(@app_config.content)

    http.request req do |response|
      puts ""
      response.read_body do |chunk|
        print chunk
      end
      if response.code != '200'
        puts response.code
      end
    end
  end
end

#read_dirsObject



216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/vpsmatrix/starter.rb', line 216

def read_dirs
  working_dir = Dir.pwd
  list_of_files = Dir.glob "#{working_dir}/**/*"
  dirs_string = ""

  list_of_files.map do |file|
    if File.directory file
      dirs_string += "#{file}\n"
    end
  end
  dirs_string
end

#read_filesObject



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/vpsmatrix/starter.rb', line 157

def read_files
  @multipart_boundary = '-'*16 + SecureRandom.hex(32)

  puts 'Writing files to temporary file'
  # TODO check size of directory
  working_dir = Dir.pwd
  list_of_files = Dir.glob "#{working_dir}/**/*"
  list_of_files.reject! {|path| path =~ /#{working_dir}\/log|#{working_dir}\/tmp/}
  unless Dir.exists?("tmp")
   Dir.mkdir("tmp")
  end
  File.open("tmp/files_to_send", 'w') do |temp_file|
    temp_file.write "#{@multipart_boundary}\n"
    list_of_files.each do |file|
      if File.file? file
        file_content = File.read(file, mode: 'rb')
        temp_file.write "#{working_dir.split('/').last + file.split(working_dir).last}\n"
        temp_file.write "#{file_content.size}\n"
        temp_file.write "#{file_content}\n"
        temp_file.write "#{Digest::SHA256.hexdigest(file_content)}\n"
      else
        temp_file.write "#{working_dir.split('/').last + file.split(working_dir).last}\n"
        temp_file.write "DIR\n"
      end
    end
    temp_file.write "#{@multipart_boundary}\n"
  end
end

#stream_fileObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/vpsmatrix/starter.rb', line 186

def stream_file
  puts 'Stream file to server'
  uri = URI.parse("https://api.vpsmatrix.net/uploads/send_new_files")

  # stream version
  Net::HTTP.start(uri.host, uri.port, use_ssl: true, :read_timeout => 500) do |http|
    req = Net::HTTP::Put.new(uri)
    req.add_field("Content-Type","multipart/form-data; boundary=#{@multipart_boundary}; ssh_key=#{Conf.new.content['ssh_key']}; api_key=#{Conf.new.content['api_key']}")
    req.add_field('Transfer-Encoding', 'chunked')
    req.basic_auth("test_app", "test_app")
    File.open('tmp/files_to_send', 'rb') do |io|
      req.content_length = io.size
      req.body_stream = io
      UploadProgress.new(req) do |progress|
        print "uploaded so far: #{ progress.upload_size }/#{ io.size }\r"
        $stdout.flush
      end
      http.request req do |response|
        puts ""
        response.read_body do |chunk|
          print chunk
        end
        if response.code != '200'
          puts response.code
        end
      end
    end
  end
end