conjure 0.0.0 → 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.
data/History.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### Version 0.0.1
2
+ 2013-10-11
3
+
4
+ * Deploy to cloud servers using Docker and DigitalOcean
5
+ * Import and export the deployed app's database
6
+ * Documentation improvements
7
+
1
8
  ### Version 0.0.0
2
9
  2013-10-07
3
10
 
data/README.md CHANGED
@@ -1,5 +1,88 @@
1
- ### Conjure
1
+ ## Conjure
2
2
 
3
3
  Magically powerful deployment for Rails applications.
4
4
 
5
- _More instructions forthcoming._
5
+ ### Requirements
6
+
7
+ Deploying a Rails application with Conjure currently requires the
8
+ following:
9
+
10
+ * A DigitalOcean account
11
+
12
+ * A Public/private SSH keypair to use for bootstrapping new cloud
13
+ servers. Generating a new keypair for this purpose is recommended.
14
+
15
+ Also, your Rails application requires all of the following:
16
+
17
+ * It must have a `.ruby-version` file indicating which version of
18
+ Ruby to run
19
+
20
+ * It must be able to run in production mode with a single
21
+ Postgres database (any existing database.yml will be ignored)
22
+
23
+ * It must be checked out locally into a git repository with a valid
24
+ `origin` remote
25
+
26
+ * The public SSH key you're using must have permission to check out
27
+ the project from `origin`
28
+
29
+ ### Getting Started
30
+
31
+ First, install the Conjure gem by either adding it to your Gemfile
32
+
33
+ group :development do
34
+ gem "conjure"
35
+ end
36
+
37
+ and then running `bundle`, OR by installing it directly:
38
+
39
+ gem install conjure
40
+
41
+ Then add a file to your Rails project called
42
+ `config/conjure.yml`. This should be a YAML file with the following
43
+ fields (all fields are required):
44
+
45
+ * `digitalocean_client_id` and `digitalocean_api_key`: These
46
+ credentials are available after logging in to your Digital Ocean
47
+ account.
48
+
49
+ * `digitalocean_region`: The geographic region for deploying new
50
+ cloud servers. If unsure, use "New York 1".
51
+
52
+ * `private_key_file` and `public_key_file`: Pathnames to local files
53
+ (relative to your project's `config` directory) that contain the
54
+ private and public SSH keys to use for deployment. It's
55
+ recommended to generate a new keypair rather than using your
56
+ personal SSH keys, since Conjure currently copies the specified
57
+ private key to the server during deployment.
58
+
59
+ Here's an example conjure.yml file:
60
+
61
+ digitalocean_client_id: XXXXXXXX
62
+ digitalocean_api_key: XXXXXXXX
63
+ digitalocean_region: New York 1
64
+ private_key_file: conjure_key
65
+ public_key_file: conjure_key.pub
66
+
67
+ Finally, tell Conjure to deploy your app:
68
+
69
+ conjure deploy
70
+
71
+ The last line of the output will tell you the IP address of the
72
+ deployed server. Repeating the command will reuse the existing server
73
+ rather than deploying a new one.
74
+
75
+ ### Additional Commands
76
+
77
+ These commands are available after you've deployed with `conjure
78
+ deploy`.
79
+
80
+ conjure export FILE
81
+
82
+ This will produce a Postgres SQL dump of the currently-deployed
83
+ server's production database, and save it to the local file `FILE`.
84
+
85
+ conjure import FILE
86
+
87
+ This will overwrite the production database on the currently-deployed
88
+ server with a Postgres SQL dump from the local file `FILE`.
data/lib/conjure.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Conjure
2
2
 
3
- VERSION = "0.0.0" unless defined?(VERSION)
3
+ VERSION = "0.0.1" unless defined?(VERSION)
4
4
  autoload :Command, "conjure/command"
5
5
  autoload :Service, "conjure/service"
6
6
 
@@ -1,10 +1,57 @@
1
1
  module Conjure
2
2
  class Command < Thor
3
3
  desc "deploy", "Deploys the app"
4
- def deploy(source_path = Dir.pwd)
5
- Service::RailsApplication.create source_path
4
+ def deploy
5
+ Service::RailsApplication.create github_url, app_name, rails_environment, config(Dir.pwd)
6
+ end
7
+
8
+ desc "import FILE", "Imports the production database from a postgres SQL dump"
9
+ def import(file)
10
+ Service::PostgresClient.create(docker_host, "#{app_name}_#{rails_environment}").import file
11
+ puts "[export] #{File.size file} bytes imported from #{file}"
12
+ end
13
+
14
+ desc "export FILE", "Exports the production database to a postgres SQL dump"
15
+ def export(file)
16
+ Service::PostgresClient.create(docker_host, "#{app_name}_#{rails_environment}").export file
17
+ puts "[export] #{File.size file} bytes exported to #{file}"
18
+ end
19
+
20
+ default_task :help
21
+
22
+ private
23
+
24
+ def rails_environment
25
+ "production"
26
+ end
27
+
28
+ def docker_host
29
+ Service::DockerHost.create "#{app_name}-#{rails_environment}", config(Dir.pwd)
30
+ end
31
+
32
+ def config(source_path)
33
+ require "ostruct"
34
+ config_path = File.join source_path, "config", "conjure.yml"
35
+ data = YAML.load_file config_path
36
+ data["config_path"] = File.dirname config_path
37
+ OpenStruct.new data
38
+ end
39
+
40
+ def app_name
41
+ name_from_github_url github_url
42
+ end
43
+
44
+ def github_url
45
+ git_origin_url Dir.pwd
46
+ end
47
+
48
+ def git_origin_url(source_path)
49
+ remote_info = `cd #{source_path}; git remote -v |grep origin`
50
+ remote_info.match(/(git@github.com[^ ]+)/)[1]
51
+ end
52
+
53
+ def name_from_github_url(github_url)
54
+ github_url.match(/\/([^.]+)\.git$/)[1]
6
55
  end
7
- default_task :deploy
8
56
  end
9
57
  end
10
-
@@ -2,30 +2,16 @@ module Conjure
2
2
  module Service
3
3
  autoload :RailsApplication, "conjure/service/rails_application"
4
4
  autoload :RailsServer, "conjure/service/rails_server"
5
- autoload :RvmShell, "conjure/service/rvm_shell"
6
5
  autoload :MachineInstance, "conjure/service/machine_instance"
7
- autoload :SourceTree, "conjure/service/source_tree"
6
+ autoload :DockerHost, "conjure/service/docker_host"
7
+ autoload :CloudServer, "conjure/service/cloud_server"
8
+ autoload :PostgresServer, "conjure/service/postgres_server"
9
+ autoload :PostgresClient, "conjure/service/postgres_client"
8
10
  end
9
11
 
10
12
  class Basic
11
- def dependencies
12
- []
13
- end
14
-
15
- def started?
16
- false
17
- end
18
-
19
- def start
20
- end
21
-
22
- def save
23
- dependencies.each &:start
24
- start unless started?
25
- end
26
-
27
13
  def self.create(*args)
28
- new(*args).save
14
+ new(*args)
29
15
  end
30
16
  end
31
17
  end
@@ -0,0 +1,108 @@
1
+ module Conjure
2
+ module Service
3
+ class CloudServer < Basic
4
+ require "fog"
5
+
6
+ def initialize(name, config = {})
7
+ @name = name
8
+ @config = config
9
+ end
10
+
11
+ def run(command, options = {})
12
+ set_fog_credentials
13
+ upload_files options[:files].to_a
14
+ result = server.ssh(command).first
15
+ remove_files options[:files].to_a
16
+ result
17
+ end
18
+
19
+ def upload_files(files)
20
+ dir_names = files.map{|local_path, remote_path| File.dirname remote_path}.uniq
21
+ server.ssh "mkdir -p #{dir_names.join ' '}" if dir_names.any?
22
+ files.each{|local_path, remote_path| server.scp local_path, remote_path}
23
+ end
24
+
25
+ def remove_files(files)
26
+ files.each{|local_path, remote_path| server.ssh "rm -f #{remote_path}"}
27
+ end
28
+
29
+ def server
30
+ @server ||= existing_server
31
+ @server ||= new_server
32
+ @server.wait_for { ready? }
33
+ @server
34
+ end
35
+
36
+ def ip_address
37
+ @server.public_ip_address
38
+ end
39
+
40
+ def existing_server
41
+ server = connection.servers.find{|s| s.name == @name }
42
+ puts " [cloud] Using existing server #{@name}" if server
43
+ server
44
+ end
45
+
46
+ def new_server
47
+ puts " [cloud] Launching new server #{@name}"
48
+ connection.servers.bootstrap bootstrap_options.merge(fog_credentials)
49
+ end
50
+
51
+ def connection
52
+ @connection ||= Fog::Compute.new compute_options
53
+ end
54
+
55
+ def bootstrap_options
56
+ {
57
+ name: @name,
58
+ flavor_id: flavor_id,
59
+ region_id: region_id,
60
+ image_id: image_id,
61
+ }
62
+ end
63
+
64
+ def compute_options
65
+ {
66
+ provider: :digitalocean,
67
+ digitalocean_api_key: config.digitalocean_api_key,
68
+ digitalocean_client_id: config.digitalocean_client_id,
69
+ }
70
+ end
71
+
72
+ def flavor_id
73
+ @flavor_id ||= connection.flavors.find{|f| f.name == "512MB"}.id
74
+ end
75
+
76
+ def region_id
77
+ @region_id ||= connection.regions.find{|r| r.name == config.digitalocean_region}.id
78
+ end
79
+
80
+ def image_id
81
+ @image_id ||= connection.images.find{|r| r.name == "Ubuntu 13.04 x64"}.id
82
+ end
83
+
84
+ def config
85
+ @config
86
+ end
87
+
88
+ def set_fog_credentials
89
+ Fog.credentials.merge! fog_credentials
90
+ end
91
+
92
+ def private_key_file
93
+ Pathname.new(config.config_path).join config.private_key_file
94
+ end
95
+
96
+ def public_key_file
97
+ Pathname.new(config.config_path).join config.public_key_file
98
+ end
99
+
100
+ def fog_credentials
101
+ {
102
+ private_key_path: private_key_file,
103
+ public_key_path: public_key_file,
104
+ }
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,171 @@
1
+ module Conjure
2
+ module Service
3
+ class DockerHost < Basic
4
+ VERBOSE = false
5
+
6
+ def initialize(server_name, config = {})
7
+ @server_name = server_name
8
+ @config = config
9
+ end
10
+
11
+ def server
12
+ @server ||= Service::CloudServer.create @server_name, config
13
+ end
14
+
15
+ def config
16
+ @config
17
+ end
18
+
19
+ def ip_address
20
+ @server.ip_address
21
+ end
22
+
23
+ def new_docker_path
24
+ puts "[docker] Installing docker"
25
+ server.run "curl https://get.docker.io/gpg | apt-key add -"
26
+ server.run "echo 'deb https://get.docker.io/ubuntu docker main' >/etc/apt/sources.list.d/docker.list"
27
+ server.run "apt-get update"
28
+ server.run "DEBIAN_FRONTEND=noninteractive apt-get install -y linux-image-extra-`uname -r` lxc-docker"
29
+ existing_docker_path
30
+ end
31
+
32
+ def existing_docker_path
33
+ path = server.run("which docker").stdout.to_s.strip
34
+ path = nil if path == ""
35
+ puts "[docker] Using installed #{path}" if path
36
+ path
37
+ end
38
+
39
+ def docker_path
40
+ @docker_path ||= existing_docker_path
41
+ @docker_path ||= new_docker_path
42
+ end
43
+
44
+ def command(command, options = {})
45
+ full_command = "#{docker_path} #{command}"
46
+ full_command = "nohup #{full_command}" if options[:nohup]
47
+ full_command = "echo '#{shell_escape options[:stdin]}' | #{full_command}" if options[:stdin]
48
+ puts " [scp] #{options[:files].inspect}" if VERBOSE and options[:files]
49
+ puts " [ssh] #{full_command}" if VERBOSE
50
+ result = server.run full_command, files: options[:files]
51
+ raise "Docker error: #{result.stdout} #{result.stderr}" unless result.status == 0
52
+ result.stdout
53
+ end
54
+
55
+ def shell_escape(text)
56
+ text.gsub "'", "'\"'\"'"
57
+ end
58
+
59
+ def containers
60
+ ContainerSet.new self
61
+ end
62
+ end
63
+
64
+ class ContainerSet
65
+ def initialize(host)
66
+ @host = host
67
+ end
68
+
69
+ def create(options)
70
+ Container.new @host, options
71
+ end
72
+ end
73
+
74
+ class Container
75
+ def initialize(host, options)
76
+ @host = host
77
+ @label = options[:label]
78
+ @base_image = options[:base_image]
79
+ @ports = options[:ports].to_a
80
+ @volumes = options[:volumes].to_a
81
+ @setup_commands = options[:setup_commands].to_a
82
+ @daemon_command = options[:daemon_command]
83
+ @environment = options[:environment]
84
+ @files = options[:files]
85
+ end
86
+
87
+ def image_fingerprint
88
+ {base_image: @base_image, setup_commands: @setup_commands}
89
+ end
90
+
91
+ def image_name
92
+ hash = Digest::SHA1.hexdigest(image_fingerprint.to_yaml).first(12)
93
+ "#{@label}_#{hash}"
94
+ end
95
+
96
+ def run
97
+ unless id
98
+ build
99
+ puts "[docker] Starting #{@label} image"
100
+ container_id = @host.command("run -d #{@label}").strip
101
+ if(!id)
102
+ output = @host.command "logs #{container_id}"
103
+ raise "Docker: #{@label} daemon exited with: #{output}"
104
+ end
105
+ end
106
+ puts "[docker] #{@label} is running at #{ip_address}"
107
+ end
108
+
109
+ def raise_build_errors(build_output)
110
+ match = build_output.match(/Error build: The command \[([^\]]*)\] returned a non-zero code:/)
111
+ if match
112
+ failed_command = match[1]
113
+ last_section = build_output.split("--->").last
114
+ last_section.gsub!(/Running in [0-9a-f]+/, "")
115
+ last_section.gsub!(/Error build: The command.*/m, "")
116
+ raise "Docker: build step '#{failed_command}' failed: #{last_section.strip}"
117
+ end
118
+ end
119
+
120
+ def raise_run_errors(run_output)
121
+ end
122
+
123
+ def dockerfile
124
+ lines = ["FROM #{@base_image}"]
125
+ lines += @environment.map{|k, v| "ENV #{k} #{v}"} if @environment
126
+ lines += @setup_commands.map{|c| "RUN #{c}"}
127
+ lines << "EXPOSE #{@ports.map{|p| "#{p}:#{p}"}.join ' '}" if @ports.to_a.any?
128
+ lines << "VOLUME #{@volumes.inspect}" if @volumes.to_a.any?
129
+ lines << "ENTRYPOINT #{@daemon_command}" if @daemon_command
130
+ lines.join "\n"
131
+ end
132
+
133
+ def build
134
+ puts "[docker] Building #{@label} image"
135
+ raise_build_errors(@host.command "build -t #{@label} -", stdin: dockerfile)
136
+ end
137
+
138
+ def command(command, options = {})
139
+ build
140
+ puts "[docker] Executing #{@label} image"
141
+ file_options = options[:files] ? "-v /files:/files" : ""
142
+ @host.command "run #{file_options} #{@label} #{command}", files: files_hash(options[:files])
143
+ end
144
+
145
+ def files_hash(files_array)
146
+ files_array.to_a.inject({}) do |hash, local_file|
147
+ hash.merge local_file => "/files/#{File.basename local_file}"
148
+ end
149
+ end
150
+
151
+ def shell_command(command)
152
+ "bash -c '#{@host.shell_escape command}'"
153
+ end
154
+
155
+ def id
156
+ @id ||= @host.command("ps | grep #{@label}: ; true").strip.split("\n").first.to_s[0..11]
157
+ @id = nil if @id == ""
158
+ @id
159
+ end
160
+
161
+ def ip_address
162
+ status["NetworkSettings"]["IPAddress"]
163
+ end
164
+
165
+ def status
166
+ require "json"
167
+ JSON.parse(@host.command "inspect #{id}").first
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,32 @@
1
+ module Conjure
2
+ module Service
3
+ class PostgresClient < Basic
4
+ def initialize(host, db_name)
5
+ server = PostgresServer.create host
6
+ server.run
7
+ @server_ip = server.ip_address
8
+ @db_name = db_name
9
+ @container = host.containers.create(
10
+ label: "pgclient",
11
+ base_image: "ubuntu",
12
+ setup_commands: [
13
+ "apt-get install -y python-software-properties software-properties-common",
14
+ "add-apt-repository -y ppa:pitti/postgresql",
15
+ "apt-get update",
16
+ "apt-get install -y postgresql-9.2 postgresql-client-9.2 postgresql-contrib-9.2",
17
+ ],
18
+ )
19
+ end
20
+
21
+ def export(file)
22
+ File.open file, "w" do |f|
23
+ f.write @container.command("/usr/lib/postgresql/9.2/bin/pg_dump -U root -h #{@server_ip} #{@db_name}")
24
+ end
25
+ end
26
+
27
+ def import(file)
28
+ @container.command "/usr/lib/postgresql/9.2/bin/psql -U root -h #{@server_ip} -d #{@db_name} -f /files/#{File.basename file}", files: [file]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module Conjure
2
+ module Service
3
+ class PostgresServer < Basic
4
+ def initialize(host)
5
+ @container = host.containers.create(
6
+ label: "postgres",
7
+ base_image: "ubuntu",
8
+ setup_commands: [
9
+ "apt-get install -y python-software-properties software-properties-common",
10
+ "add-apt-repository -y ppa:pitti/postgresql",
11
+ "apt-get update",
12
+ "apt-get install -y postgresql-9.2 postgresql-client-9.2 postgresql-contrib-9.2",
13
+ "service postgresql start; su postgres -c 'createuser -d -r -s root; createdb -O root root'; service postgresql stop",
14
+ "echo 'host all all 0.0.0.0/0 trust' >>/etc/postgresql/9.2/main/pg_hba.conf",
15
+ "echo \"listen_addresses='*'\" >>/etc/postgresql/9.2/main/postgresql.conf",
16
+ ],
17
+ daemon_command: "su postgres -c '/usr/lib/postgresql/9.2/bin/postgres -c config_file=/etc/postgresql/9.2/main/postgresql.conf'",
18
+ volumes: ["/var/lib/postgresql/9.2/main"],
19
+ )
20
+ end
21
+
22
+ def run
23
+ @container.run
24
+ end
25
+
26
+ def ip_address
27
+ @container.ip_address
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,15 +1,15 @@
1
1
  module Conjure
2
2
  module Service
3
3
  class RailsApplication < Basic
4
- def initialize(source_path)
5
- source_path = source_path
6
- @instance = Service::MachineInstance.new
7
- @source_tree = Service::SourceTree.new source_path, @instance
8
- @server = Service::RailsServer.new @source_tree, @instance
9
- end
10
-
11
- def dependencies
12
- [@instance, @source_tree, @server]
4
+ def initialize(github_url, name = "myapp", environment = "production", config = {})
5
+ @name = name
6
+ @environment = environment
7
+ docker = Service::DockerHost.create "#{name}-#{environment}", config
8
+ postgres = Service::PostgresServer.create docker
9
+ postgres.run
10
+ rails = Service::RailsServer.create docker, github_url, name, postgres.ip_address, environment
11
+ rails.run
12
+ puts "[deploy] Application deployed to #{docker.ip_address}"
13
13
  end
14
14
  end
15
15
  end
@@ -1,35 +1,72 @@
1
1
  module Conjure
2
2
  module Service
3
3
  class RailsServer < Basic
4
- def initialize(source_tree, instance)
5
- @working_dir = "codebase"
6
- @instance = instance
7
- @source_tree = source_tree
8
- @rvm_shell = Service::RvmShell.new instance, "1.9.3", "codebase"
4
+ def file_contents(config, file_path)
5
+ file_path = File.join config.config_path, file_path
6
+ `cat #{file_path}`
9
7
  end
10
8
 
11
- def dependencies
12
- [@instance, @source_tree, @rvm_shell]
9
+ def initialize(host, github_url, app_name, database_ip_address, rails_environment = "production")
10
+ config = host.config
11
+ ruby_version = file_contents(config, "../.ruby-version").strip
12
+ github_private_key = file_contents(config, config.private_key_file).gsub("\n", "\\n")
13
+ github_public_key = file_contents(config, config.public_key_file).gsub("\n", "\\n")
14
+ @container = host.containers.create(
15
+ label: "rails",
16
+ base_image: "ubuntu",
17
+ setup_commands: [
18
+ "apt-get install -y curl git",
19
+ "curl -L https://get.rvm.io | bash -s stable",
20
+ "rvm install #{ruby_version}",
21
+ "bash -c 'source /usr/local/rvm/scripts/rvm; rvm use #{ruby_version}@global --default'",
22
+ "mkdir -p /root/.ssh; echo '#{github_private_key}' > /root/.ssh/id_rsa",
23
+ "mkdir -p /root/.ssh; echo '#{github_public_key}' > /root/.ssh/id_rsa.pub",
24
+ "chmod -R go-rwx /root/.ssh",
25
+ "echo 'Host github.com\\n\\tStrictHostKeyChecking no\\n' >> /root/.ssh/config",
26
+ "git clone #{github_url}",
27
+ "apt-get install -y #{apt_packages_required_for_gems.join ' '}",
28
+ "cd #{app_name}; bundle --deployment",
29
+
30
+ "echo 'deb http://us.archive.ubuntu.com/ubuntu/ precise universe' >>/etc/apt/sources.list",
31
+ "apt-get install -y python-software-properties software-properties-common",
32
+ "add-apt-repository -y ppa:chris-lea/node.js-legacy",
33
+ "apt-get update",
34
+ "apt-get install -y nodejs",
35
+
36
+ "echo '#{database_yml database_ip_address, app_name, rails_environment}' >/#{app_name}/config/database.yml",
37
+ "cd #{app_name}; bundle exec rake db:setup",
38
+ ],
39
+ environment: {
40
+ PATH:"/usr/local/rvm/gems/ruby-1.9.3-p448@global/bin:/usr/local/rvm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
41
+ RAILS_ENV: rails_environment,
42
+ GITHUB_TOKEN: ENV["GITHUB_TOKEN"],
43
+ FRECKLE_SUBDOMAIN: "neomind",
44
+ },
45
+ daemon_command: "cd #{app_name}; bundle exec rails server -p 80",
46
+ ports: [80],
47
+ volumes: ["/#{app_name}/log"],
48
+ )
13
49
  end
14
50
 
15
- def started?
16
- shell("bundle check").include? "dependencies are satisfied"
51
+ def run
52
+ @container.run
17
53
  end
18
54
 
19
- def start
20
- puts "Installing gems..."
21
- execute "cd codebase; bundle"
22
- puts "Starting rails server..."
23
- if execute("rails server -d").include? "application starting"
24
- puts "The app is running at http://localhost:4000/"
25
- else
26
- puts "The rails server failed to start."
27
- end
55
+ def database_yml(database_ip_address, app_name, rails_environment)
56
+ {
57
+ rails_environment => {
58
+ "adapter" => "postgresql",
59
+ "database" => "#{app_name}_#{rails_environment}",
60
+ "encoding" => "utf8",
61
+ "host" => database_ip_address,
62
+ "username" => "root",
63
+ "template" => "template0",
64
+ }
65
+ }.to_yaml.gsub("\n", "\\n")
28
66
  end
29
67
 
30
- def execute(command)
31
- command = "cd #{@working_dir}; #{command}" if @working_dir
32
- @rvm_shell.execute command
68
+ def apt_packages_required_for_gems
69
+ ["libpq-dev"]
33
70
  end
34
71
  end
35
72
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conjure
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-08 00:00:00.000000000 Z
12
+ date: 2013-10-11 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fog
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.15.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.15.0
14
30
  - !ruby/object:Gem::Dependency
15
31
  name: thor
16
32
  requirement: !ruby/object:Gem::Requirement
@@ -52,11 +68,13 @@ extensions: []
52
68
  extra_rdoc_files: []
53
69
  files:
54
70
  - lib/conjure.rb
71
+ - lib/conjure/service/cloud_server.rb
55
72
  - lib/conjure/service/rails_server.rb
73
+ - lib/conjure/service/postgres_server.rb
56
74
  - lib/conjure/service/rails_application.rb
57
75
  - lib/conjure/service/machine_instance.rb
58
- - lib/conjure/service/source_tree.rb
59
- - lib/conjure/service/rvm_shell.rb
76
+ - lib/conjure/service/postgres_client.rb
77
+ - lib/conjure/service/docker_host.rb
60
78
  - lib/conjure/service.rb
61
79
  - lib/conjure/command.rb
62
80
  - README.md
@@ -1,30 +0,0 @@
1
- module Conjure
2
- module Service
3
- class RvmShell < Basic
4
- def initialize(machine_instance, ruby_version, gemset)
5
- @instance = machine_instance
6
- @ruby_version = ruby_version
7
- @gemset = gemset
8
- end
9
-
10
- def dependences
11
- [@instance]
12
- end
13
-
14
- def start
15
- shell "sudo apt-get -y install curl libyaml-dev build-essential libsqlite3-dev nodejs"
16
- shell "curl -L https://get.rvm.io | bash -s -- --ignore-dotfiles"
17
- shell "echo \"source $HOME/.rvm/scripts/rvm\" >> ~/.bash_profile"
18
- shell "source $HOME/.rvm/scripts/rvm"
19
- shell "rvm install #{@ruby_version}"
20
- shell "rvm use #{@ruby_version}@#{@gemset} --create --default"
21
- end
22
-
23
- def execute(command)
24
- command.gsub! "'", "'\\\\''"
25
- command = "bash --login -c '#{command}' 2>&1"
26
- @instance.remote_command_output command
27
- end
28
- end
29
- end
30
- end
@@ -1,25 +0,0 @@
1
- module Conjure
2
- module Service
3
- class SourceTree < Basic
4
- def initialize(source_path, machine_instance)
5
- @source_path = source_path
6
- @instance = machine_instance
7
- end
8
-
9
- def copy_to(instance, dest_path)
10
- options = "-a -e \"ssh #{instance.ssh_options}\""
11
- source = "#{@source_path}/"
12
- dest = "#{instance.ssh_address}:#{dest_path}"
13
- system "rsync #{options} #{source} #{dest}"
14
- end
15
-
16
- def start(dest_path="codebase")
17
- puts "Transferring source code..."
18
- copy_to @instance, dest_path
19
- size = "#{@instance.remote_command_output "du -hs #{dest_path}"}"
20
- size = size.split(/\s/).first
21
- puts "Installed codebase size is #{size}."
22
- end
23
- end
24
- end
25
- end