forked from heroku/vulcan
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 60d4eee
Showing
142 changed files
with
14,709 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.env | ||
node_modules | ||
pkg/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
source "http://rubygems.org" | ||
|
||
gemspec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
PATH | ||
remote: . | ||
specs: | ||
vulcan (0.0.1) | ||
multipart-post (~> 1.1.3) | ||
rest-client (~> 1.6.7) | ||
thor (~> 0.14.6) | ||
|
||
GEM | ||
remote: http://rubygems.org/ | ||
specs: | ||
mime-types (1.16) | ||
multipart-post (1.1.3) | ||
rest-client (1.6.7) | ||
mime-types (>= 1.16) | ||
thor (0.14.6) | ||
|
||
PLATFORMS | ||
ruby | ||
|
||
DEPENDENCIES | ||
vulcan! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/usr/bin/env ruby | ||
|
||
require "net/http/post/multipart" | ||
require "tmpdir" | ||
require "uri" | ||
require "vulcan/cli" | ||
|
||
Vulcan::CLI.start | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module Vulcan | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
require "digest/sha1" | ||
require "net/http/post/multipart" | ||
require "rest_client" | ||
require "thor" | ||
require "tmpdir" | ||
require "uri" | ||
require "vulcan" | ||
require "yaml" | ||
|
||
class Vulcan::CLI < Thor | ||
|
||
desc "build [COMMAND]", <<-DESC | ||
build a piece of software for the heroku cloud using COMMANd as a build command | ||
if no COMMAND is specified, a sensible default will be chosen for you | ||
DESC | ||
|
||
method_option :command, :aliases => "-c", :desc => "the command to run for compilation" | ||
method_option :name, :aliases => "-n", :desc => "the name of the library (defaults ot the directory name)" | ||
method_option :output, :aliases => "-o", :desc => "output build artifacts to this file" | ||
method_option :prefix, :aliases => "-p", :desc => "the build/install --prefix of the software" | ||
method_option :source, :aliases => "-s", :desc => "the source directory to build from" | ||
method_option :verbose, :aliases => "-v", :desc => "show the full build output", :type => :boolean | ||
|
||
def build | ||
app = read_config[:app] || "need a server first, use vulcan create" | ||
|
||
command = options[:command] || "./configure --prefix #{prefix} && make install" | ||
name = options[:name] || File.basename(Dir.pwd) | ||
output = options[:output] || "/tmp/#{name}.tgz" | ||
prefix = options[:prefix] || "/app/vendor/#{name}" | ||
source = options[:source] || Dir.pwd | ||
server = URI.parse(ENV["MAKE_SERVER"] || "http://#{app}.herokuapp.com") | ||
|
||
Dir.mktmpdir do |dir| | ||
puts ">> Packaging local directory" | ||
%x{ cd #{source} && tar czvf #{dir}/input.tgz . 2>&1 } | ||
|
||
puts ">> Uploading code for build" | ||
File.open("#{dir}/input.tgz", "r") do |input| | ||
request = Net::HTTP::Post::Multipart.new "/make", | ||
"code" => UploadIO.new(input, "application/octet-stream", "input.tgz"), | ||
"command" => command, | ||
"prefix" => prefix | ||
|
||
puts ">> Building with: #{command}" | ||
response = Net::HTTP.start(server.host, server.port) do |http| | ||
http.request(request) do |response| | ||
response.read_body do |chunk| | ||
print chunk if options[:verbose] | ||
end | ||
end | ||
end | ||
|
||
error "Unknown error, no build output given" unless response["X-Make-Id"] | ||
|
||
puts ">> Downloading build artifacts to: #{output}" | ||
|
||
File.open(output, "w") do |output| | ||
begin | ||
output.print RestClient.get("#{server}/output/#{response["X-Make-Id"]}") | ||
rescue Exception => ex | ||
puts ex.inspect | ||
end | ||
end | ||
end | ||
end | ||
rescue Errno::EPIPE | ||
error "Could not connect to build server: #{server}" | ||
end | ||
|
||
desc "create APP_NAME", <<-DESC | ||
create a build server on Heroku | ||
DESC | ||
|
||
def create(name) | ||
secret = Digest::SHA1.hexdigest("--#{rand(10000)}--#{Time.now}--") | ||
|
||
Dir.mktmpdir do |dir| | ||
Dir.chdir(dir) do | ||
system "env BUNDLE_GEMFILE= heroku create #{name} -s cedar" | ||
end | ||
end | ||
write_config :ap=> name, :host => "#{name}.herokuapp.com", :secret => secret | ||
update | ||
end | ||
|
||
|
||
desc "update", <<-DESC | ||
update the build server | ||
DESC | ||
|
||
def update | ||
error "no apyet, create first" unless config[:app] | ||
|
||
FileUtils.mkdir_p File.expand_path("~/.heroku/plugins/heroku-credentials") | ||
|
||
File.open(File.expand_path("~/.heroku/plugins/heroku-credentials/init.rb"), "w") do |file| | ||
file.puts <<-CONTENTS | ||
class Heroku::Command::Credentials < Heroku::Command::Base | ||
def index | ||
puts Heroku::Auth.password | ||
end | ||
end | ||
CONTENTS | ||
end | ||
|
||
Dir.mktmpdir do |dir| | ||
Dir.chdir(dir) do | ||
api_key = %x{ env BUNDLE_GEMFILE= heroku credentials } | ||
|
||
system "git init" | ||
system "git remote add heroku git@heroku.com:#{config[:app]}.git" | ||
FileUtils.cp_r "#{server_path}/.", "." | ||
File.open(".gitignore", "w") do |file| | ||
file.puts ".env" | ||
file.puts "node_modules" | ||
end | ||
system "ls -la" | ||
system "git add ." | ||
system "git commit -m commit" | ||
system "git push heroku -f master" | ||
|
||
%x{ env BUNDLE_GEMFILE= heroku config:add SECRET=#{config[:secret]} SPAWN_ENV=heroku HEROKU_APP=#{config[:app]} HEROKU_API_KEY=#{api_key} 2>&1 } | ||
%x{ env BUNDLE_GEMFILE= heroku addons:add cloudant:oxygen } | ||
end | ||
end | ||
end | ||
|
||
private | ||
|
||
def config_file | ||
File.expand_path("~/.vulcan") | ||
end | ||
|
||
def config | ||
read_config | ||
end | ||
|
||
def read_config | ||
return {} unless File.exists?(config_file) | ||
config = YAML.load_file(config_file) | ||
config.is_a?(Hash) ? config : {} | ||
end | ||
|
||
def write_config(config) | ||
full_config = read_config.merge(config) | ||
File.open(config_file, "w") do |file| | ||
file.puts YAML.dump(full_config) | ||
end | ||
end | ||
|
||
def error(message) | ||
puts "!! #{message}" | ||
exit 1 | ||
end | ||
|
||
def server_path | ||
File.expand_path("../../../server", __FILE__) | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module Vulcan | ||
|
||
VERSION = "0.0.1" | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: node web.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#!/usr/bin/env ruby | ||
|
||
ENV["GEM_HOME"] = File.expand_path("../../vendor/gems", __FILE__) | ||
ENV["GEM_PATH"] = File.expand_path("../../vendor/gems", __FILE__) | ||
|
||
require "rubygems" | ||
|
||
id = ARGV.shift | ||
command = ARGV.shift | ||
prefix = ARGV.shift | ||
|
||
require "couchrest" | ||
require "fileutils" | ||
require "tmpdir" | ||
|
||
db = CouchRest.database!(ENV["CLOUDANT_URL"] + ":5984/make") | ||
|
||
Dir.mktmpdir do |dir| | ||
Dir.chdir(dir) do | ||
doc = db.get(id) | ||
|
||
File.open("input.tgz", "wb") do |file| | ||
file.print doc.fetch_attachment("input") | ||
end | ||
|
||
FileUtils.mkdir_p "input" | ||
|
||
Dir.chdir("input") do | ||
%x{ tar xzf ../input.tgz 2>&1 } | ||
system command | ||
end | ||
|
||
Dir.chdir(prefix) do | ||
%x{ tar czf #{dir}/output.tgz * 2>&1 } | ||
end | ||
|
||
doc.put_attachment("output", File.open("#{dir}/output.tgz")) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
var events = require('events'); | ||
|
||
module.exports.inject = function(object) { | ||
object.emitter = events.EventEmitter(); | ||
|
||
object.on = function(key, handler) { | ||
object.emitter.on(key, handler); | ||
} | ||
|
||
object.emit = function() { | ||
object.emitter.emit(arguments); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
var events = require('events'); | ||
var https = require('https'); | ||
var net = require('net'); | ||
var qs = require('querystring'); | ||
var restler = require('restler'); | ||
var spawn = require('child_process').spawn; | ||
var tls = require('tls'); | ||
|
||
var Spawner = function(env) { | ||
|
||
require('on').inject(this); | ||
|
||
this.env = env || process.env.SPAWN_ENV || 'local'; | ||
|
||
var cs = this; | ||
|
||
this.spawn = function(command, callback) { | ||
var spawner = cs['spawn_' + cs.env]; | ||
|
||
if (!spawner) { | ||
callback('no spawner for env: ' + cs.env); | ||
return(new events.EventEmitter()); | ||
} else { | ||
console.log('spawning on %s: %s', cs.env, command); | ||
return(spawner(command, callback)); | ||
} | ||
} | ||
|
||
this.spawn_local = function(command, callback) { | ||
var args = command.match(/("[^"]*"|[^"]+)(\s+|$)/g); | ||
var command = args.shift().replace(/\s+$/g, ''); | ||
|
||
args = args.map(function(arg) { | ||
return(arg.match(/"?([^"]*)"?/)[1]); | ||
}); | ||
|
||
var proc = spawn(command, args, { env: process.env }); | ||
var emitter = new events.EventEmitter(); | ||
|
||
proc.stdout.on('data', function(data) { | ||
emitter.emit('data', data); | ||
}); | ||
|
||
proc.stderr.on('data', function(data) { | ||
emitter.emit('data', data); | ||
}); | ||
|
||
proc.on('exit', function(code) { | ||
emitter.emit('exit', code); | ||
}); | ||
|
||
return(emitter); | ||
} | ||
|
||
this.spawn_heroku = function(command, callback) { | ||
var api_key = process.env.HEROKU_API_KEY; | ||
var app = process.env.HEROKU_APP; | ||
var emitter = new events.EventEmitter(); | ||
|
||
var auth = new Buffer(':' + api_key).toString('base64'); | ||
|
||
restler.post('https://api.heroku.com/apps/' + app + '/ps', { | ||
headers: { | ||
'Authorization': auth, | ||
'Accept': 'application/json' | ||
}, | ||
data: { | ||
attach: true, | ||
command: command, | ||
'ps_env[AMAZON_BUCKET]': '' | ||
}, | ||
}).on('success', function(data) { | ||
|
||
var url = require('url').parse(data.rendezvous_url); | ||
var rendezvous = new net.Socket(); | ||
|
||
rendezvous.connect(url.port, url.hostname, function() { | ||
rendezvous.write(url.pathname.substring(1) + '\n'); | ||
}); | ||
|
||
rendezvous.on('data', function(data) { | ||
if (data != 'rendezvous\r\n') { | ||
emitter.emit('data', data); | ||
} | ||
}); | ||
|
||
rendezvous.on('end', function() { | ||
emitter.emit('exit', 0); | ||
}); | ||
|
||
}).on('error', function(error) { | ||
emitter.emit('error', error); | ||
}); | ||
|
||
return(emitter); | ||
} | ||
} | ||
|
||
module.exports.create = function(env) { | ||
return new Spawner(env); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "heroku-make", | ||
"version": "0.0.1", | ||
"dependencies": [ | ||
"connect-form", | ||
"cradle", | ||
"express", | ||
"knox", | ||
"node-uuid", | ||
"restler" | ||
] | ||
} |
Oops, something went wrong.