breeze 0.0.1 → 0.0.2
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/README.md +89 -1
- data/lib/breeze.rb +1 -1
- data/lib/breeze/tasks.rb +1 -1
- data/lib/breeze/tasks/app.rb +42 -9
- data/lib/breeze/tasks/{list.rb → describe.rb} +5 -3
- data/lib/breeze/tasks/server.rb +1 -1
- data/lib/breeze/tasks/server/image.rb +10 -5
- data/lib/templates/Thorfile +13 -10
- data/lib/templates/profiles/rails_and_image_magick/configs/database.yml +1 -1
- data/lib/templates/profiles/rails_and_image_magick/configs/nginx/nginx.conf +5 -9
- data/lib/templates/profiles/rails_and_image_magick/scripts/install_conf.sh +1 -1
- data/lib/templates/profiles/rails_and_image_magick/scripts/install_cust.sh +1 -1
- data/lib/templates/shared/scripts/deploy.sh +3 -3
- metadata +4 -4
data/README.md
CHANGED
@@ -1,4 +1,92 @@
|
|
1
1
|
# breeze
|
2
2
|
|
3
3
|
Breeze provides some [Thor](https://github.com/wycats/thor) tasks and example scripts for managing cloud computing resources
|
4
|
-
on [Amazon's AWS cloud](http://aws.amazon.com/).
|
4
|
+
and deployments on [Amazon's AWS cloud](http://aws.amazon.com/). It uses [fog](https://github.com/geemus/fog) for the hard
|
5
|
+
work so it should be fairly easy to add support for other cloud computing providers that are supported by fog.
|
6
|
+
|
7
|
+
Breeze implements zero downtime deployments by moving an elastic ip from one server to another. Db migrations have to be
|
8
|
+
compatible with the previous version.
|
9
|
+
|
10
|
+
## install
|
11
|
+
|
12
|
+
gem install breeze
|
13
|
+
cd your-project
|
14
|
+
breeze init
|
15
|
+
|
16
|
+
Then edit Thorfile and the stuff that got copied to config/breeze.
|
17
|
+
|
18
|
+
Management of configuration files is almost compatible with [rubber](https://github.com/wr0ngway/rubber)
|
19
|
+
but breeze does not support roles and additives. See [the rubber wiki](https://github.com/wr0ngway/rubber/wiki/Configuration)
|
20
|
+
for more information.
|
21
|
+
|
22
|
+
## create a server image
|
23
|
+
|
24
|
+
thor server:image:create
|
25
|
+
|
26
|
+
The default install.sh compiles ruby, passenger, nginx and image magick. It takes a long time
|
27
|
+
(maybe half an hour on a small instance). It will prompt for the image name when completed.
|
28
|
+
|
29
|
+
## use it
|
30
|
+
|
31
|
+
thor describe # List all cloud resources that the current account can control with breeze
|
32
|
+
|
33
|
+
thor staging:deploy # Deploy a new version by replacing old servers with new ones
|
34
|
+
thor staging:disable # Copy maintenance.html to public/system/ on active web servers
|
35
|
+
thor staging:enable # Remove system/maintenance.html from active web servers
|
36
|
+
thor staging:rollback # Rollback the previous deploy
|
37
|
+
thor staging:start # Start web server and db for staging
|
38
|
+
thor staging:stop # Stop staging and destroy server and db
|
39
|
+
|
40
|
+
Define your staging and production in the Thorfile and the same tasks become available for both name spaces.
|
41
|
+
These tasks call app tasks with fixed parameters.
|
42
|
+
|
43
|
+
## plumbing commands
|
44
|
+
|
45
|
+
app
|
46
|
+
---
|
47
|
+
thor app:deploy PUBLIC_SERVER_NAME DB_SERVER_NAME BRANCH # Deploy a new version by replacing old servers with new ones
|
48
|
+
thor app:disable PUBLIC_SERVER_NAME # Upload system/maintenance.html to web servers
|
49
|
+
thor app:enable PUBLIC_SERVER_NAME # Remove system/maintenance.html from web servers
|
50
|
+
thor app:rollback PUBLIC_SERVER_NAME # Rollback a deploy
|
51
|
+
thor app:start PUBLIC_SERVER_NAME [DB_SERVER_NAME] [DB_NAME] # Start a new app with web server and db
|
52
|
+
thor app:stop PUBLIC_SERVER_NAME # Destroy web server and db
|
53
|
+
|
54
|
+
configuration
|
55
|
+
-------------
|
56
|
+
thor configuration:deploy_to_localhost # Transform and deploy server configuration files to the local file system based on...
|
57
|
+
|
58
|
+
db
|
59
|
+
--
|
60
|
+
thor db:clone OLD_DB NEW_DB # Create a new db server using the latest backup of OLD_DB.
|
61
|
+
thor db:create SERVER_NAME [DB_NAME] # Create a new database server
|
62
|
+
thor db:destroy NAME # Destroy a database server
|
63
|
+
|
64
|
+
dns
|
65
|
+
---
|
66
|
+
thor dns:record:create ZONE_ID NAME TYPE IP [TTL] # Create a new DNS record
|
67
|
+
thor dns:record:destroy ZONE_ID NAME [TYPE] # Destroy a DNS record
|
68
|
+
thor dns:zone:create DOMAIN # Create a new DNS zone
|
69
|
+
thor dns:zone:destroy ZONE_ID # Destroy a DNS zone
|
70
|
+
thor dns:zone:import ZONE_ID FILE # Creates dns records specified in FILE
|
71
|
+
|
72
|
+
describe
|
73
|
+
--------
|
74
|
+
thor describe:addresses # List allocated ip addresses
|
75
|
+
thor describe:cloud_resources # List all cloud resources that the current account can control with breeze
|
76
|
+
thor describe:db_servers # List database servers
|
77
|
+
thor describe:dns_records ZONE_ID # List all DNS records for the given zone
|
78
|
+
thor describe:dns_zones # Describe DNS zones
|
79
|
+
thor describe:images # Describe machine images owned by Breeze::CONFIGURATION[:image_owner]
|
80
|
+
thor describe:servers # Describe server instances
|
81
|
+
thor describe:volumes # Describe block store volumes (EBS)
|
82
|
+
|
83
|
+
server
|
84
|
+
------
|
85
|
+
thor server:address:associate IP NEW_SERVER_ID # Associate an existing IP with a new server
|
86
|
+
thor server:address:create SERVER_ID # Create and associate a new elastic ip
|
87
|
+
thor server:address:release IP # Release the ip address
|
88
|
+
thor server:create # Launch a new server instance
|
89
|
+
thor server:destroy INSTANCE_ID # Terminate a running (or stopped) server instance
|
90
|
+
thor server:image:create # Launch a server with the base image, wait for it to boot, invoke...
|
91
|
+
thor server:tag:create SERVER_ID KEY VALUE # Create or update a tag
|
92
|
+
thor server:tag:destroy SERVER_ID KEY # Delete a tag
|
data/lib/breeze.rb
CHANGED
data/lib/breeze/tasks.rb
CHANGED
data/lib/breeze/tasks/app.rb
CHANGED
@@ -57,24 +57,34 @@ module Breeze
|
|
57
57
|
deploy_command([new_server], public_server_name, db_server_name, branch)
|
58
58
|
puts("The new server should soon be available at #{ip(new_server)}.")
|
59
59
|
if ask("Ready to continue and move the elastic_ip for #{public_server_name} to the new server? [YES/rollback] >") =~ /r|n/i
|
60
|
-
|
60
|
+
new_server.destroy
|
61
|
+
else
|
62
|
+
remote("sudo shutdown -h +#{CONFIGURATION[:rollback_window]} &", :host => ip(old_server))
|
61
63
|
old_server.spare_for_rollback!
|
62
64
|
move_addresses(old_server, new_server)
|
63
|
-
else
|
64
|
-
new_server.destroy
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
68
|
desc 'rollback PUBLIC_SERVER_NAME', 'Rollback a deploy'
|
69
69
|
def rollback(public_server_name)
|
70
70
|
old_server = spare_servers(public_server_name).first
|
71
|
+
raise "no running spare server found for #{public_server_name}" unless old_server
|
72
|
+
if ip(old_server)
|
73
|
+
temp_ip = nil
|
74
|
+
else
|
75
|
+
puts("Old server does not have a public ip. Allocating a temporary address:")
|
76
|
+
thor("server:address:create #{old_server.id}")
|
77
|
+
old_server.reload until old_server.addresses.first
|
78
|
+
temp_ip = ip(old_server)
|
79
|
+
end
|
71
80
|
remote('sudo shutdown -c', :host => ip(old_server))
|
72
81
|
new_server = active_servers(public_server_name).first
|
73
82
|
remote(disable_app_command, :host => ip(new_server))
|
83
|
+
thor("server:address:release #{temp_ip}") if temp_ip
|
74
84
|
move_addresses(new_server, old_server)
|
75
85
|
old_server.breeze_state('reactivated')
|
76
86
|
new_server.breeze_state('abandoned_due_to_rollback')
|
77
|
-
if accept?('
|
87
|
+
if accept?('Ready to destroy the abandoned server now?')
|
78
88
|
new_server.destroy
|
79
89
|
end
|
80
90
|
end
|
@@ -87,16 +97,16 @@ module Breeze
|
|
87
97
|
end
|
88
98
|
end
|
89
99
|
|
90
|
-
def
|
91
|
-
fog.servers.select{ |s| s.name == public_server_name }
|
100
|
+
def running_servers(public_server_name)
|
101
|
+
fog.servers.select{ |s| s.ready? and s.name == public_server_name }
|
92
102
|
end
|
93
103
|
|
94
104
|
def spare_servers(public_server_name)
|
95
|
-
|
105
|
+
running_servers(public_server_name).select{ |s| s.spare_for_rollback? }
|
96
106
|
end
|
97
107
|
|
98
108
|
def active_servers(public_server_name)
|
99
|
-
|
109
|
+
running_servers(public_server_name).select{ |s| not s.spare_for_rollback? }
|
100
110
|
end
|
101
111
|
|
102
112
|
def on_each_server(command, public_server_name)
|
@@ -106,7 +116,7 @@ module Breeze
|
|
106
116
|
end
|
107
117
|
|
108
118
|
def disable_app_command
|
109
|
-
"cd #{CONFIGURATION[:app_path]} && cp config/breeze/maintenance.html public/system/"
|
119
|
+
"cd #{CONFIGURATION[:app_path]} && mkdir -p public/system && cp config/breeze/maintenance.html public/system/"
|
110
120
|
end
|
111
121
|
|
112
122
|
def enable_app_command
|
@@ -141,5 +151,28 @@ module Breeze
|
|
141
151
|
super(task + (options[:force] ? ' --force' : ''))
|
142
152
|
end
|
143
153
|
|
154
|
+
# Don't know how to include or inherit thor tasks and descriptions.
|
155
|
+
# These may be included in Staging and Production.
|
156
|
+
def self.inherited(c)
|
157
|
+
c.class_eval <<-END_TASKS
|
158
|
+
desc 'deploy', 'Deploy a new version by replacing old servers with new ones'
|
159
|
+
def deploy
|
160
|
+
thor("app:deploy \#{PUBLIC_SERVER_NAME} \#{DB_SERVER_NAME} \#{BRANCH}")
|
161
|
+
end
|
162
|
+
desc 'rollback', 'Rollback the previous deploy'
|
163
|
+
def rollback
|
164
|
+
thor("app:rollback \#{PUBLIC_SERVER_NAME}")
|
165
|
+
end
|
166
|
+
desc 'disable', 'Copy maintenance.html to public/system/ on active web servers'
|
167
|
+
def disable
|
168
|
+
thor("app:disable \#{PUBLIC_SERVER_NAME}")
|
169
|
+
end
|
170
|
+
desc 'enable', 'Remove system/maintenance.html from active web servers'
|
171
|
+
def enable
|
172
|
+
thor("app:enable \#{PUBLIC_SERVER_NAME}")
|
173
|
+
end
|
174
|
+
END_TASKS
|
175
|
+
end
|
176
|
+
|
144
177
|
end
|
145
178
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Breeze
|
2
2
|
|
3
|
-
class
|
3
|
+
class Describe < Veur
|
4
|
+
|
5
|
+
default_task :cloud_resources
|
4
6
|
|
5
7
|
desc :cloud_resources, 'List all cloud resources that the current account can control with breeze'
|
6
8
|
def cloud_resources
|
@@ -24,9 +26,9 @@ module Breeze
|
|
24
26
|
desc :servers, 'Describe server instances'
|
25
27
|
def servers
|
26
28
|
report "SERVER INSTANCES",
|
27
|
-
['Name', 'Instance ID', 'IP Address', 'Image ID', '
|
29
|
+
['Name', 'Instance ID', 'IP Address', 'Image ID', 'Type', 'Zone', 'State', 'Info'],
|
28
30
|
fog.servers.map { |i|
|
29
|
-
[i.name, i.id, i.public_ip_address, i.image_id, i.flavor_id, i.availability_zone, i.state]
|
31
|
+
[i.name, i.id, i.public_ip_address, i.image_id, i.flavor_id, i.availability_zone, i.state, i.breeze_state]
|
30
32
|
}
|
31
33
|
end
|
32
34
|
|
data/lib/breeze/tasks/server.rb
CHANGED
@@ -8,19 +8,24 @@ module Breeze
|
|
8
8
|
'stop the server, create a new machine image as a snapshot of the root device, and destroy the server.'
|
9
9
|
method_options CONFIGURATION[:default_server_options].merge(CONFIGURATION[:create_image_options])
|
10
10
|
def create
|
11
|
-
|
11
|
+
# The commented lines used to work before fog 0.7.0.
|
12
|
+
# options[:block_device_mapping] = [{:device_name => '/dev/sda1', :ebs_volume_size => options.delete(:root_device_size)}]
|
13
|
+
options[:block_device_mapping] = [{'DeviceName' => '/dev/sda1', 'Ebs.VolumeSize' => options.delete(:root_device_size)}]
|
12
14
|
server = create_server(options)
|
13
15
|
prepare_private_image(server.public_ip_address)
|
14
16
|
print('Stopping the server before saving a snapshot')
|
15
17
|
server.stop
|
16
18
|
wait_until('stopped!') { server.stopped? }
|
17
|
-
thor('
|
18
|
-
|
19
|
+
thor('describe:images')
|
20
|
+
puts('===== Old server images are listed above. Give a name to the new image. =====')
|
21
|
+
# image = fog.images.create(:name => ask('Image name >'), :instance_id => server.id)
|
22
|
+
fog.create_image(server.id, ask('Image name >'), '')
|
19
23
|
server.destroy
|
20
24
|
puts
|
21
|
-
puts("===> Created image #{image.id} and terminated temporary server #{server.id}.")
|
25
|
+
# puts("===> Created image #{image.id} and terminated temporary server #{server.id}.")
|
26
|
+
puts("===> Created a new server image and terminated temporary server #{server.id}.")
|
22
27
|
puts
|
23
|
-
puts("NOTICE: it may take a while before the new image shows up in
|
28
|
+
puts("NOTICE: it may take a while before the new image shows up in describe:images")
|
24
29
|
end
|
25
30
|
|
26
31
|
end
|
data/lib/templates/Thorfile
CHANGED
@@ -16,6 +16,7 @@ Breeze::CONFIGURATION = {
|
|
16
16
|
# Remote and upload commands are required in order to create a server image or deploy
|
17
17
|
# an application. Arguments marked with %{} are automatically replaced when the
|
18
18
|
# commands are used. Use "ssh -i /path/to/key" if not using your default ssh key.
|
19
|
+
:remote_available? => 'ssh -q ubuntu@%{host} exit',
|
19
20
|
:remote_command => "ssh ubuntu@%{host} '%{command}'",
|
20
21
|
:upload_command => 'rsync -v %{file_pattern} ubuntu@%{host}:%{remote_path}',
|
21
22
|
|
@@ -38,7 +39,7 @@ Breeze::CONFIGURATION = {
|
|
38
39
|
:root_device_size => 15 # in GB
|
39
40
|
},
|
40
41
|
|
41
|
-
# machine images owned by this account are included in
|
42
|
+
# machine images owned by this account are included in describe:images (provided that you have access to them)
|
42
43
|
:image_owner => 'YOUR-ACCOUNT-ID-WITHOUT-DASHES', # canonical: '099720109477'
|
43
44
|
|
44
45
|
# db configuration is required in order to use Amazon RDS
|
@@ -66,10 +67,10 @@ Breeze::CONFIGURATION = {
|
|
66
67
|
# with the "thor help" command.
|
67
68
|
require 'breeze/tasks'
|
68
69
|
|
70
|
+
# prepare_private_image is called from server:image:create. Modify this and/or the scripts
|
71
|
+
# that are uploaded in order to create your own private machine image.
|
69
72
|
class Breeze::Server::Image
|
70
73
|
private
|
71
|
-
# This method is called from server:image:create. Modify this and/or the scripts that
|
72
|
-
# are uploaded in order to create your own private machine image.
|
73
74
|
def prepare_private_image(ip_address)
|
74
75
|
wait_until_host_is_available(ip_address)
|
75
76
|
puts("Uploading scripts...")
|
@@ -78,8 +79,7 @@ class Breeze::Server::Image
|
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
|
-
#
|
82
|
-
|
82
|
+
# deploy_command is called from app:start and app:deploy.
|
83
83
|
class Breeze::App
|
84
84
|
private
|
85
85
|
def deploy_command(servers, public_server_name, db_server_name, branch)
|
@@ -90,15 +90,18 @@ class Breeze::App
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
#
|
93
|
+
# Define staging:start etc. below. The constants are also needed by
|
94
|
+
# inherited tasks: deploy, rollback, enable and disable.
|
95
|
+
|
94
96
|
class Staging < Breeze::App
|
95
97
|
|
96
98
|
PUBLIC_SERVER_NAME = 'staging.example.com'
|
97
99
|
DB_SERVER_NAME = 'staging-db'
|
100
|
+
BRANCH = 'master'
|
98
101
|
|
99
102
|
desc 'start', 'Start web server and db for staging'
|
100
103
|
def start
|
101
|
-
thor("app:start #{PUBLIC_SERVER_NAME} #{DB_SERVER_NAME} --db-to-clone=#{Production::DB_SERVER_NAME} --deploy-branch
|
104
|
+
thor("app:start #{PUBLIC_SERVER_NAME} #{DB_SERVER_NAME} --db-to-clone=#{Production::DB_SERVER_NAME} --deploy-branch=#{BRANCH}")
|
102
105
|
end
|
103
106
|
|
104
107
|
desc 'stop', 'Stop staging and destroy server and db'
|
@@ -108,15 +111,15 @@ class Staging < Breeze::App
|
|
108
111
|
|
109
112
|
end
|
110
113
|
|
111
|
-
# thor production:start
|
112
114
|
class Production < Breeze::App
|
113
115
|
|
114
|
-
PUBLIC_SERVER_NAME = '
|
116
|
+
PUBLIC_SERVER_NAME = 'www.example.com'
|
115
117
|
DB_SERVER_NAME = 'production-db'
|
118
|
+
BRANCH = 'stable'
|
116
119
|
|
117
120
|
desc 'start', 'Start web server and db for production'
|
118
121
|
def start
|
119
|
-
thor("app:start #{PUBLIC_SERVER_NAME} #{DB_SERVER_NAME}
|
122
|
+
thor("app:start #{PUBLIC_SERVER_NAME} #{DB_SERVER_NAME} db_name --dns-ttl=300 --deploy-branch=#{BRANCH}")
|
120
123
|
end
|
121
124
|
|
122
125
|
end
|
@@ -5,9 +5,9 @@
|
|
5
5
|
system("mkdir -p #{dir} && chown www-data #{dir}") unless File.directory?(dir)
|
6
6
|
end
|
7
7
|
|
8
|
-
passenger_version = "3.0.
|
8
|
+
passenger_version = "3.0.5"
|
9
9
|
server_name = ENV['PUBLIC_SERVER_NAME']
|
10
|
-
server_root = "/
|
10
|
+
server_root = "#{CONFIGURATION[:app_path]}/public"
|
11
11
|
|
12
12
|
shared_server_conf = <<-END_SHARED_SERVER_CONF
|
13
13
|
|
@@ -22,14 +22,10 @@
|
|
22
22
|
# let browsers cache static assets
|
23
23
|
location ~ ^/(images|javascripts|stylesheets)/ { expires 1y; }
|
24
24
|
|
25
|
-
#
|
26
|
-
|
27
|
-
if (-f $document_root/system/maintenance.html) {
|
28
|
-
rewrite ^(.*)$ /system/maintenance.html last;
|
29
|
-
break;
|
30
|
-
}
|
25
|
+
# static files, page caching and maintenance.html
|
26
|
+
try_files $uri $uri/index.html $uri.html /system/maintenance.html @passenger;
|
31
27
|
|
32
|
-
location
|
28
|
+
location @passenger {
|
33
29
|
passenger_enabled on;
|
34
30
|
}
|
35
31
|
|
@@ -17,7 +17,7 @@ PACKAGES="$SYSTEM_PACKAGES $DB_CLIENT_PACKAGES $RUBY_BUILD_DEPENDENCIES $NGINX_A
|
|
17
17
|
|
18
18
|
# the rest is used by install_cust.sh
|
19
19
|
RUBY_PACKAGE=ruby-1.9.2-p180
|
20
|
-
IMAGE_MAGICK_PACKAGE=ImageMagick-6.6.
|
20
|
+
IMAGE_MAGICK_PACKAGE=ImageMagick-6.6.8-6
|
21
21
|
IMAGE_MAGICK_OPTIONS='--disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8'
|
22
22
|
NGINX_OPTIONS="\
|
23
23
|
--conf-path=/etc/nginx/nginx.conf \
|
@@ -5,7 +5,7 @@
|
|
5
5
|
download ftp://ftp.ruby-lang.org//pub/ruby/1.9/$RUBY_PACKAGE.tar.gz
|
6
6
|
extract_and_install $RUBY_PACKAGE
|
7
7
|
sudo gem update --system
|
8
|
-
sudo gem install --no-ri --no-rdoc bundler passenger
|
8
|
+
sudo gem install --no-ri --no-rdoc bundler passenger breeze
|
9
9
|
|
10
10
|
# install nginx and passenger
|
11
11
|
sudo passenger-install-nginx-module --auto --auto-download --prefix=/usr --extra-configure-flags="$NGINX_OPTIONS"
|
@@ -34,10 +34,10 @@ sudo usermod --groups rails ubuntu
|
|
34
34
|
|
35
35
|
wget -q --no-check-certificate --directory-prefix=$HOME --output-document=tarball.tar.gz $DOWNLOAD_URL
|
36
36
|
tar --directory $HOME -xzf tarball.tar.gz
|
37
|
-
|
38
37
|
sudo mv $HOME/*$APP_NAME* $DEPLOY_PATH
|
39
|
-
|
38
|
+
|
40
39
|
cd $DEPLOY_PATH
|
41
|
-
|
40
|
+
bundle install --deployment --without=test development
|
41
|
+
sudo chown -R rails:rails $DEPLOY_PATH
|
42
42
|
sudo PUBLIC_SERVER_NAME=$PUBLIC_SERVER_NAME DB_SERVER=$DB_SERVER thor configuration:deploy_to_localhost
|
43
43
|
sudo /etc/init.d/monit start
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Markus Bengts
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-03-
|
17
|
+
date: 2011-03-22 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -73,8 +73,8 @@ files:
|
|
73
73
|
- lib/breeze/tasks/app.rb
|
74
74
|
- lib/breeze/tasks/configuration.rb
|
75
75
|
- lib/breeze/tasks/db.rb
|
76
|
+
- lib/breeze/tasks/describe.rb
|
76
77
|
- lib/breeze/tasks/dns.rb
|
77
|
-
- lib/breeze/tasks/list.rb
|
78
78
|
- lib/breeze/tasks/server.rb
|
79
79
|
- lib/breeze/tasks/server/address.rb
|
80
80
|
- lib/breeze/tasks/server/image.rb
|