conjure 0.2.10 → 0.3.0

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.
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