Class: VaeLocal

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

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.run_trapping_exceptions!Object



201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/vae.rb', line 201

def self.run_trapping_exceptions!
  begin
    v = VaeLocal.new
    v.run!
  rescue VaeError => e
    cmd = $0
    cmd = "vae" if cmd =~ /\.\.\/vae_local/
    puts "** Error:"
    puts "   " + e.to_s
    puts "Type #{cmd} --help for help."
  end
end

Instance Method Details

#fetch_from_vaeplatform(site, req) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/vae.rb', line 33

def fetch_from_vaeplatform(site, req)
  http = Net::HTTP.new("#{site}.vaeplatform.com", 443)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  http.start { |http|
    http.read_timeout = 120
    http.request(req)
  }
end

#get_svn_credentials(site) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/vae.rb', line 43

def get_svn_credentials(site)
  home = Dir.chdir { Dir.pwd }
  Dir.glob("#{home}/.subversion/auth/svn.simple/*").each do |file|
    params = parse_svn_auth_file(file)
    if params["svn:realmstring"] =~ /<http:\/\/svn(\.|_)#{site}.(vae|verb)site.com/ or params["svn:realmstring"] =~ /<http:\/\/#{site}(\.|_)svn.(vae|verb)site.com/
      return params
    end
  end
  {}
end

#parse_svn_auth_file(file) ⇒ Object



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

def parse_svn_auth_file(file)
  key = nil
  mode = nil
  params = {}
  File.read(file).each_line do |line|
    line.strip!
    if mode == :key
      key = line
      mode = nil
    elsif mode == :value
      params[key] = line
      mode = nil
    else
      if line[0,1] == "K"
        mode = :key
      elsif line[0, 1] == "V"
        mode = :value
      end
    end
  end
  params
end

#run!Object

Raises:



77
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
103
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/vae.rb', line 77

def run!
  options = { :port => 9999 }
  ARGV.options  do |opts|
    opts.banner = BANNER + "\n\nUsage: vae [options]\n         starts a local development server\n       vae [options] deploy\n         promotes the source in Subversion repository to the FTP\n\n  If you are using the Vae Production environment features:\n       vae [options] stage\n         promotes the source in Subversion repository to the staging environment\n       vae [options] stagerelease\n         promotes the source in Subversion repository to the staging environment\n         and releases it to the production environment\n       vae [options] release\n         releases the current staging environment to the production environment\n       vae [options] rollback\n         rolls back the production environment to a previous release\n\nAvailable Options:"
    opts.on("-u","--username <username>","Your Vae username") { |o| options[:username] = o } 
    opts.on("-p","--port <port number>","Start server on this port") { |o| options[:port] = o } 
    opts.on("-r","--root <path to site root>","Path to the root of the local copy of your Vae site.") { |o| options[:site_root] = o }   
    opts.on("-s","--site <subdomain>","Vae subdomain for this site") { |o| options[:site] = o }  
    opts.on_tail("-h","--help", "Show this help message") { puts opts; exit }
    opts.parse!
  end
  options[:site_root] = Dir.pwd if options[:site_root].nil? and (File.exists?("#{Dir.pwd}/__vae.yml") or File.exists?("#{Dir.pwd}/__verb.yml"))
  if options[:site_root]
    [ "verb", "vae" ].each do |name|
      if File.exists?("#{options[:site_root]}/__#{name}.yml")
        site_conf_file = File.read("#{options[:site_root]}/__#{name}.yml")
        site_conf = YAML.load(site_conf_file)
        options[:site] = site_conf[name]["site"] if site_conf[name] and site_conf[name]["site"]
      end
    end
  end
  raise VaeError, "We could not determine the Vae subdomain for this site.  Please specify it manually by using the --site option or create a __vae.yml file within the site root." if options[:site].nil?
  unless options[:username]
    svn_credentials = get_svn_credentials(options[:site])
    options[:username] = svn_credentials["username"]
    options[:password] = svn_credentials["password"]
  end
  raise VaeError, "We could not determine the Vae username that you use.  Please specify it manually by using the --username option." if options[:username].nil?
  if options[:password].nil?
    options[:password] = ask("Please enter the Vae password for username #{options[:username]}:") {|q| q.echo = false}
  end
  if [ "deploy", "release", "rollback", "stage", "stagerelease" ].include?(ARGV.last)
    stagerelease(ARGV.last, options[:site], options[:username], options[:password])
    exit
  end

  # Move mongrel dependency here so not as required on Windows

  raise VaeError, "You did not specify the path to the root of the local copy of your Vae site.  Please specify it manually by using the --root option or cd to the site root (and make sure it contains a __vae.yml file)." unless options[:site_root]
  raise VaeError, "You specified an invalid path to the local copy of your Vae site." unless File.exists?(options[:site_root])

  $biglock = Mutex.new
  dw = DirectoryWatcher.new options[:site_root], :interval => 1.0, :glob => SERVER_PARSED_GLOB, :pre_load => true, :logger => DirectoryWatcher::NullLogger.new
  dw.add_observer { |*args| 
    args.each { |event|
      path = event.path.gsub($site.root, "")
      $biglock.synchronize {
        $changed[path] = event.type
      }
    }
  }
  dw.start

  set_mime_types

  Dir.chdir File.dirname(__FILE__)
  puts BANNER
  puts "Vae is in action at http://localhost:#{options[:port]}/"  
  puts "  (hit Control+C to exit)"
  $site = Site.new(:subdomain => options[:site], :root => options[:site_root], :username => options[:username], :password => options[:password])
  $cache = {}
  $changed = {}
  $server = Mongrel::Configurator.new :host => "0.0.0.0", :port => options[:port] do
    listener do
      uri "/", :handler => VaeSiteServlet.new
      #uri "/__welcome/", :handler => VaeLocalServlet.new
    end
    trap("INT") { raise Mongrel::StopServer }
    run
  end

  begin
    $server.join
  rescue Mongrel::StopServer
    puts "Thanks for using Vae!"
  end
end

#set_mime_typesObject



178
179
180
181
# File 'lib/vae.rb', line 178

def set_mime_types
  WEBrick::HTTPUtils::DefaultMimeTypes.store 'js', 'application/javascript'
  WEBrick::HTTPUtils::DefaultMimeTypes.store 'svg', 'image/svg+xml'
end

#show_job_status(res, site) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/vae.rb', line 155

def show_job_status(res, site)
  data = JSON.parse(res.body)
  if data['error']
    raise VaeError, data['error']
  else
    puts "Request started, waiting for completion..."
    loop do
      sleep 5
      req = Net::HTTP::Get.new("/api/local/v1/job_status/#{data['job']}")
      res = fetch_from_vaeplatform(site, req)
      status = JSON.parse(res.body)
      if status['status'] == "completed"
        puts data['success']
        return
      elsif status['status'] != "working"
        raise VaeError, "Got the following error from Vae Platform: #{status['message']}"
      end
    end
  end
rescue JSON::ParserError
  raise VaeError, "An unknown error occurred requesting this operation from Vae Platform.  Please email support for help."
end

#stagerelease(action, site, username, password) ⇒ Object



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/vae.rb', line 183

def stagerelease(action, site, username, password)
  if action == "deploy"
    action = "stage"
  elsif action == "stagerelease"
    stagerelease("stage", site, username, password)
    stagerelease("release", site, username, password)
    return
  end
  req = Net::HTTP::Post.new("/api/local/v1/#{action}")
  req.body = "username=#{CGI.escape(username)}&password=#{CGI.escape(password)}&vae_local=1"
  res = fetch_from_vaeplatform(site, req)
  if res.is_a?(Net::HTTPFound)
    raise VaeError, "Invalid username/password or insufficient permissions."
  else
    show_job_status(res, site)
  end
end