conjure 0.2.8 → 0.2.9

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,11 @@
1
+ ### Version 0.2.9
2
+ 2015-06-24
3
+
4
+ * Add ssl_hostname and instance_size provisioning options
5
+ * Use volumes to store data for provisioned containers
6
+ * Make provisioned containers restart on reboot
7
+ * Upgrade provisioned Ruby version to 2.2
8
+
1
9
  ### Version 0.2.8
2
10
  2014-10-31
3
11
 
@@ -18,7 +18,7 @@ module Conjure
18
18
  end
19
19
 
20
20
  def started_container_id(image_name, daemon_command, run_options = nil)
21
- all_options = "-d #{run_options.to_s} #{image_name} #{daemon_command}"
21
+ all_options = "#{run_options.to_s} #{image_name} #{daemon_command}"
22
22
  @platform.run("docker run #{all_options}").strip
23
23
  end
24
24
 
@@ -9,13 +9,46 @@ module Conjure
9
9
  @name = image_name
10
10
  end
11
11
 
12
- def start(command, options = {})
13
- container_id = @docker_host.started_container_id @name, command, options[:run_options]
12
+ def start_volume(options = {})
13
+ @docker_host.started_container_id @name, "/bin/true", daemon_options(options)
14
+ end
15
+
16
+ def start_daemon(command, options = {})
17
+ container_id = @docker_host.started_container_id @name, command, daemon_options(options)
14
18
  sleep 2
15
19
  ip_address = @docker_host.container_ip_address container_id
16
20
  raise "Container failed to start" unless ip_address.present?
17
21
  ip_address
18
22
  end
23
+
24
+ private
25
+
26
+ def volume_options(options)
27
+ "-d " + run_options(options)
28
+ end
29
+
30
+ def daemon_options(options)
31
+ "-d --restart=always " + run_options(options)
32
+ end
33
+
34
+ def run_options(options)
35
+ [
36
+ mapped_options("--link", options[:linked_containers]),
37
+ ("--name #{options[:name]}" if options[:name]),
38
+ mapped_options("-p", options[:ports]),
39
+ listed_options("--volumes-from", options[:volume_containers]),
40
+ ].flatten.compact.join(" ")
41
+ end
42
+
43
+ def listed_options(command, values)
44
+ values ||= []
45
+ values.map { |v| "#{command} #{v}" }
46
+ end
47
+
48
+ def mapped_options(command, values)
49
+ values ||= {}
50
+ values.map { |from, to| "#{command} #{from}:#{to}" }
51
+ end
19
52
  end
20
53
  end
21
54
  end
@@ -25,6 +25,10 @@ module Conjure
25
25
  @commands << "RUN #{command}"
26
26
  end
27
27
 
28
+ def volume(name)
29
+ @commands << "VOLUME #{name}"
30
+ end
31
+
28
32
  def source
29
33
  @commands.join "\n"
30
34
  end
@@ -18,7 +18,7 @@ module Conjure
18
18
  if options[:local]
19
19
  platform = LocalDocker.new
20
20
  else
21
- platform = Server.create "#{@app_name}-#{@rails_env}"
21
+ platform = Server.create "#{@app_name}-#{@rails_env}", @options
22
22
  end
23
23
 
24
24
  database = Postgres.new(platform)
@@ -39,7 +39,8 @@ module Conjure
39
39
  :ip_address => ip_address,
40
40
  :port => port,
41
41
  :user => "app",
42
- :rails_env => @rails_env
42
+ :rails_env => @rails_env,
43
+ :pending_files => webserver.pending_files,
43
44
  }
44
45
  end
45
46
 
@@ -13,22 +13,52 @@ module Conjure
13
13
  @nginx_directives = options[:nginx_directives] || {}
14
14
  @system_packages = options[:system_packages] || []
15
15
  @rubygems_version = options[:rubygems_version]
16
+ @use_ssl = !!options[:ssl_hostname]
17
+ @ssl_hostname = options[:ssl_hostname] || "unknown"
16
18
  end
17
19
 
18
20
  def start
19
- @ip_address = dockerfile.build(@platform).start("/sbin/my_init", start_options)
21
+ @ip_address = server_template.build(@platform).start_daemon("/sbin/my_init", start_options)
22
+ end
23
+
24
+ def pending_files
25
+ return [] unless @use_ssl
26
+ [
27
+ "/etc/ssl/certs/application.crt",
28
+ "/etc/ssl/certs/root_and_intermediates.crt",
29
+ "/etc/ssl/private/application.key",
30
+ "/etc/ssl/dhparam.pem",
31
+ ]
20
32
  end
21
33
 
22
34
  private
23
35
 
24
36
  def start_options
25
- {:run_options => "-p 80:80 -p 443:443 -p 2222:22"}
37
+ {
38
+ :linked_containers => @database.container_link,
39
+ :name => "passenger",
40
+ :ports => {80 => 80, 443 => 443, 2222 => 22},
41
+ :volume_containers => [data_container_name],
42
+ }
43
+ end
44
+
45
+ def data_container_name
46
+ data_template.build(@platform).start_volume(:name => "passenger_data")
47
+ "passenger_data"
26
48
  end
27
49
 
28
- def dockerfile
50
+ def data_template
51
+ file = Docker::Template.new("conjure/passenger-ruby22:1.0.0")
52
+ file.add_file_data database_yml, "/home/app/application/shared/config/database.yml"
53
+ file.add_file_data secrets_yml, "/home/app/application/shared/config/secrets.yml"
54
+ file.volume "/home/app/application"
55
+ file
56
+ end
57
+
58
+ def server_template
29
59
  public_key = File.expand_path("~/.ssh/id_rsa.pub")
30
60
  raise "Error: ~/.ssh/id_rsa.pub must exist." unless File.exist?(public_key)
31
- file = Docker::Template.new("conjure/passenger-ruby21:1.0.2")
61
+ file = Docker::Template.new("conjure/passenger-ruby22:1.0.0")
32
62
  file.run apt_command if apt_command
33
63
  file.run rubygems_command if rubygems_command
34
64
  file.add_file public_key, "/root/.ssh/authorized_keys"
@@ -37,9 +67,8 @@ module Conjure
37
67
  file.run "chown root.root /root/.ssh/authorized_keys"
38
68
  file.add_file_data nginx_conf, "/etc/nginx/sites-available/application-no-ssl.conf"
39
69
  file.add_file_data nginx_ssl_conf, "/etc/nginx/sites-available/application-ssl.conf"
40
- file.run "ln -s /etc/nginx/sites-available/application-no-ssl.conf /etc/nginx/sites-enabled/application.conf"
41
- file.add_file_data database_yml, "/home/app/application/shared/config/database.yml"
42
- file.add_file_data secrets_yml, "/home/app/application/shared/config/secrets.yml"
70
+ which_config = @use_ssl ? "application-ssl" : "application-no-ssl"
71
+ file.run "ln -s /etc/nginx/sites-available/#{which_config}.conf /etc/nginx/sites-enabled/application.conf"
43
72
  file
44
73
  end
45
74
 
@@ -75,7 +104,7 @@ module Conjure
75
104
  def render_template(name)
76
105
  template_path = File.join File.dirname(__FILE__), "templates", "#{name}.erb"
77
106
  template_data = File.read template_path
78
- Erubis::Eruby.new(template_data).result :rails_env => @rails_env
107
+ Erubis::Eruby.new(template_data).result :rails_env => @rails_env, :ssl_hostname => @ssl_hostname
79
108
  end
80
109
  end
81
110
  end
@@ -11,23 +11,49 @@ module Conjure
11
11
  end
12
12
 
13
13
  def start
14
- @ip_address = dockerfile.build(@platform).start("/sbin/my_init")
14
+ @ip_address = server_template.build(@platform).start_daemon("/sbin/my_init", start_options)
15
15
  end
16
16
 
17
17
  def rails_config
18
18
  {
19
19
  "adapter" => "postgresql",
20
20
  "database" => @name,
21
- "host" => @ip_address,
21
+ "host" => container_name,
22
22
  "username" => "db",
23
23
  "password" => @password,
24
24
  "template" => "template0",
25
25
  }
26
26
  end
27
27
 
28
+ def container_link
29
+ {container_name => container_name}
30
+ end
31
+
28
32
  private
29
33
 
30
- def dockerfile
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
31
57
  file = Docker::Template.new("conjure/postgres93:1.0.0")
32
58
  file.run "echo \"ALTER USER db PASSWORD '#{@password}'\" >/tmp/setpass"
33
59
  file.run "/sbin/my_init -- /sbin/setuser postgres sh -c \"sleep 1; psql -f /tmp/setpass\""
@@ -31,23 +31,23 @@ module Conjure
31
31
  end
32
32
 
33
33
  def install_swap
34
- run "dd if=/dev/zero of=/root/swapfile bs=1024 count=524288"
34
+ run "dd if=/dev/zero of=/root/swapfile bs=4096 count=524288"
35
35
  run "mkswap /root/swapfile; swapon /root/swapfile"
36
36
  end
37
37
 
38
- def self.create(name)
38
+ def self.create(name, options = {})
39
39
  puts "Creating DigitalOcean droplet..."
40
- new DigitalOcean::Droplet.new(droplet_options uniquify(name))
40
+ new DigitalOcean::Droplet.new(droplet_options(uniquify(name), options))
41
41
  end
42
42
 
43
- def self.droplet_options(name)
43
+ def self.droplet_options(name, options = {})
44
44
  raise "Error: DIGITALOCEAN_API_TOKEN must be set." unless ENV["DIGITALOCEAN_API_TOKEN"]
45
45
  {
46
46
  image: "docker",
47
47
  key_data: key_data,
48
48
  name: name,
49
49
  region: "nyc3",
50
- size: "512mb",
50
+ size: (options[:instance_size] || "512mb"),
51
51
  token: ENV["DIGITALOCEAN_API_TOKEN"],
52
52
  }
53
53
  end
@@ -3,6 +3,6 @@ server {
3
3
  root /home/app/application/current/public;
4
4
  passenger_enabled on;
5
5
  passenger_user app;
6
- passenger_ruby /usr/bin/ruby2.1;
6
+ passenger_ruby /usr/bin/ruby2.2;
7
7
  passenger_app_env <%= rails_env %>;
8
8
  }
@@ -5,23 +5,23 @@ server {
5
5
 
6
6
  server {
7
7
  listen 443 ssl;
8
+ server_name <%= ssl_hostname %>;
8
9
  root /home/app/application/current/public;
9
10
  passenger_enabled on;
10
11
  passenger_user app;
11
- passenger_ruby /usr/bin/ruby2.1;
12
+ passenger_ruby /usr/bin/ruby2.2;
12
13
  passenger_app_env <%= rails_env %>;
13
14
 
14
15
  ssl_certificate /etc/ssl/certs/application.crt;
15
16
  ssl_certificate_key /etc/ssl/private/application.key;
17
+ ssl_session_timeout 1d;
18
+ ssl_session_cache shared:SSL:50m;
19
+ ssl_dhparam /etc/ssl/dhparam.pem;
16
20
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
17
- ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
21
+ ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
18
22
  ssl_prefer_server_ciphers on;
19
-
20
- proxy_set_header X-SSL-Subject $ssl_client_s_dn;
21
- proxy_set_header X-SSL-Issuer $ssl_client_i_dn;
22
- proxy_set_header X-Forwarded-Proto https;
23
- proxy_set_header X-Real-IP $remote_addr;
24
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
25
- proxy_set_header Host $http_host;
26
- proxy_redirect off;
23
+ ssl_stapling on;
24
+ ssl_stapling_verify on;
25
+ ssl_trusted_certificate /etc/ssl/certs/root_and_intermediates.crt;
26
+ resolver 8.8.8.8 8.8.4.4;
27
27
  }
@@ -1,7 +1,6 @@
1
1
  module Conjure
2
2
  module Service
3
3
  class CloudServer
4
- require "fog"
5
4
  require "pathname"
6
5
  attr_reader :name
7
6
 
@@ -1,3 +1,3 @@
1
1
  module Conjure
2
- VERSION = "0.2.8" unless defined?(VERSION)
2
+ VERSION = "0.2.9" unless defined?(VERSION)
3
3
  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.2.8
4
+ version: 0.2.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,16 +9,16 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-10-31 00:00:00.000000000 Z
12
+ date: 2015-06-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: fog
15
+ name: net-scp
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 1.19.0
21
+ version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,9 +26,9 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 1.19.0
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: thor
31
+ name: net-ssh
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
@@ -44,7 +44,7 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
- name: unf
47
+ name: thor
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
@@ -163,54 +163,53 @@ executables:
163
163
  extensions: []
164
164
  extra_rdoc_files: []
165
165
  files:
166
- - lib/conjure.rb
167
- - lib/conjure/instance.rb
168
- - lib/conjure/target.rb
169
- - lib/conjure/provider.rb
170
166
  - lib/conjure/application.rb
167
+ - lib/conjure/command.rb
171
168
  - lib/conjure/command_target.rb
172
- - lib/conjure/log.rb
173
- - lib/conjure/version.rb
174
169
  - lib/conjure/config.rb
170
+ - lib/conjure/data_set.rb
171
+ - lib/conjure/digital_ocean/account.rb
172
+ - lib/conjure/digital_ocean/droplet.rb
173
+ - lib/conjure/digital_ocean/key.rb
174
+ - lib/conjure/digital_ocean/key_set.rb
175
+ - lib/conjure/http_request.rb
175
176
  - lib/conjure/identity.rb
176
- - lib/conjure/provision/server.rb
177
+ - lib/conjure/instance.rb
178
+ - lib/conjure/log.rb
179
+ - lib/conjure/provider.rb
180
+ - lib/conjure/provision/docker/host.rb
181
+ - lib/conjure/provision/docker/image.rb
182
+ - lib/conjure/provision/docker/template.rb
177
183
  - lib/conjure/provision/instance.rb
184
+ - lib/conjure/provision/local_docker.rb
178
185
  - lib/conjure/provision/passenger.rb
179
186
  - lib/conjure/provision/postgres.rb
180
- - lib/conjure/provision/docker/host.rb
181
- - lib/conjure/provision/docker/template.rb
182
- - lib/conjure/provision/docker/image.rb
183
- - lib/conjure/provision/templates/application-ssl.conf.erb
187
+ - lib/conjure/provision/server.rb
184
188
  - lib/conjure/provision/templates/application-no-ssl.conf.erb
185
- - lib/conjure/provision/local_docker.rb
186
- - lib/conjure/command.rb
187
- - lib/conjure/data_set.rb
188
- - lib/conjure/service/digital_ocean_account.rb
189
- - lib/conjure/service/rails_codebase.rb
190
- - lib/conjure/service/database/postgres.rb
189
+ - lib/conjure/provision/templates/application-ssl.conf.erb
190
+ - lib/conjure/provision.rb
191
+ - lib/conjure/service/cloud_server.rb
191
192
  - lib/conjure/service/database/mysql.rb
192
- - lib/conjure/service/rails_log_view.rb
193
- - lib/conjure/service/docker_host.rb
193
+ - lib/conjure/service/database/postgres.rb
194
194
  - lib/conjure/service/database.rb
195
- - lib/conjure/service/cloud_server.rb
195
+ - lib/conjure/service/digital_ocean_account.rb
196
+ - lib/conjure/service/docker_host.rb
197
+ - lib/conjure/service/docker_shell.rb
196
198
  - lib/conjure/service/forwarded_shell.rb
199
+ - lib/conjure/service/rails_codebase.rb
200
+ - lib/conjure/service/rails_console.rb
201
+ - lib/conjure/service/rails_log_view.rb
197
202
  - lib/conjure/service/rails_server.rb
203
+ - lib/conjure/service/rake_task.rb
198
204
  - lib/conjure/service/remote_file_set.rb
199
205
  - lib/conjure/service/remote_shell.rb
200
- - lib/conjure/service/rails_console.rb
201
- - lib/conjure/service/rake_task.rb
202
- - lib/conjure/service/docker_shell.rb
203
206
  - lib/conjure/service/repository_link.rb
204
207
  - lib/conjure/service/volume.rb
205
- - lib/conjure/provision.rb
206
- - lib/conjure/notes.txt
207
- - lib/conjure/view/table_view.rb
208
+ - lib/conjure/target.rb
209
+ - lib/conjure/version.rb
208
210
  - lib/conjure/view/application_view.rb
209
- - lib/conjure/digital_ocean/key.rb
210
- - lib/conjure/digital_ocean/key_set.rb
211
- - lib/conjure/digital_ocean/account.rb
212
- - lib/conjure/digital_ocean/droplet.rb
213
- - lib/conjure/http_request.rb
211
+ - lib/conjure/view/table_view.rb
212
+ - lib/conjure.rb
214
213
  - README.md
215
214
  - History.md
216
215
  - License.txt
@@ -236,7 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
236
235
  version: 1.3.6
237
236
  requirements: []
238
237
  rubyforge_project:
239
- rubygems_version: 1.8.29
238
+ rubygems_version: 1.8.30
240
239
  signing_key:
241
240
  specification_version: 3
242
241
  summary: Magically powerful deployment for Rails applications
@@ -1,201 +0,0 @@
1
- ==== New hook-based architecture:
2
- 1. Proxy app, binds to machine's ports and proxies traffic to other containers
3
- 2. Deployer app, builds and starts revisions of the app in other containers
4
- - Recieves github push notification, builds a new container with the new app revision
5
- - Uses a custom-built Dockerfile for the app, designed to rebuild with minimal i/o
6
- - After new revision is verified up and running, notifies the proxy to redirect
7
- - Could run a small capybara smoke test against the production app
8
- - Stops old container. Destroys it? (Rebuilding it should be fast if needed)
9
- 3. The application itself
10
- ====
11
-
12
- 1. Add area in conjure repo to build and publish docker images
13
- - publish "conjure/passenger-ruby21"
14
- - publish "conjure/postgres"
15
- 2. Add isolated conjure commands to work with custom docker images:
16
- - "provision [rails-env]"
17
- - Creates DO server using DIGITAL_OCEAN_* env vars
18
- - Starts conjure/postgres
19
- - Installs shared database.yml
20
- - Adds 'passenger_app_env ENV' to http{} section of nginx.conf
21
- - Starts conjure/passenger-ruby21 linked to postgres
22
- - Displays needed Cap info: ip, ssh port, deploy user, app path, rails_env
23
- - "addkey [ip] [sshport]"
24
- 3. Add conjure to client app & run "provision staging"
25
- 4. Add Cap to client app and configure staging settings
26
- 5. "cap staging deploy" from client app
27
-
28
- ==== Steps to deploy w/ Cap:
29
-
30
- Dockerfile (webserver):
31
- Install passenger/nginx
32
- Install likely gem dependencies incl. node
33
- Install required ruby version
34
- Dockerfile (postgres):
35
-
36
- Conjure:
37
- Provision DigitalOcean Docker instance
38
-
39
- Postgres:
40
- Start postgres container
41
-
42
- Passenger:
43
- Start webserver container linked to postgres container
44
- Install public key in webserver container
45
- Install nginx config for app
46
- Install shared database.yml
47
-
48
- Script in app:
49
- Capistrano:
50
- Deploy current app version
51
-
52
-
53
- TASKS:
54
- Remove "label" from prepared shell creation
55
- Alternate way to show per-service progress output
56
- Log creation and status from each service
57
- Log name and IP from docker container creation in verbose mode only
58
- Separate platforms vs services
59
- Deployment.deploy should become Deployment.create
60
-
61
- Instead of passing DockerHost objects around, pass something that
62
- knows how to provision OS shells (possibly from multiple sources).
63
- DigitalOceanAccount etc should be an implementation of this interface.
64
- shell = shell_source.prepare_shell do
65
- run "cmd"
66
- run "cmd2"
67
- environment :key => "value"
68
- port 80
69
- end
70
-
71
- Application - the code to be deployed (in the abstract, i.e. in a
72
- repo not yet copied to the server(s)
73
-
74
- Instance - a specific running copy of an application
75
- accessed through various interfaces: web address, rails console, etc
76
-
77
- Database - n/a, too ambiguous
78
- Dataset - A specific data set
79
- accessed through an interface w/ a specific db protocol.
80
-
81
- Deployment should return a shell in the app environment as an
82
- interface
83
-
84
- Deployment should return a DataSet (that possible aggregates multiple
85
- data sets used by the app). If an app needs a MySQL database, a Redis
86
- database, and a local directory of user-uploaded files, all these must
87
- stay in sync with each other and so should be aggregated under a
88
- single DataSet interface.
89
-
90
- Instance should instantiate and provide subsequent access to all
91
- runtime dependencies of the codebase. This includes the web server,
92
- data sets, etc. An app's mutable local filesystem should be considered
93
- a data set too, and probably also the logs.
94
-
95
- An Application should be something more abstract than the current
96
- Codebase. It shouldn't know about the rails environment or the
97
- database, it should be little more than a reference to a git repo. The
98
- concept of a "codebase" that's checked out onto the deployment
99
- server(s) should be something else (maybe just a Volume that a branch
100
- of the application gets copied to).
101
-
102
- But where do the database, logger, cron jobs, and other required
103
- services get identified and instantiated?
104
-
105
- Conjure's basic job is: deploy [something] [somewhere] using
106
- [platforms]. "Something" is a Service, of which Instance and DataSet
107
- are both types. "Somewhere" is the desired interface over which the
108
- new Service will be accessible. "Platform" is the cloud service, local
109
- VMs, and other combined platforms that will be used to do the
110
- deployment.
111
-
112
- Need a concept for something that has both stdin and stdout (and
113
- stderr) streams ("Console"?). This is what's returned by a rake task
114
- or rails console instantiation, to connect it to the user's console,
115
- and it can also be returned from a CommandShell to give the user
116
- direct access to that as well.
117
-
118
- "Show" output prototype:
119
-
120
- # Showing application status (Conjure v1.2.23)
121
- # Origin git@github.com/brianauton/conjure
122
- # Authorization OK (using public key)
123
- #
124
- # Deployed Instances:
125
- # Address Environment Branch Revision
126
- # 192.168.0.1 production master 3FA4D099 (up to date)
127
- #
128
- # Data Sets:
129
- # Name Status Size
130
- # production-2 active 2GB
131
- # production-1 archived 2MB
132
-
133
- # Showing instance status (Conjure v1.2.23)
134
- # Address 192.168.0.1
135
- # Environment production
136
- # Branch master
137
- # Revision 3FA4D099 (behind by 2 commits)
138
- # Uptime 2 days, 3 hours, 17 minutes
139
-
140
- Could have "named" instances ("production-2", user-specified names,
141
- etc) but "address" is enough to identify instances for now. Should
142
- guess the specified instance by either ip address, subdomain (when
143
- supported), or rails_env. Need "deploy" to be a shorthand for either
144
- "create" or "update" since "deploy staging" is ambiguous if there's
145
- already a staging instance. Maybe "deploy" should be deprecated?
146
-
147
- Needs:
148
- Separate commands to "create" and "update" instances
149
- Support specific env/branch when creating
150
- Preserve existing env/branch when updating
151
- Support changing env/branch when updating
152
- Support default instance params based on addr/env/other info given
153
- Destroy instances
154
- Introduce "platforms"
155
- Deploy to local docker
156
- Deploy to vagrant (?)
157
- Progress display
158
- Allow specifying SHA for deployment (pull out into object with repo+branch?)
159
- Used stored docker images for faster deployment
160
-
161
-
162
- New Refactor (POODR)
163
-
164
- Application-related models:
165
- Application - All revisions of the app in abstract (a repo URL for now)
166
- ApplicationVersion - Refers to a specific repo/branch/revision
167
- ApplicationSource - Unpacked into a file system for reading/writing
168
-
169
- UserPreferredPlatform - used by Command. Takes all user
170
- configuration (command line switches, config file, etc) and produces
171
- a Platform used to provision services.
172
-
173
- InstanceFactory - takes a Platform and an ApplicationRevision to deploy on it.
174
- queries [something] to ask which services the ApplicationRevision needs.
175
- queries Instance to create it with the services
176
- Instance - associates an ApplicationVersion with multiple Services that support it.
177
- traverses the services to find certain kinds (web service, database)
178
-
179
-
180
- Acceptance specs that drive Command and watch for specific output
181
- Unit specs for Command that expect messages to collaborators
182
-
183
-
184
- [binary]
185
- constructs Command with a CommandResultView
186
-
187
- Command
188
- takes status_view (via constant)
189
- sends output to status_view
190
-
191
- StatusView
192
- takes various *View classes for rendering different types
193
- takes output_stream
194
- sends output_stream and object for each object rendered
195
- sends text output directly to output_stream
196
-
197
- ApplicationView
198
- takes output_stream and application
199
-
200
- Cloud server infrastructure tips:
201
- http://wblinks.com/notes/aws-tips-i-wish-id-known-before-i-started/