dockerploy 0.0.2 → 0.0.3
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.
- checksums.yaml +8 -8
- data/.gitignore +2 -1
- data/c +2 -0
- data/dockerploy.gemspec +2 -0
- data/lib/dockerploy/cli.rb +18 -5
- data/lib/dockerploy/configuration.rb +26 -0
- data/lib/dockerploy/deploy.rb +32 -4
- data/lib/dockerploy/image.rb +10 -4
- data/lib/dockerploy/shell_client.rb +20 -8
- data/lib/dockerploy/template.rb +27 -0
- data/lib/dockerploy/templates/config.yml.erb +17 -0
- data/lib/dockerploy/version.rb +1 -1
- data/spec/fixtures/config_with_hooks.yml +27 -0
- data/spec/fixtures/config_with_hooks_for_each_env.yml +27 -0
- data/spec/lib/dockerploy/cli_spec.rb +52 -0
- data/spec/lib/dockerploy/deploy_spec.rb +53 -3
- data/spec/lib/dockerploy/image_spec.rb +73 -0
- data/spec/lib/dockerploy/template_spec.rb +60 -0
- data/spec/spec_helper.rb +1 -0
- metadata +41 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MmJiMDlmMDFkMmE1MzVjZWUwNTU0NWM2NDU5MDkxMWVkMjI5NzFiZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NzhlOGFiMDYwNzFmN2VjNmE3MDIyOWIzYzM5ZjAxOWI3ZTkyNWEyZg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDA0ODIwNGQwNTMzODg0NGYwOTRiNGI1NTBjZTExYzBhMGY4NTIyYjUxNmMz
|
10
|
+
YjVlNWVjNDczNmNiOTVmN2RjNzQzYTBlYmUzYTg4MDRjNmM0NTU3MzBkYmJk
|
11
|
+
ZDY2ZmNlN2UzOTI4MmM3OTEyNGJlNjljYzUyZjVhOTFkNmI1NjA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MGQyNGMzYzQwNmU2OWNkN2QwMmI3OWE1MDRkNjM0MDg3MGE4NjhkNGMxNzIw
|
14
|
+
M2QxYzAwYWM3MjI5NjIwZTJhODI2NTViMjFhY2FkOGE5Yzg0MWQyYzQyZjcz
|
15
|
+
OGU0MDU3N2MwN2IzMmYxYjVjY2JlNjM0Zjc2Yjc5MmRiMjgzNjc=
|
data/.gitignore
CHANGED
data/dockerploy.gemspec
CHANGED
@@ -21,8 +21,10 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.required_ruby_version = '>= 1.9.3'
|
22
22
|
spec.add_dependency 'thor', '~> 0.19'
|
23
23
|
spec.add_dependency 'mono_logger', '~> 1.1.0'
|
24
|
+
spec.add_dependency 'net-ssh', '~> 2.6'
|
24
25
|
|
25
26
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
26
27
|
spec.add_development_dependency 'rake'
|
27
28
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
29
|
+
spec.add_development_dependency 'fakefs', '~> 0.6'
|
28
30
|
end
|
data/lib/dockerploy/cli.rb
CHANGED
@@ -4,16 +4,25 @@ require 'yaml'
|
|
4
4
|
require 'dockerploy/configuration'
|
5
5
|
require 'dockerploy/deploy'
|
6
6
|
require 'dockerploy/image'
|
7
|
+
require 'dockerploy/template'
|
8
|
+
require 'erb'
|
9
|
+
require 'ostruct'
|
7
10
|
|
8
11
|
module Dockerploy
|
9
12
|
# The command-line interface for Dockerploy
|
10
13
|
class CLI < Thor
|
11
|
-
class_option :config, aliases: ['-c'], type: :string
|
14
|
+
class_option :config, aliases: ['-c'], type: :string, required: false
|
15
|
+
class_option :tag, aliases: ['-t'], type: :string, required: false
|
12
16
|
|
13
17
|
def initialize(args = [], opts = {}, config = {})
|
14
18
|
super(args, opts, config)
|
15
19
|
end
|
16
20
|
|
21
|
+
desc 'init', 'Generate a config.yml file'
|
22
|
+
def init
|
23
|
+
Template.write
|
24
|
+
end
|
25
|
+
|
17
26
|
desc 'ps ENVIRONMENT', 'Show running containers'
|
18
27
|
def ps(environment)
|
19
28
|
config = configuration(environment.to_sym)
|
@@ -26,23 +35,27 @@ module Dockerploy
|
|
26
35
|
|
27
36
|
desc 'build', 'build an image'
|
28
37
|
def build
|
29
|
-
|
38
|
+
build_options = { tag: options[:tag] }
|
39
|
+
Image.new(configuration, build_options).build
|
30
40
|
end
|
31
41
|
|
32
42
|
desc 'push', 'push an image'
|
33
43
|
def push
|
34
|
-
|
44
|
+
build_options = { tag: options[:tag] }
|
45
|
+
Image.new(configuration, build_options).push
|
35
46
|
end
|
36
47
|
|
37
48
|
desc 'pull', 'pull an image'
|
38
49
|
def pull(environment)
|
39
|
-
|
50
|
+
build_options = { tag: options[:tag] }
|
51
|
+
Image.new(configuration(environment.to_sym), build_options).pull
|
40
52
|
end
|
41
53
|
|
42
54
|
desc 'deploy', 'deploy an application'
|
43
55
|
def deploy(environment)
|
56
|
+
deploy_options = { tag: options[:tag] }
|
44
57
|
config = configuration(environment.to_sym)
|
45
|
-
Deploy.new(config).deploy
|
58
|
+
Deploy.new(config, deploy_options).deploy
|
46
59
|
end
|
47
60
|
|
48
61
|
private
|
@@ -42,6 +42,32 @@ module Dockerploy
|
|
42
42
|
options[@env][:tagging]
|
43
43
|
end
|
44
44
|
|
45
|
+
def before_all_hooks
|
46
|
+
return {} if options[:hooks].nil? || options[:hooks][:before_deploy].nil?
|
47
|
+
options[:hooks][:before_deploy]
|
48
|
+
end
|
49
|
+
|
50
|
+
def before_hooks
|
51
|
+
raise NoEnvError if @env.nil?
|
52
|
+
return {} if options[@env].nil?
|
53
|
+
hooks = options[@env][:hooks]
|
54
|
+
return {} if hooks.nil? || hooks[:before_deploy].nil?
|
55
|
+
hooks[:before_deploy]
|
56
|
+
end
|
57
|
+
|
58
|
+
def after_all_hooks
|
59
|
+
return {} if options[:hooks].nil? || options[:hooks][:after_deploy].nil?
|
60
|
+
options[:hooks][:after_deploy]
|
61
|
+
end
|
62
|
+
|
63
|
+
def after_hooks
|
64
|
+
raise NoEnvError if @env.nil?
|
65
|
+
return {} if options[@env].nil?
|
66
|
+
hooks = options[@env][:hooks]
|
67
|
+
return {} if hooks.nil? || hooks[:after_deploy].nil?
|
68
|
+
hooks[:after_deploy]
|
69
|
+
end
|
70
|
+
|
45
71
|
private
|
46
72
|
|
47
73
|
def options
|
data/lib/dockerploy/deploy.rb
CHANGED
@@ -3,8 +3,9 @@ module Dockerploy
|
|
3
3
|
SSH_PORT = 22
|
4
4
|
HTTP_PORT = 80
|
5
5
|
|
6
|
-
def initialize(config)
|
6
|
+
def initialize(config, options = {})
|
7
7
|
@config = config
|
8
|
+
@options = options
|
8
9
|
end
|
9
10
|
|
10
11
|
def destroy(ssh_client, server)
|
@@ -19,25 +20,48 @@ module Dockerploy
|
|
19
20
|
command << option_delimiter + port_option(server)
|
20
21
|
command << option_delimiter + volume_option
|
21
22
|
command << option_delimiter + environment_variables_option
|
22
|
-
command << option_delimiter +
|
23
|
+
command << option_delimiter + image_name
|
23
24
|
ssh_client.command(command)
|
24
25
|
end
|
25
26
|
|
26
27
|
def deploy
|
27
28
|
create_tag if @config.tagging?
|
28
29
|
@config.servers.each do |server|
|
30
|
+
run_before_hooks(server)
|
29
31
|
ssh_client = SSHClient.new(server[:host], server[:username], server[:password], server[:port])
|
30
32
|
destroy(ssh_client, server)
|
31
33
|
run(ssh_client, server)
|
34
|
+
run_after_hooks(server)
|
32
35
|
end
|
33
36
|
end
|
34
37
|
|
38
|
+
def run_before_hooks(server)
|
39
|
+
@config.before_all_hooks.each { |hook| run_hook(server, hook) }
|
40
|
+
@config.before_hooks.each { |hook| run_hook(server, hook) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_after_hooks(server)
|
44
|
+
@config.after_all_hooks.each { |hook| run_hook(server, hook) }
|
45
|
+
@config.after_hooks.each { |hook| run_hook(server, hook) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_hook(server, hook)
|
49
|
+
if hook[:local]
|
50
|
+
hook[:local].each do |command|
|
51
|
+
ShellClient.new(abort_on_failure: true).command(command)
|
52
|
+
end
|
53
|
+
elsif hook[:remote]
|
54
|
+
hook[:remote].each do |command|
|
55
|
+
SSHClient.new(server[:host], server[:username], server[:password], server[:port]).command(command)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
35
59
|
private
|
36
60
|
|
37
61
|
def create_tag
|
38
62
|
tag_name = sprintf('%s-%s', @config.env, Time.now.strftime('%Y%m%dT%H%M'))
|
39
|
-
command
|
40
|
-
ShellClient.new.command(
|
63
|
+
ShellClient.new.command(sprintf('git tag %s %s', tag_name, @config.branch))
|
64
|
+
ShellClient.new.command(sprintf('git push origin %s', tag_name))
|
41
65
|
end
|
42
66
|
|
43
67
|
def volume_option
|
@@ -73,5 +97,9 @@ module Dockerploy
|
|
73
97
|
def hostname_option
|
74
98
|
sprintf('--hostname %s', @config.application_name)
|
75
99
|
end
|
100
|
+
|
101
|
+
def image_name
|
102
|
+
@options[:tag] ? sprintf('%s:%s', @config.image_name, @options[:tag]) : @config.image_name
|
103
|
+
end
|
76
104
|
end
|
77
105
|
end
|
data/lib/dockerploy/image.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
module Dockerploy
|
2
2
|
class Image
|
3
|
-
def initialize(config)
|
3
|
+
def initialize(config, options = {})
|
4
4
|
@config = config
|
5
|
+
@options = options
|
5
6
|
end
|
6
7
|
|
7
8
|
def build
|
8
|
-
command = sprintf('env DOCKER_HOST=%s docker build -t %s .', @config.docker_host,
|
9
|
+
command = sprintf('env DOCKER_HOST=%s docker build -t %s .', @config.docker_host, image_name)
|
9
10
|
ShellClient.new.command(command)
|
10
11
|
end
|
11
12
|
|
12
13
|
def push
|
13
|
-
command = sprintf('env DOCKER_HOST=%s docker push %s', @config.docker_host,
|
14
|
+
command = sprintf('env DOCKER_HOST=%s docker push %s', @config.docker_host, image_name)
|
14
15
|
ShellClient.new.command(command)
|
15
16
|
end
|
16
17
|
|
@@ -18,8 +19,13 @@ module Dockerploy
|
|
18
19
|
return unless @config.servers
|
19
20
|
@config.servers.each do |server|
|
20
21
|
ssh_client = SSHClient.new(server[:host], server[:username], server[:password], server[:port])
|
21
|
-
ssh_client.command(sprintf('docker pull %s',
|
22
|
+
ssh_client.command(sprintf('docker pull %s', image_name))
|
22
23
|
end
|
23
24
|
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def image_name
|
28
|
+
@options[:tag] ? sprintf('%s:%s', @config.image_name, @options[:tag]) : @config.image_name
|
29
|
+
end
|
24
30
|
end
|
25
31
|
end
|
@@ -1,16 +1,28 @@
|
|
1
1
|
module Dockerploy
|
2
|
-
# Wrapper for local shell command
|
3
2
|
class ShellClient
|
4
|
-
|
3
|
+
attr_accessor :output
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = options
|
5
7
|
end
|
6
8
|
|
7
9
|
def command(command)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
Dockerploy.logger.debug sprintf('Running: %s', command)
|
11
|
+
IO.popen('-') do |p|
|
12
|
+
if p.nil?
|
13
|
+
$stderr.close
|
14
|
+
exec *command.split(' ')
|
15
|
+
end
|
16
|
+
@output = p.read
|
17
|
+
Dockerploy.logger.debug p.read
|
18
|
+
end
|
19
|
+
|
20
|
+
return false if $?.nil?
|
21
|
+
result = $?.exitstatus == 0
|
22
|
+
if !result && @options[:abort_on_failure]
|
23
|
+
Dockerploy.logger.error sprintf('Failed to run: %s', command)
|
24
|
+
abort
|
12
25
|
end
|
13
|
-
true
|
14
26
|
end
|
15
27
|
end
|
16
|
-
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Dockerploy
|
2
|
+
class Template
|
3
|
+
TEMPLATE_PATH = 'templates/config.yml.erb'.freeze
|
4
|
+
CONFIG_PATH = 'docker/config.yml.sample'.freeze
|
5
|
+
|
6
|
+
def self.application_name
|
7
|
+
File.basename(Dir.getwd)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.project_name
|
11
|
+
shell_client = ShellClient.new
|
12
|
+
shell_client.command('git config --get remote.origin.url')
|
13
|
+
shell_client.output.match(/([\w-]+\/[\w-]+).git/)[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.generate
|
17
|
+
namespace = OpenStruct.new(user: ENV['USER'], application_name: self.application_name, project_name: self.project_name)
|
18
|
+
template = File.read(File.expand_path(TEMPLATE_PATH, File.dirname(__FILE__)))
|
19
|
+
ERB.new(template).result(namespace.instance_eval { binding })
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.write
|
23
|
+
FileUtils.mkdir_p('docker')
|
24
|
+
File.open(CONFIG_PATH, 'w') { |f| f.write(self.generate) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
image_name: <%= project_name %>
|
2
|
+
docker_username: <%= user %>
|
3
|
+
docker_host: tcp://:2375
|
4
|
+
application_name: <%= application_name %>
|
5
|
+
development:
|
6
|
+
branch: master
|
7
|
+
tagging: true
|
8
|
+
volumes: []
|
9
|
+
servers:
|
10
|
+
- host: 0.0.0.0
|
11
|
+
username: <%= user %>
|
12
|
+
password:
|
13
|
+
port: 22
|
14
|
+
container:
|
15
|
+
host: 0.0.0.0
|
16
|
+
ssh_port: 22
|
17
|
+
http_port: 80
|
data/lib/dockerploy/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
image_name: docker/image
|
2
|
+
docker_username: dockeruser
|
3
|
+
docker_host: tcp://test.host:4243
|
4
|
+
application_name: app
|
5
|
+
hooks:
|
6
|
+
before_deploy:
|
7
|
+
- local:
|
8
|
+
- echo "Started deploying"
|
9
|
+
- remote:
|
10
|
+
- echo "Access to server"
|
11
|
+
after_deploy:
|
12
|
+
- local:
|
13
|
+
- echo "Finished deploying"
|
14
|
+
- remote:
|
15
|
+
- echo "Access to server again"
|
16
|
+
test:
|
17
|
+
branch: master
|
18
|
+
servers:
|
19
|
+
- host: server.host
|
20
|
+
username: server_user
|
21
|
+
password: server_pass
|
22
|
+
port: 2000
|
23
|
+
role: server_role
|
24
|
+
container:
|
25
|
+
host: container.host
|
26
|
+
ssh_port: 1022
|
27
|
+
http_port: 8080
|
@@ -0,0 +1,27 @@
|
|
1
|
+
image_name: docker/image
|
2
|
+
docker_username: dockeruser
|
3
|
+
docker_host: tcp://test.host:4243
|
4
|
+
application_name: app
|
5
|
+
test:
|
6
|
+
branch: master
|
7
|
+
hooks:
|
8
|
+
before_deploy:
|
9
|
+
- local:
|
10
|
+
- echo "Started deploying on testing"
|
11
|
+
- remote:
|
12
|
+
- echo "Access to test server"
|
13
|
+
after_deploy:
|
14
|
+
- local:
|
15
|
+
- echo "Finished deploying on testing"
|
16
|
+
- remote:
|
17
|
+
- echo "Access to test server again"
|
18
|
+
servers:
|
19
|
+
- host: server.host
|
20
|
+
username: server_user
|
21
|
+
password: server_pass
|
22
|
+
port: 2000
|
23
|
+
role: server_role
|
24
|
+
container:
|
25
|
+
host: container.host
|
26
|
+
ssh_port: 1022
|
27
|
+
http_port: 8080
|
@@ -7,6 +7,18 @@ module Dockerploy
|
|
7
7
|
stub_const('Dockerploy::Configuration::DEFAULT_CONFIG_FILE', fixture_path)
|
8
8
|
end
|
9
9
|
|
10
|
+
describe '#init' do
|
11
|
+
include FakeFS::SpecHelpers
|
12
|
+
it 'runs docker ps in servers' do
|
13
|
+
FakeFS do
|
14
|
+
expect(Template).to receive(:generate).and_return('template')
|
15
|
+
cli = described_class.new
|
16
|
+
cli.init
|
17
|
+
expect(File.read('docker/config.yml.sample')).to eq('template')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
describe '#ps' do
|
11
23
|
it 'runs docker ps in servers' do
|
12
24
|
expect_any_instance_of(SSHClient).to receive(:command).with('docker ps | grep app')
|
@@ -22,6 +34,15 @@ module Dockerploy
|
|
22
34
|
cli = described_class.new
|
23
35
|
cli.build
|
24
36
|
end
|
37
|
+
|
38
|
+
context 'with tag' do
|
39
|
+
it 'runs docker build with tag name' do
|
40
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker build -t docker/image:tag .'
|
41
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
42
|
+
cli = described_class.new([], tag: 'tag')
|
43
|
+
cli.build
|
44
|
+
end
|
45
|
+
end
|
25
46
|
end
|
26
47
|
|
27
48
|
describe '#push' do
|
@@ -31,6 +52,15 @@ module Dockerploy
|
|
31
52
|
cli = described_class.new
|
32
53
|
cli.push
|
33
54
|
end
|
55
|
+
|
56
|
+
context 'with tag' do
|
57
|
+
it 'pushes the image with tag name' do
|
58
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker push docker/image:tag'
|
59
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
60
|
+
cli = described_class.new([], tag: 'tag')
|
61
|
+
cli.push
|
62
|
+
end
|
63
|
+
end
|
34
64
|
end
|
35
65
|
|
36
66
|
describe '#pull' do
|
@@ -39,6 +69,15 @@ module Dockerploy
|
|
39
69
|
cli = described_class.new
|
40
70
|
cli.pull('test')
|
41
71
|
end
|
72
|
+
|
73
|
+
context 'with tag' do
|
74
|
+
it 'pulls the image with tag name' do
|
75
|
+
expected_command = 'docker pull docker/image:tag'
|
76
|
+
expect_any_instance_of(SSHClient).to receive(:command).with(expected_command)
|
77
|
+
cli = described_class.new([], tag: 'tag')
|
78
|
+
cli.pull('test')
|
79
|
+
end
|
80
|
+
end
|
42
81
|
end
|
43
82
|
|
44
83
|
describe '#deploy' do
|
@@ -52,6 +91,19 @@ SHELL
|
|
52
91
|
cli = described_class.new
|
53
92
|
cli.deploy('test')
|
54
93
|
end
|
94
|
+
|
95
|
+
context 'with tag' do
|
96
|
+
it 'creates a container on server' do
|
97
|
+
expect_any_instance_of(SSHClient).to receive(:command).with('docker rm -f app_8080')
|
98
|
+
expected_command = <<-SHELL
|
99
|
+
docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p container.host:8080:80 docker/image:tag
|
100
|
+
SHELL
|
101
|
+
expected_command.chomp!
|
102
|
+
expect_any_instance_of(SSHClient).to receive(:command).with(expected_command)
|
103
|
+
cli = described_class.new([], tag: 'tag')
|
104
|
+
cli.deploy('test')
|
105
|
+
end
|
106
|
+
end
|
55
107
|
end
|
56
108
|
end
|
57
109
|
end
|
@@ -6,7 +6,8 @@ module Dockerploy
|
|
6
6
|
let(:config) { Configuration.new(env: 'test') }
|
7
7
|
let(:ssh_client) { double(command: double) }
|
8
8
|
let(:shell_client) { double(command: double) }
|
9
|
-
|
9
|
+
let(:options) { {} }
|
10
|
+
subject { described_class.new(config, options) }
|
10
11
|
|
11
12
|
before do
|
12
13
|
stub_const('Dockerploy::Configuration::DEFAULT_CONFIG_FILE', fixture_path)
|
@@ -30,6 +31,19 @@ docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p contai
|
|
30
31
|
subject.deploy
|
31
32
|
end
|
32
33
|
|
34
|
+
context 'with tag' do
|
35
|
+
let(:options) { {tag: 'tag'} }
|
36
|
+
|
37
|
+
it 'creates a container on server with tag' do
|
38
|
+
expected_command = <<-SHELL
|
39
|
+
docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p container.host:8080:80 docker/image:tag
|
40
|
+
SHELL
|
41
|
+
expected_command.chomp!
|
42
|
+
expect(ssh_client).to receive(:command).with(expected_command)
|
43
|
+
subject.deploy
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
33
47
|
context 'an environment file exists' do
|
34
48
|
let(:fixture_path) { 'spec/fixtures/config_with_env_file.yml' }
|
35
49
|
|
@@ -66,8 +80,44 @@ docker/image
|
|
66
80
|
|
67
81
|
it 'pushes a tags to the repository' do
|
68
82
|
timestamp = Time.now.strftime('%Y%m%dT%H%M')
|
69
|
-
|
70
|
-
|
83
|
+
expect(shell_client).to receive(:command).with("git tag test-#{timestamp} test-branch").and_return(true)
|
84
|
+
expect(shell_client).to receive(:command).with("git push origin test-#{timestamp}").and_return(true)
|
85
|
+
subject.deploy
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with hooks' do
|
90
|
+
let(:fixture_path) { 'spec/fixtures/config_with_hooks.yml' }
|
91
|
+
|
92
|
+
it 'runs hooks before/after deploying' do
|
93
|
+
expect(shell_client).to receive(:command).with('echo "Started deploying"').ordered
|
94
|
+
expect(ssh_client).to receive(:command).with('echo "Access to server"').ordered
|
95
|
+
expect(ssh_client).to receive(:command).with('docker rm -f app_8080').ordered
|
96
|
+
expected_command = <<-SHELL
|
97
|
+
docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p container.host:8080:80 docker/image
|
98
|
+
SHELL
|
99
|
+
expected_command.chomp!
|
100
|
+
expect(ssh_client).to receive(:command).with(expected_command).ordered
|
101
|
+
expect(shell_client).to receive(:command).with('echo "Finished deploying"').ordered
|
102
|
+
expect(ssh_client).to receive(:command).with('echo "Access to server again"').ordered
|
103
|
+
subject.deploy
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'with hooks in each environment' do
|
108
|
+
let(:fixture_path) { 'spec/fixtures/config_with_hooks_for_each_env.yml' }
|
109
|
+
|
110
|
+
it 'runs hooks before/after deploying' do
|
111
|
+
expect(shell_client).to receive(:command).with('echo "Started deploying on testing"').ordered
|
112
|
+
expect(ssh_client).to receive(:command).with('echo "Access to test server"').ordered
|
113
|
+
expect(ssh_client).to receive(:command).with('docker rm -f app_8080').ordered
|
114
|
+
expected_command = <<-SHELL
|
115
|
+
docker run -d --name app_8080 --hostname app -p container.host:1022:22 -p container.host:8080:80 docker/image
|
116
|
+
SHELL
|
117
|
+
expected_command.chomp!
|
118
|
+
expect(ssh_client).to receive(:command).with(expected_command).ordered
|
119
|
+
expect(shell_client).to receive(:command).with('echo "Finished deploying on testing"').ordered
|
120
|
+
expect(ssh_client).to receive(:command).with('echo "Access to test server again"').ordered
|
71
121
|
subject.deploy
|
72
122
|
end
|
73
123
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dockerploy
|
4
|
+
describe Image do
|
5
|
+
let(:fixture_path) { 'spec/fixtures/config.yml' }
|
6
|
+
before do
|
7
|
+
stub_const('Dockerploy::Configuration::DEFAULT_CONFIG_FILE', fixture_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
let(:config) { Configuration.new(env: 'test') }
|
11
|
+
let(:options) { {} }
|
12
|
+
|
13
|
+
describe '#build' do
|
14
|
+
subject { Image.new(config, options).build }
|
15
|
+
|
16
|
+
it 'runs docker build' do
|
17
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker build -t docker/image .'
|
18
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with tag' do
|
23
|
+
let(:options) { { tag: 'tag' } }
|
24
|
+
|
25
|
+
it 'runs docker build with tag' do
|
26
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker build -t docker/image:tag .'
|
27
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
28
|
+
subject
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#push' do
|
34
|
+
subject { Image.new(config, options).push }
|
35
|
+
|
36
|
+
it 'runs docker push' do
|
37
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker push docker/image'
|
38
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
39
|
+
subject
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with tag' do
|
43
|
+
let(:options) { { tag: 'tag' } }
|
44
|
+
|
45
|
+
it 'runs docker push with tag name' do
|
46
|
+
expected_command = 'env DOCKER_HOST=tcp://test.host:4243 docker push docker/image:tag'
|
47
|
+
expect_any_instance_of(ShellClient).to receive(:command).with(expected_command)
|
48
|
+
subject
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#pull' do
|
54
|
+
subject { Image.new(config, options).pull }
|
55
|
+
|
56
|
+
it 'pulls the image' do
|
57
|
+
expected_command = 'docker pull docker/image'
|
58
|
+
expect_any_instance_of(SSHClient).to receive(:command).with(expected_command)
|
59
|
+
subject
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'with tag' do
|
63
|
+
let(:options) { { tag: 'tag' } }
|
64
|
+
|
65
|
+
it 'runs docker pull with tag name' do
|
66
|
+
expected_command = 'docker pull docker/image:tag'
|
67
|
+
expect_any_instance_of(SSHClient).to receive(:command).with(expected_command)
|
68
|
+
subject
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Dockerploy
|
4
|
+
describe Template do
|
5
|
+
describe '.application_name' do
|
6
|
+
subject { described_class.application_name }
|
7
|
+
it 'returns application name from current working directory' do
|
8
|
+
expect(Dir).to receive(:getwd).and_return('/home/sunjin')
|
9
|
+
expect(subject).to eq('sunjin')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '.project_name' do
|
14
|
+
subject { described_class.project_name }
|
15
|
+
|
16
|
+
it 'returns project name from git repository name' do
|
17
|
+
client = double(output: 'git@github.com:org/project-name.git')
|
18
|
+
expect(ShellClient).to receive(:new).and_return(client)
|
19
|
+
expect(client).to receive(:command).with('git config --get remote.origin.url')
|
20
|
+
expect(subject).to eq('org/project-name')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.generate' do
|
25
|
+
subject { described_class.generate }
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow(Dir).to receive(:getwd).and_return('/home/application-name')
|
29
|
+
client = double(output: 'git@github.com:org/project-name.git')
|
30
|
+
allow(ShellClient).to receive(:new).and_return(client)
|
31
|
+
allow(client).to receive(:command).with('git config --get remote.origin.url')
|
32
|
+
ENV['USER'] = 'sunjin'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'generates template file' do
|
36
|
+
result = <<-YML
|
37
|
+
image_name: org/project-name
|
38
|
+
docker_username: sunjin
|
39
|
+
docker_host: tcp://:2375
|
40
|
+
application_name: application-name
|
41
|
+
development:
|
42
|
+
branch: master
|
43
|
+
tagging: true
|
44
|
+
volumes: []
|
45
|
+
servers:
|
46
|
+
- host: 0.0.0.0
|
47
|
+
username: sunjin
|
48
|
+
password:
|
49
|
+
port: 22
|
50
|
+
container:
|
51
|
+
host: 0.0.0.0
|
52
|
+
ssh_port: 22
|
53
|
+
http_port: 80
|
54
|
+
YML
|
55
|
+
|
56
|
+
expect(subject).to eq(result.chop)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dockerploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sunjin Lee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: net-ssh
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.6'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.6'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +94,20 @@ dependencies:
|
|
80
94
|
- - ~>
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: fakefs
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.6'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.6'
|
83
111
|
description: Deploy dockerized an application
|
84
112
|
email:
|
85
113
|
- styner32@gmail.com
|
@@ -97,6 +125,7 @@ files:
|
|
97
125
|
- README.md
|
98
126
|
- Rakefile
|
99
127
|
- bin/dockerploy
|
128
|
+
- c
|
100
129
|
- d.sh
|
101
130
|
- dockerploy.gemspec
|
102
131
|
- lib/dockerploy.rb
|
@@ -107,14 +136,20 @@ files:
|
|
107
136
|
- lib/dockerploy/image.rb
|
108
137
|
- lib/dockerploy/shell_client.rb
|
109
138
|
- lib/dockerploy/ssh_client.rb
|
139
|
+
- lib/dockerploy/template.rb
|
140
|
+
- lib/dockerploy/templates/config.yml.erb
|
110
141
|
- lib/dockerploy/version.rb
|
111
142
|
- spec/fixtures/config.yml
|
112
143
|
- spec/fixtures/config_with_env_file.yml
|
144
|
+
- spec/fixtures/config_with_hooks.yml
|
145
|
+
- spec/fixtures/config_with_hooks_for_each_env.yml
|
113
146
|
- spec/fixtures/config_with_tagging.yml
|
114
147
|
- spec/fixtures/config_with_volumes.yml
|
115
148
|
- spec/fixtures/test.yml
|
116
149
|
- spec/lib/dockerploy/cli_spec.rb
|
117
150
|
- spec/lib/dockerploy/deploy_spec.rb
|
151
|
+
- spec/lib/dockerploy/image_spec.rb
|
152
|
+
- spec/lib/dockerploy/template_spec.rb
|
118
153
|
- spec/spec_helper.rb
|
119
154
|
homepage: https://github.com/viki-org/dockerploy
|
120
155
|
licenses:
|
@@ -143,10 +178,14 @@ summary: Deploy dockerized an application
|
|
143
178
|
test_files:
|
144
179
|
- spec/fixtures/config.yml
|
145
180
|
- spec/fixtures/config_with_env_file.yml
|
181
|
+
- spec/fixtures/config_with_hooks.yml
|
182
|
+
- spec/fixtures/config_with_hooks_for_each_env.yml
|
146
183
|
- spec/fixtures/config_with_tagging.yml
|
147
184
|
- spec/fixtures/config_with_volumes.yml
|
148
185
|
- spec/fixtures/test.yml
|
149
186
|
- spec/lib/dockerploy/cli_spec.rb
|
150
187
|
- spec/lib/dockerploy/deploy_spec.rb
|
188
|
+
- spec/lib/dockerploy/image_spec.rb
|
189
|
+
- spec/lib/dockerploy/template_spec.rb
|
151
190
|
- spec/spec_helper.rb
|
152
191
|
has_rdoc:
|