dg 0.4
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 +7 -0
- data/.gitignore +2 -0
- data/Gemfile +14 -0
- data/README.md +10 -0
- data/bin/dg +23 -0
- data/dg.gemspec +16 -0
- data/lib/docker.rb +198 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bfa6c8117f605ab7db2805f81e17216c92987489
|
4
|
+
data.tar.gz: eaafc7f4ffb0ee78493790040d9bb5eec079b49b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b5830cb101398c6699904cd09bb3d8f87711561e6efd05a3422c2cc8c3a8de803a6ca4a999868444a1954bf9fe734bb11f761c410fa879bcf1eb49e17e840460
|
7
|
+
data.tar.gz: 6acfe0496cba3c12eec562fbbcc2fe59efc9dfe9f82229838ee2a539f4405c92a24028f043ab17d0b7c4526c67b8fb56530550d6772e12b5fc92a6cb9f8fedc6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
# Declare your gem's dependencies in docker_go_tasks.gemspec.
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
5
|
+
# development dependencies will be added by default to the :development group.
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
# Declare any dependencies that are still in development here instead of in
|
9
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
10
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
11
|
+
# your gem to rubygems.org.
|
12
|
+
|
13
|
+
# To use debugger
|
14
|
+
# gem 'debugger'
|
data/README.md
ADDED
data/bin/dg
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require File.expand_path('../../lib/docker', __FILE__)
|
4
|
+
|
5
|
+
COMMANDS = %w(
|
6
|
+
-h
|
7
|
+
build
|
8
|
+
debug
|
9
|
+
deploy
|
10
|
+
help
|
11
|
+
purge
|
12
|
+
push
|
13
|
+
run
|
14
|
+
test
|
15
|
+
)
|
16
|
+
|
17
|
+
if COMMANDS.include?(ARGV.first)
|
18
|
+
Docker.send(ARGV.first.tr('-','').to_sym)
|
19
|
+
exit 0
|
20
|
+
else
|
21
|
+
STDERR.puts "You must supply a command (#{COMMANDS.join(', ')})"
|
22
|
+
exit 1
|
23
|
+
end
|
data/dg.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
# Describe your gem and declare its dependencies:
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "dg"
|
6
|
+
s.version = '0.4'
|
7
|
+
s.authors = ["Michael Malet"]
|
8
|
+
s.email = ["michael@nervd.com"]
|
9
|
+
s.homepage = "https://github.com/shinyscorpion/dg"
|
10
|
+
s.license = "MIT"
|
11
|
+
s.summary = "Provides integration between Docker and GoCD."
|
12
|
+
s.description = File.read('README.md')
|
13
|
+
|
14
|
+
s.files = `git ls-files -z`.split("\x0")
|
15
|
+
s.executables = `git ls-files -z -- bin/*`.split("\x0").map{ |f| File.basename(f) }
|
16
|
+
end
|
data/lib/docker.rb
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
require 'pty'
|
2
|
+
require 'uri'
|
3
|
+
require 'net/http'
|
4
|
+
|
5
|
+
class Docker
|
6
|
+
MATERIAL_NAME = ENV['MATERIAL_NAME'] || 'BITBUCKET'
|
7
|
+
SUDO = !!ENV["GO_REVISION_#{MATERIAL_NAME}"]
|
8
|
+
BASEPATH = Dir.pwd
|
9
|
+
GIT_COMMIT = ENV['GO_REVISION_BITBUCKET'] || `git rev-parse HEAD`.strip
|
10
|
+
|
11
|
+
FIG_YML_PATH = "#{BASEPATH}/fig.yml"
|
12
|
+
FIG_GEN_PATH = "#{BASEPATH}/fig_gen.yml"
|
13
|
+
|
14
|
+
class << self
|
15
|
+
|
16
|
+
def build
|
17
|
+
build_docker_image_with_tag
|
18
|
+
end
|
19
|
+
|
20
|
+
def debug
|
21
|
+
generate_fig_yaml
|
22
|
+
debug_app
|
23
|
+
end
|
24
|
+
|
25
|
+
def purge
|
26
|
+
run_with_output("docker rm $(docker ps -a -q) && docker rmi $(docker images -q)")
|
27
|
+
end
|
28
|
+
|
29
|
+
def push
|
30
|
+
run_with_output("docker push #{git_image_name.tr(':',' ')}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def deploy
|
34
|
+
required_envs = %w(GO_HOST GO_USER GO_PWD)
|
35
|
+
unless required_envs.reduce{ |acc, e| acc && ENV[e] }
|
36
|
+
error!(
|
37
|
+
RuntimeError.new("Environment variables {#{required_envs.join(', ')}} must be set"),
|
38
|
+
'triggering pipeline'
|
39
|
+
)
|
40
|
+
end
|
41
|
+
deploy_stages.each do |deploy_stage|
|
42
|
+
schedule_pipeline(project_name, deploy_stage, git_image_name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def deploy_stages
|
47
|
+
candidates = Dir['deploy-to*']
|
48
|
+
if candidates.size == 1
|
49
|
+
script = candidates.first
|
50
|
+
if File.executable?(script)
|
51
|
+
branch = ENV['GIT_BRANCH'] ||
|
52
|
+
`git symbolic-ref --short -q HEAD`.strip
|
53
|
+
return `./#{script} #{branch}`.strip.split(',')
|
54
|
+
else
|
55
|
+
error!(
|
56
|
+
RuntimeError.new(
|
57
|
+
%(Deploy-to script: "#{script}" must be executable! (e.g. chmod +x #{script}))
|
58
|
+
),
|
59
|
+
"determining stage to deploy to"
|
60
|
+
)
|
61
|
+
end
|
62
|
+
else
|
63
|
+
error!(
|
64
|
+
RuntimeError.new(
|
65
|
+
"There must be a deploy-to* script " +
|
66
|
+
"(e.g. deploy-to.{rb|sh|js}): #{candidates.size} found"
|
67
|
+
),
|
68
|
+
"determining stage to deploy to"
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def run
|
74
|
+
generate_fig_yaml
|
75
|
+
run_app
|
76
|
+
end
|
77
|
+
|
78
|
+
def test
|
79
|
+
generate_fig_yaml
|
80
|
+
run_tests
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
def error!(e, step = "executing")
|
86
|
+
STDERR.puts "An error occurred while #{step}: #{e.message}"
|
87
|
+
exit 1
|
88
|
+
end
|
89
|
+
|
90
|
+
def run_with_output(command)
|
91
|
+
sudo_command = SUDO ? "sudo -E bash -c '#{command}'" : command
|
92
|
+
puts "Running `#{sudo_command}` in #{Dir.pwd}"
|
93
|
+
PTY.spawn(sudo_command) do |stdin, stdout, pid|
|
94
|
+
stdin.each { |line| print line } rescue Errno::EIO
|
95
|
+
Process.wait(pid)
|
96
|
+
end
|
97
|
+
status_code = $?.exitstatus
|
98
|
+
|
99
|
+
error!(RuntimeError.new("exit code was #{status_code}"), "executing #{command}") if status_code != 0
|
100
|
+
rescue PTY::ChildExited
|
101
|
+
puts "The child process exited!"
|
102
|
+
end
|
103
|
+
|
104
|
+
def fig_yml
|
105
|
+
@@fig_yml ||= File.read(FIG_YML_PATH)
|
106
|
+
rescue => e
|
107
|
+
error!(e, "reading fig.yml from #{FIG_YML_PATH}")
|
108
|
+
end
|
109
|
+
|
110
|
+
def project_name
|
111
|
+
@@project_name ||= ENV['GO_PIPELINE_NAME'] || image_name.split('/').last
|
112
|
+
end
|
113
|
+
|
114
|
+
# Infer the project name from the image specified in the fig.yml
|
115
|
+
def image_name
|
116
|
+
@@image_name ||= fig_yml.match(/\s+image: (.*)/)[1]
|
117
|
+
end
|
118
|
+
|
119
|
+
# Add the git commit hash to the image name
|
120
|
+
def git_image_name
|
121
|
+
@@git_image_name ||= "#{image_name}:#{GIT_COMMIT}"
|
122
|
+
end
|
123
|
+
|
124
|
+
def generate_fig_yaml
|
125
|
+
File.write(
|
126
|
+
FIG_GEN_PATH,
|
127
|
+
fig_yml.sub(image_name, git_image_name)
|
128
|
+
)
|
129
|
+
rescue => e
|
130
|
+
error!(e, "generating new fig.yml")
|
131
|
+
end
|
132
|
+
|
133
|
+
def build_docker_image_with_tag
|
134
|
+
run_with_output("docker build -t #{git_image_name} #{BASEPATH}")
|
135
|
+
rescue => e
|
136
|
+
error!(e, "building docker image")
|
137
|
+
end
|
138
|
+
|
139
|
+
def run_tests
|
140
|
+
run_with_output("fig -f #{FIG_GEN_PATH} run test")
|
141
|
+
rescue => e
|
142
|
+
error!(e, "running tests")
|
143
|
+
end
|
144
|
+
|
145
|
+
def run_app
|
146
|
+
run_with_output("fig -f #{FIG_GEN_PATH} up -d web")
|
147
|
+
end
|
148
|
+
|
149
|
+
def debug_app
|
150
|
+
puts "docker run -it --entrypoint=/bin/bash #{git_image_name}"
|
151
|
+
end
|
152
|
+
|
153
|
+
def schedule_pipeline(project_name, deploy_stage, image_id)
|
154
|
+
pipeline_name = "docker-#{project_name}-#{deploy_stage}"
|
155
|
+
|
156
|
+
uri = URI("https://#{ENV['GO_HOST']}/go/api/pipelines/#{pipeline_name}/schedule")
|
157
|
+
request = Net::HTTP::Post.new(uri.path)
|
158
|
+
request.basic_auth ENV['GO_USER'], ENV['GO_PWD']
|
159
|
+
request.set_form_data({ 'variables[IMAGE_ID]' => git_image_name.gsub('/','\/') })
|
160
|
+
|
161
|
+
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
162
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
163
|
+
http.ssl_version = :SSLv3
|
164
|
+
http.request(request)
|
165
|
+
end
|
166
|
+
|
167
|
+
if response.code.to_i == 202
|
168
|
+
puts response.body.strip
|
169
|
+
else
|
170
|
+
error!(
|
171
|
+
RuntimeError.new(
|
172
|
+
"response code was #{response.code}: #{response.body.strip}"
|
173
|
+
),
|
174
|
+
"scheduling pipeline"
|
175
|
+
)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def help
|
180
|
+
puts "Usage: dg COMMAND
|
181
|
+
|
182
|
+
A helper for building, testing, and running docker images via docker & fig.
|
183
|
+
|
184
|
+
Commands:
|
185
|
+
build Build an image based on your fig.yml (tags with the project's Git commit hash)
|
186
|
+
debug Debug a previously built image (!) THIS MUST BE RUN IN A SUBSHELL: `$(dim debug)`
|
187
|
+
deploy Trigger the GoCD pipeline for this project
|
188
|
+
help Display this help text
|
189
|
+
purge Remove ALL docker containers and images (not just for this project!)
|
190
|
+
push Push the image to your docker registry
|
191
|
+
run Run the image using your fig.yml's `web` config
|
192
|
+
test Run the image using your fig.yml's `test` config
|
193
|
+
".gsub(/^ {6}/,'')
|
194
|
+
end
|
195
|
+
alias_method :h, :help
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.4'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Malet
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
DockerGo (DG)
|
15
|
+
=============
|
16
|
+
|
17
|
+
Provides tasks for quickly building docker and running (via fig) docker images.
|
18
|
+
|
19
|
+
Prerequisites:
|
20
|
+
|
21
|
+
- Git for version control.
|
22
|
+
- Mac or GNU/Linux environment.
|
23
|
+
- docker and fig are installed
|
24
|
+
email:
|
25
|
+
- michael@nervd.com
|
26
|
+
executables:
|
27
|
+
- dg
|
28
|
+
extensions: []
|
29
|
+
extra_rdoc_files: []
|
30
|
+
files:
|
31
|
+
- ".gitignore"
|
32
|
+
- Gemfile
|
33
|
+
- README.md
|
34
|
+
- bin/dg
|
35
|
+
- dg.gemspec
|
36
|
+
- lib/docker.rb
|
37
|
+
homepage: https://github.com/shinyscorpion/dg
|
38
|
+
licenses:
|
39
|
+
- MIT
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
requirements: []
|
56
|
+
rubyforge_project:
|
57
|
+
rubygems_version: 2.4.3
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: Provides integration between Docker and GoCD.
|
61
|
+
test_files: []
|
62
|
+
has_rdoc:
|