conjure 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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/