conjure 0.2.10 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/History.md +8 -0
  2. data/README.md +35 -76
  3. data/lib/conjure.rb +1 -12
  4. data/lib/conjure/delayed_job.rb +39 -0
  5. data/lib/conjure/digital_ocean/droplet.rb +5 -2
  6. data/lib/conjure/docker/host.rb +75 -0
  7. data/lib/conjure/docker/template.rb +71 -0
  8. data/lib/conjure/instance.rb +31 -76
  9. data/lib/conjure/passenger.rb +123 -0
  10. data/lib/conjure/postgres.rb +67 -0
  11. data/lib/conjure/rails_application.rb +32 -0
  12. data/lib/conjure/server.rb +41 -0
  13. data/lib/conjure/swap.rb +28 -0
  14. data/lib/conjure/{provision/templates → templates}/application-no-ssl.conf.erb +2 -1
  15. data/lib/conjure/{provision/templates → templates}/application-ssl.conf.erb +2 -1
  16. data/lib/conjure/version.rb +1 -1
  17. metadata +12 -41
  18. data/lib/conjure/application.rb +0 -35
  19. data/lib/conjure/command.rb +0 -74
  20. data/lib/conjure/command_target.rb +0 -25
  21. data/lib/conjure/config.rb +0 -44
  22. data/lib/conjure/data_set.rb +0 -7
  23. data/lib/conjure/identity.rb +0 -25
  24. data/lib/conjure/log.rb +0 -26
  25. data/lib/conjure/provider.rb +0 -26
  26. data/lib/conjure/provision.rb +0 -1
  27. data/lib/conjure/provision/docker/host.rb +0 -32
  28. data/lib/conjure/provision/docker/image.rb +0 -55
  29. data/lib/conjure/provision/docker/template.rb +0 -55
  30. data/lib/conjure/provision/instance.rb +0 -52
  31. data/lib/conjure/provision/local_docker.rb +0 -16
  32. data/lib/conjure/provision/passenger.rb +0 -111
  33. data/lib/conjure/provision/postgres.rb +0 -70
  34. data/lib/conjure/provision/server.rb +0 -78
  35. data/lib/conjure/service/cloud_server.rb +0 -112
  36. data/lib/conjure/service/database.rb +0 -25
  37. data/lib/conjure/service/database/mysql.rb +0 -69
  38. data/lib/conjure/service/database/postgres.rb +0 -77
  39. data/lib/conjure/service/digital_ocean_account.rb +0 -31
  40. data/lib/conjure/service/docker_host.rb +0 -259
  41. data/lib/conjure/service/docker_shell.rb +0 -46
  42. data/lib/conjure/service/forwarded_shell.rb +0 -25
  43. data/lib/conjure/service/rails_codebase.rb +0 -67
  44. data/lib/conjure/service/rails_console.rb +0 -10
  45. data/lib/conjure/service/rails_log_view.rb +0 -14
  46. data/lib/conjure/service/rails_server.rb +0 -91
  47. data/lib/conjure/service/rake_task.rb +0 -11
  48. data/lib/conjure/service/remote_file_set.rb +0 -24
  49. data/lib/conjure/service/remote_shell.rb +0 -73
  50. data/lib/conjure/service/repository_link.rb +0 -52
  51. data/lib/conjure/service/volume.rb +0 -28
  52. data/lib/conjure/target.rb +0 -19
  53. data/lib/conjure/view/application_view.rb +0 -42
  54. data/lib/conjure/view/table_view.rb +0 -38
@@ -1,70 +0,0 @@
1
- require "conjure/provision/docker/template"
2
- require "securerandom"
3
-
4
- module Conjure
5
- module Provision
6
- class Postgres
7
- def initialize(platform)
8
- @platform = platform
9
- @name = "conjure_db_#{SecureRandom.hex 8}"
10
- @password = new_password
11
- end
12
-
13
- def start
14
- @ip_address = server_template.build(@platform).start_daemon("/sbin/my_init", start_options)
15
- end
16
-
17
- def rails_config
18
- {
19
- "adapter" => "postgresql",
20
- "database" => @name,
21
- "host" => container_name,
22
- "username" => "db",
23
- "password" => @password,
24
- "template" => "template0",
25
- }
26
- end
27
-
28
- def container_link
29
- {container_name => container_name}
30
- end
31
-
32
- private
33
-
34
- def start_options
35
- {
36
- :name => container_name,
37
- :volume_containers => [data_container_name],
38
- }
39
- end
40
-
41
- def container_name
42
- "postgres"
43
- end
44
-
45
- def data_container_name
46
- data_template.build(@platform).start_volume(:name => "postgres_data")
47
- "postgres_data"
48
- end
49
-
50
- def data_template
51
- file = Docker::Template.new("conjure/postgres93:1.0.0")
52
- file.volume "/var/lib/postgresql/9.3/main"
53
- file
54
- end
55
-
56
- def server_template
57
- file = Docker::Template.new("conjure/postgres93:1.0.0")
58
- file.run "echo \"ALTER USER db PASSWORD '#{@password}'\" >/tmp/setpass"
59
- file.run "/sbin/my_init -- /sbin/setuser postgres sh -c \"sleep 1; psql -f /tmp/setpass\""
60
- file.run "rm /tmp/setpass"
61
- file.run "/sbin/my_init -- /sbin/setuser db sh -c \"sleep 1; /usr/bin/createdb #{@name}\""
62
- file
63
- end
64
-
65
- def new_password
66
- SecureRandom.urlsafe_base64 20
67
- end
68
- end
69
- end
70
- end
@@ -1,78 +0,0 @@
1
- require "conjure/digital_ocean/droplet"
2
- require "securerandom"
3
-
4
- module Conjure
5
- module Provision
6
- class Server
7
- def initialize(server)
8
- @server = server
9
- puts "Configuring droplet..."
10
- install_swap
11
- end
12
-
13
- def ip_address
14
- @server.ip_address
15
- end
16
-
17
- def run(command)
18
- `ssh #{ssh_options} root@#{ip_address} '#{shell_escape_single_quotes command}'`
19
- end
20
-
21
- def send_file(local_name, remote_name)
22
- `scp #{ssh_options} #{local_name} root@#{ip_address}:#{remote_name}`
23
- end
24
-
25
- def ssh_options
26
- "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
27
- end
28
-
29
- def shell_escape_single_quotes(command)
30
- command.gsub("'", "'\"'\"'")
31
- end
32
-
33
- def install_swap
34
- run "dd if=/dev/zero of=/root/swapfile bs=4096 count=524288"
35
- run "mkswap /root/swapfile; swapon /root/swapfile"
36
- end
37
-
38
- def self.create(name, options = {})
39
- puts "Creating DigitalOcean droplet..."
40
- new DigitalOcean::Droplet.new(droplet_options(uniquify(name), options))
41
- end
42
-
43
- def self.droplet_options(name, options = {})
44
- raise "Error: DIGITALOCEAN_API_TOKEN must be set." unless ENV["DIGITALOCEAN_API_TOKEN"]
45
- {
46
- image: "docker",
47
- key_data: key_data,
48
- name: name,
49
- region: "nyc3",
50
- size: (options[:instance_size] || "512mb"),
51
- token: ENV["DIGITALOCEAN_API_TOKEN"],
52
- }
53
- end
54
-
55
- def self.key_data
56
- ssh_dir = File.expand_path "~/.ssh"
57
- raise "Error: ~/.ssh/id_rsa.pub must exist." unless File.exist?(ssh_dir) && File.exist?("#{ssh_dir}/id_rsa.pub")
58
- File.read "#{ssh_dir}/id_rsa.pub"
59
- end
60
-
61
- def self.uniquify(server_name)
62
- "#{server_name}-#{SecureRandom.hex 4}"
63
- end
64
-
65
- def with_directory(local_path, &block)
66
- local_archive = remote_archive = "/tmp/archive.tar.gz"
67
- remote_path = "/tmp/unpacked_archive"
68
- `cd #{local_path}; tar czf #{local_archive} *`
69
- send_file local_archive, remote_archive
70
- run "mkdir #{remote_path}; cd #{remote_path}; tar mxzf #{remote_archive}"
71
- yield remote_path
72
- ensure
73
- `rm #{local_archive}`
74
- run "rm -Rf #{remote_path} #{remote_archive}"
75
- end
76
- end
77
- end
78
- end
@@ -1,112 +0,0 @@
1
- module Conjure
2
- module Service
3
- class CloudServer
4
- require "pathname"
5
- attr_reader :name
6
-
7
- def initialize(name)
8
- @name = name
9
- end
10
-
11
- def run(command, options = {}, &block)
12
- set_fog_credentials
13
- file_set = RemoteFileSet.new(:shell => remote_shell, :files => options[:files])
14
- file_set.upload
15
- result = remote_shell.run(command, :stream_stdin => options[:stream_stdin], &block)
16
- file_set.remove
17
- result
18
- end
19
-
20
- def server
21
- @server ||= existing_server
22
- @server ||= new_server
23
- @server.wait_for { ready? }
24
- @server
25
- end
26
-
27
- def ip_address
28
- server.public_ip_address
29
- end
30
-
31
- def existing_server
32
- @existing_server ||= connection.servers.find{|s| s.name == @name } if connection
33
- end
34
-
35
- def self.connection
36
- new("").connection
37
- end
38
-
39
- def self.each_with_name_prefix(prefix, &block)
40
- return unless connection
41
- connection.servers.all.select{|s| s.name.match(/^#{prefix}/)}.each do |server|
42
- block.call new(server.name)
43
- end
44
- end
45
-
46
- def self.ensure_unique_name(name)
47
- return name unless connection
48
- existing_names = connection.servers.all.map{ |s| s.name }
49
- name = increment_numeric_suffix(name) while existing_names.include? name
50
- name
51
- end
52
-
53
- def self.increment_numeric_suffix(name)
54
- parts = name.split("-")
55
- parts[2] = parts[2] ? ((parts[2].to_i)+1).to_s : "2"
56
- parts.join("-")
57
- end
58
-
59
- def new_server
60
- Log.info " [cloud] Launching new server #{@name}"
61
- bootstrap_options = account.bootstrap_options.merge(:name => @name)
62
- options = prepare_bootstrap_options(bootstrap_options).merge(fog_credentials)
63
- connection.servers.bootstrap options
64
- end
65
-
66
- def account
67
- @account ||= Provider.all(:cloud_account).first
68
- end
69
-
70
- def connection
71
- @connection ||= Fog::Compute.new account.compute_options if account
72
- end
73
-
74
- def add_resource_id(options, type)
75
- id = "#{type}_id".to_sym
76
- name = "#{type}_name".to_sym
77
- collection = "#{type}s".to_sym
78
- options[id] = resource_id(collection, options[name]) if options[name]
79
- end
80
-
81
- def prepare_bootstrap_options(options)
82
- add_resource_id(options, :flavor)
83
- add_resource_id(options, :region)
84
- add_resource_id(options, :image)
85
- options
86
- end
87
-
88
- def resource_id(collection, name)
89
- connection.send(collection).find{|i| i.name == name}.id
90
- end
91
-
92
- def set_fog_credentials
93
- Fog.credential = Conjure.identity.unique_identifier
94
- Fog.credentials.merge! fog_credentials
95
- end
96
-
97
- def fog_credentials
98
- {
99
- private_key_path: Conjure.identity.private_key_path,
100
- public_key_path: Conjure.identity.public_key_path,
101
- }
102
- end
103
-
104
- def remote_shell
105
- @remote_shell ||= RemoteShell.new(
106
- :ip_address => server.public_ip_address,
107
- :username => "root",
108
- )
109
- end
110
- end
111
- end
112
- end
@@ -1,25 +0,0 @@
1
- module Conjure
2
- module Service
3
- class Database
4
- def self.new(options)
5
- services_by_gem.each do |gem_name, service_class|
6
- if options[:codebase].gem_names.include? gem_name
7
- return service_class.new(
8
- :target => options[:target],
9
- :database_name => "rails_app_db",
10
- :adapter_name => adapters_by_gem[gem_name],
11
- )
12
- end
13
- end
14
- end
15
-
16
- def self.services_by_gem
17
- {"pg" => Postgres, "mysql2" => Mysql, "mysql" => Mysql}
18
- end
19
-
20
- def self.adapters_by_gem
21
- {"pg" => "postgresql", "mysql2" => "mysql2", "mysql" => "mysql"}
22
- end
23
- end
24
- end
25
- end
@@ -1,69 +0,0 @@
1
- module Conjure
2
- module Service
3
- class Database
4
- class Mysql
5
- def initialize(options)
6
- @target = options[:target]
7
- @db_name = options[:database_name]
8
- @adapter_name = options[:adapter_name]
9
- end
10
-
11
- def base_image
12
- @base_image ||= @target.shell.prepare(
13
- label: "mysql",
14
- setup_commands: [
15
- "apt-get install -y mysql-server mysql-client"
16
- ],
17
- )
18
- end
19
-
20
- def server_image
21
- @server_image ||= base_image.prepare(
22
- label: "mysqlserver",
23
- setup_commands: [
24
- "/usr/sbin/mysqld & sleep 5; echo \"GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '' WITH GRANT OPTION\" | /usr/bin/mysql",
25
- ],
26
- daemon_command: "/usr/sbin/mysqld --bind-address=0.0.0.0",
27
- volumes: ["/var/lib/mysql"],
28
- )
29
- end
30
-
31
- def run
32
- container
33
- end
34
-
35
- def container
36
- @container ||= server_image.run
37
- end
38
-
39
- def name
40
- @db_name
41
- end
42
-
43
- def ip_address
44
- container.ip_address
45
- end
46
-
47
- def export(file)
48
- File.open file, "w" do |f|
49
- f.write base_image.command("/usr/bin/mysqldump #{client_options}")
50
- end
51
- Log.info "[export] #{File.size file} bytes exported to #{file}"
52
- end
53
-
54
- def import(file)
55
- base_image.command "echo 'source /files/#{File.basename file}' | /usr/bin/mysql #{client_options}", files: [file]
56
- Log.info "[import] #{File.size file} bytes imported from #{file}"
57
- end
58
-
59
- def client_options
60
- "-u root -h #{ip_address} #{@db_name}"
61
- end
62
-
63
- def adapter_name
64
- @adapter_name || "mysql2"
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,77 +0,0 @@
1
- module Conjure
2
- module Service
3
- class Database
4
- class Postgres
5
- def initialize(options)
6
- @target = options[:target]
7
- @db_name = options[:database_name]
8
- end
9
-
10
- def base_image
11
- @base_image ||= @target.shell.prepare(
12
- label: "postgres",
13
- setup_commands: [
14
- "apt-get install -y python-software-properties software-properties-common",
15
- "add-apt-repository -y ppa:pitti/postgresql",
16
- "apt-get update",
17
- "apt-get install -y postgresql-9.2 postgresql-client-9.2 postgresql-contrib-9.2",
18
- ],
19
- )
20
- end
21
-
22
- def server_image
23
- @server_image ||= base_image.prepare(
24
- label: "pgserver",
25
- setup_commands: [
26
- "service postgresql start; su postgres -c 'createuser -d -r -s root; createdb -O root root'; service postgresql stop",
27
- "echo 'host all all 0.0.0.0/0 trust' >>/etc/postgresql/9.2/main/pg_hba.conf",
28
- "echo \"listen_addresses='*'\" >>/etc/postgresql/9.2/main/postgresql.conf",
29
- ],
30
- daemon_command: "su postgres -c '#{bin_path}/postgres -c config_file=/etc/postgresql/9.2/main/postgresql.conf'",
31
- volumes: ["/var/lib/postgresql/9.2/main"],
32
- )
33
- end
34
-
35
- def run
36
- container
37
- end
38
-
39
- def container
40
- @container ||= server_image.run
41
- end
42
-
43
- def name
44
- @db_name
45
- end
46
-
47
- def ip_address
48
- container.ip_address
49
- end
50
-
51
- def export(file)
52
- File.open file, "w" do |f|
53
- f.write base_image.command("#{bin_path}/pg_dump #{client_options} #{@db_name}")
54
- end
55
- Log.info "[export] #{File.size file} bytes exported to #{file}"
56
- end
57
-
58
- def import(file)
59
- base_image.command "#{bin_path}/psql #{client_options} -d #{@db_name} -f /files/#{File.basename file}", files: [file]
60
- Log.info "[import] #{File.size file} bytes imported from #{file}"
61
- end
62
-
63
- def client_options
64
- "-U root -h #{ip_address}"
65
- end
66
-
67
- def bin_path
68
- "/usr/lib/postgresql/9.2/bin"
69
- end
70
-
71
- def adapter_name
72
- "postgresql"
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,31 +0,0 @@
1
- module Conjure
2
- module Service
3
- class DigitalOceanAccount
4
- include Conjure::Provider
5
-
6
- provides :cloud_account do
7
- new if configured?
8
- end
9
-
10
- def self.configured?
11
- Conjure.config.digitalocean_api_key and Conjure.config.digitalocean_client_id
12
- end
13
-
14
- def compute_options
15
- {
16
- :provider => :digitalocean,
17
- :digitalocean_api_key => Conjure.config.digitalocean_api_key,
18
- :digitalocean_client_id => Conjure.config.digitalocean_client_id,
19
- }
20
- end
21
-
22
- def bootstrap_options
23
- {
24
- :flavor_name => "512MB",
25
- :region_name => (Conjure.config.digitalocean_region || "New York 1"),
26
- :image_name => "Ubuntu 13.04 x64",
27
- }
28
- end
29
- end
30
- end
31
- end