quay 0.0.1
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/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +6 -0
- data/bin/quay +5 -0
- data/lib/quay.rb +9 -0
- data/lib/quay/cli.rb +98 -0
- data/lib/quay/config.rb +29 -0
- data/lib/quay/container.rb +60 -0
- data/lib/quay/env_lookup.rb +18 -0
- data/lib/quay/state.rb +42 -0
- data/lib/quay/templates/Quayfile +25 -0
- data/lib/quay/version.rb +3 -0
- data/quay.gemspec +27 -0
- data/spec/Quayfile +24 -0
- data/spec/quay/cli_spec.rb +131 -0
- data/spec/quay/config_spec.rb +37 -0
- data/spec/quay/state_spec.rb +37 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/cli_driver.rb +7 -0
- metadata +155 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Braintree
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# quay
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'quay
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install quay
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/pitluga/quay/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/quay
ADDED
data/lib/quay.rb
ADDED
data/lib/quay/cli.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
module Quay
|
2
|
+
class CLI < Thor
|
3
|
+
include Thor::Actions
|
4
|
+
|
5
|
+
class_option :config, type: :string
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def self.exit_on_failure?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "version", "Prints version and exits"
|
13
|
+
def version
|
14
|
+
puts "Quay Version #{VERSION}"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "init [dir]", "create a new Quayfile"
|
18
|
+
def init(dir=nil)
|
19
|
+
target = dir ? File.join(dir, 'Quayfile') : 'Quayfile'
|
20
|
+
copy_file('Quayfile', target)
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "tasks", "list available tasks"
|
24
|
+
def tasks
|
25
|
+
config = Quay::Config.eval_from_path(options[:config])
|
26
|
+
config.tasks.each do |name, _|
|
27
|
+
puts name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "run TASK", "runs the given task"
|
32
|
+
def run_task(name)
|
33
|
+
config = Quay::Config.eval_from_path(options[:config])
|
34
|
+
task = config.tasks[name]
|
35
|
+
raise Thor::Error.new("unknown task #{name.inspect}") if task.nil?
|
36
|
+
|
37
|
+
Array(task[:depends]).each do |dependency|
|
38
|
+
puts "starting #{dependency}"
|
39
|
+
Container.start(dependency, config.services[dependency])
|
40
|
+
end
|
41
|
+
|
42
|
+
container = Container.start(name, task)
|
43
|
+
|
44
|
+
puts "Started #{name} #{container.id[0...12]}"
|
45
|
+
container.attach do |stream, chunk|
|
46
|
+
puts "#{stream}: #{chunk}"
|
47
|
+
end
|
48
|
+
|
49
|
+
Array(task[:depends]).each do |dependency|
|
50
|
+
puts "stopping #{dependency}"
|
51
|
+
Container.stop(dependency, config.services[dependency])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "services", "lists available services"
|
56
|
+
def services
|
57
|
+
config = Quay::Config.eval_from_path(options[:config])
|
58
|
+
state = Quay::State.new
|
59
|
+
lines = config.services.keys.sort.map do |service|
|
60
|
+
id = state.containers[service]
|
61
|
+
if id
|
62
|
+
container = Docker::Container.get(id)
|
63
|
+
[service, container.id[0...12]]
|
64
|
+
else
|
65
|
+
[service, nil]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
puts "DEPENDENCY CONTAINER_ID"
|
69
|
+
puts lines.map{|col| col.join(" ") }.join("\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "start SERVICE", "start a SERVICE"
|
73
|
+
def start(name)
|
74
|
+
config = Quay::Config.eval_from_path(options[:config])
|
75
|
+
service = config.services[name]
|
76
|
+
|
77
|
+
raise Thor::Error.new("unknown service #{name.inspect}") if service.nil?
|
78
|
+
|
79
|
+
container = Container.start(name, service)
|
80
|
+
puts "Started #{name} #{container.id[0...12]}"
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "stop SERVICE", "stop a SERVICE"
|
84
|
+
def stop(name)
|
85
|
+
config = Quay::Config.eval_from_path(options[:config])
|
86
|
+
service = config.services[name]
|
87
|
+
|
88
|
+
raise Thor::Error.new("unknown service #{name.inspect}") if service.nil?
|
89
|
+
|
90
|
+
container = Container.stop(name, service)
|
91
|
+
if container.nil?
|
92
|
+
puts "Skipping #{name}"
|
93
|
+
else
|
94
|
+
puts "Stopped #{name} #{container.id[0...12]}"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/quay/config.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Quay
|
2
|
+
class Config
|
3
|
+
def self.eval_from_path(path)
|
4
|
+
path ||= "Quayfile"
|
5
|
+
evaluate(File.read(path))
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.evaluate(contents)
|
9
|
+
config = self.new
|
10
|
+
config.instance_eval(contents)
|
11
|
+
config
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :services, :tasks
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@services = {}
|
18
|
+
@tasks = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def service(name, options={})
|
22
|
+
@services[name] = options
|
23
|
+
end
|
24
|
+
|
25
|
+
def task(name, options={})
|
26
|
+
@tasks[name] = options
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Quay
|
2
|
+
class Container
|
3
|
+
def self.ensure_image(image)
|
4
|
+
Docker::Image.get(image)
|
5
|
+
rescue Docker::Error::NotFoundError
|
6
|
+
Docker::Image.create('fromImage' => image)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.start(name, container_config)
|
10
|
+
state = Quay::State.new
|
11
|
+
env_lookup = Quay::EnvLookup.new(state)
|
12
|
+
|
13
|
+
env = container_config.fetch(:env, {}).map do |k,v|
|
14
|
+
if v =~ /^\$/
|
15
|
+
value = env_lookup.get(v)
|
16
|
+
"#{k}=#{value}"
|
17
|
+
else
|
18
|
+
"#{k}=#{v}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
volumes = container_config.fetch(:volumes, []).map do |host, container, mode|
|
23
|
+
[container, {}]
|
24
|
+
end
|
25
|
+
|
26
|
+
binds = container_config.fetch(:volumes, []).map do |*args|
|
27
|
+
args.join(":")
|
28
|
+
end
|
29
|
+
|
30
|
+
opts = {
|
31
|
+
'Image' => container_config[:image],
|
32
|
+
'Cmd' => container_config[:cmd],
|
33
|
+
'WorkingDir' => container_config[:working_dir],
|
34
|
+
'Volumes' => Hash[volumes],
|
35
|
+
'Env' => env,
|
36
|
+
}
|
37
|
+
ensure_image(container_config[:image])
|
38
|
+
container = Docker::Container.create(opts)
|
39
|
+
container.start('Binds' => binds)
|
40
|
+
|
41
|
+
state.save_container(name, container.id)
|
42
|
+
|
43
|
+
container
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.stop(name, dependency)
|
47
|
+
state = Quay::State.new
|
48
|
+
id = state.containers[name]
|
49
|
+
|
50
|
+
return if id.nil?
|
51
|
+
|
52
|
+
container = Docker::Container.get(id)
|
53
|
+
container.stop
|
54
|
+
|
55
|
+
state.remove_container(name)
|
56
|
+
|
57
|
+
container
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Quay
|
2
|
+
class EnvLookup
|
3
|
+
def initialize(state)
|
4
|
+
@state = state
|
5
|
+
end
|
6
|
+
|
7
|
+
def get(value)
|
8
|
+
name, path = value.match(/\$(\w+):(.*)/).captures
|
9
|
+
id = @state.containers[name]
|
10
|
+
container = Docker::Container.get(id)
|
11
|
+
json = container.json
|
12
|
+
|
13
|
+
path.split("/").reduce(json) do |current, key|
|
14
|
+
current[key]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/quay/state.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Quay
|
2
|
+
class State
|
3
|
+
def initialize(file = ".quay.yml")
|
4
|
+
@file = file
|
5
|
+
end
|
6
|
+
|
7
|
+
def containers
|
8
|
+
_state["containers"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def save_container(name, id)
|
12
|
+
containers[name] = id
|
13
|
+
_save
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_container(name)
|
17
|
+
containers.delete(name)
|
18
|
+
_save
|
19
|
+
end
|
20
|
+
|
21
|
+
def _state
|
22
|
+
_load if @state.nil?
|
23
|
+
@state
|
24
|
+
end
|
25
|
+
|
26
|
+
def _save
|
27
|
+
File.open(@file, "w") do |file|
|
28
|
+
YAML.dump(@state, file)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def _load
|
33
|
+
if File.exists?(@file)
|
34
|
+
@state = YAML.load_file(@file)
|
35
|
+
else
|
36
|
+
@state = {}
|
37
|
+
end
|
38
|
+
@state.default_proc = proc { |hash, key| hash[key] = {} }
|
39
|
+
@state
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# vim: ft=ruby:
|
2
|
+
|
3
|
+
service 'redis', image: 'orchardup/redis'
|
4
|
+
service 'memcache', image: 'jacksoncage/memcache'
|
5
|
+
|
6
|
+
task 'sayhi', image: 'ubuntu', cmd: ['/bin/echo', 'hello world']
|
7
|
+
|
8
|
+
task 'redis_info',
|
9
|
+
depends: 'redis',
|
10
|
+
image: 'orchardup/redis',
|
11
|
+
env: {
|
12
|
+
'REDIS_HOST' => '$redis:NetworkSettings/IPAddress',
|
13
|
+
'REDIS_PORT' => '6379'
|
14
|
+
},
|
15
|
+
cmd: ['/bin/bash', '-c', '/usr/bin/redis-cli -h $REDIS_HOST -p $REDIS_PORT info']
|
16
|
+
|
17
|
+
project_root = File.expand_path(File.dirname(__FILE__))
|
18
|
+
|
19
|
+
task 'ls_volume',
|
20
|
+
image: 'ubuntu',
|
21
|
+
volumes: [
|
22
|
+
[project_root, '/mnt', 'ro']
|
23
|
+
],
|
24
|
+
working_dir: '/mnt',
|
25
|
+
cmd: ['/bin/ls']
|
data/lib/quay/version.rb
ADDED
data/quay.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'quay/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "quay"
|
8
|
+
spec.version = Quay::VERSION
|
9
|
+
spec.authors = ["Tony Pitluga"]
|
10
|
+
spec.email = ["tony.pitluga@gmail.com"]
|
11
|
+
spec.summary = %q{automating docker dev environments}
|
12
|
+
spec.description = %q{automation for docker dev environments}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "thor", "~> 0.18.1"
|
22
|
+
spec.add_dependency "docker-api", "~> 1.7.6"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.1.1"
|
26
|
+
spec.add_development_dependency "rspec", "~> 2.14.1"
|
27
|
+
end
|
data/spec/Quayfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# vim: ft=ruby:
|
2
|
+
service 'redis', image: 'orchardup/redis'
|
3
|
+
service 'memcache', image: 'jacksoncage/memcache'
|
4
|
+
|
5
|
+
task 'sayhi', image: 'ubuntu', cmd: ['/bin/echo', 'hello world']
|
6
|
+
|
7
|
+
task 'redis_info',
|
8
|
+
depends: 'redis',
|
9
|
+
image: 'orchardup/redis',
|
10
|
+
env: {
|
11
|
+
'REDIS_HOST' => '$redis:NetworkSettings/IPAddress',
|
12
|
+
'REDIS_PORT' => '6379'
|
13
|
+
},
|
14
|
+
cmd: ['/bin/bash', '-c', '/usr/bin/redis-cli -h $REDIS_HOST -p $REDIS_PORT info']
|
15
|
+
|
16
|
+
project_root = File.expand_path(File.dirname(__FILE__))
|
17
|
+
|
18
|
+
task 'ls_volume',
|
19
|
+
image: 'ubuntu',
|
20
|
+
volumes: [
|
21
|
+
[project_root, '/mnt', 'ro']
|
22
|
+
],
|
23
|
+
working_dir: '/mnt',
|
24
|
+
cmd: ['/bin/ls']
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Quay::CLI, type: :cli do
|
4
|
+
describe "default config" do
|
5
|
+
it "looks in the working directory" do
|
6
|
+
Dir.chdir(File.dirname(EXAMPLE_FILE)) do
|
7
|
+
output = quay('services')
|
8
|
+
output.should match(/DEPENDENCY CONTAINER_ID/)
|
9
|
+
output.should match(/^memcache *$/)
|
10
|
+
output.should match(/^redis *$/)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "version" do
|
16
|
+
it "prints the version and exits" do
|
17
|
+
quay("version").should match(/Quay Version [\d\.]+/)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "init" do
|
22
|
+
it "generates a Quayfile in the current dir" do
|
23
|
+
Dir.mktmpdir do |dir|
|
24
|
+
Dir.chdir(dir) do
|
25
|
+
File.exist?("Quayfile").should == false
|
26
|
+
quay("init")
|
27
|
+
File.exist?("Quayfile").should == true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "generates a Quayfile in the given dir" do
|
33
|
+
Dir.mktmpdir do |dir|
|
34
|
+
File.exist?(File.join(dir, "Quayfile")).should == false
|
35
|
+
quay("init #{dir}")
|
36
|
+
File.exist?(File.join(dir, "Quayfile")).should == true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "services" do
|
42
|
+
before(:each) do
|
43
|
+
quay("stop redis --config #{EXAMPLE_FILE}")
|
44
|
+
quay("stop memcache --config #{EXAMPLE_FILE}")
|
45
|
+
end
|
46
|
+
|
47
|
+
after(:each) do
|
48
|
+
quay("stop redis --config #{EXAMPLE_FILE}")
|
49
|
+
quay("stop memcache --config #{EXAMPLE_FILE}")
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "start" do
|
53
|
+
it "starts the given dependency" do
|
54
|
+
quay("start redis --config #{EXAMPLE_FILE}").should match(/Started redis/)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns an error if the name is unknown" do
|
58
|
+
quay("start unknown --config #{EXAMPLE_FILE}").should match(/unknown service "unknown"/)
|
59
|
+
$?.exitstatus.should == 1
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "stop" do
|
64
|
+
it "stop the given dependency" do
|
65
|
+
quay("start redis --config #{EXAMPLE_FILE}").should match(/Started redis/)
|
66
|
+
quay("stop redis --config #{EXAMPLE_FILE}").should match(/Stopped redis/)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "skips dependencies that are not running" do
|
70
|
+
quay("stop redis --config #{EXAMPLE_FILE}").should match(/Skipping redis/)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "returns an error if the name is unknown" do
|
74
|
+
quay("stop unknown --config #{EXAMPLE_FILE}").should match(/unknown service "unknown"/)
|
75
|
+
$?.exitstatus.should == 1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "list" do
|
80
|
+
it "show the status of all dependencies" do
|
81
|
+
output = quay("services --config #{EXAMPLE_FILE}")
|
82
|
+
output.should match(/DEPENDENCY CONTAINER_ID/)
|
83
|
+
output.should match(/^memcache *$/)
|
84
|
+
output.should match(/^redis *$/)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "shows the container id of a running container" do
|
88
|
+
quay("start redis --config #{EXAMPLE_FILE}").should match(/Started redis/)
|
89
|
+
|
90
|
+
output = quay("services --config #{EXAMPLE_FILE}")
|
91
|
+
output.should match(/DEPENDENCY CONTAINER_ID/)
|
92
|
+
output.should match(/^redis [a-z0-9]{12}*$/)
|
93
|
+
output.should match(/^memcache *$/)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe 'list' do
|
99
|
+
it "lists the available tasks" do
|
100
|
+
output = quay("tasks --config #{EXAMPLE_FILE}")
|
101
|
+
output.should match(/sayhi/)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe 'run' do
|
106
|
+
it "runs the specified task" do
|
107
|
+
output = quay("run sayhi --config #{EXAMPLE_FILE}")
|
108
|
+
output.should match(/hello world/)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "can run a task with a dependency" do
|
112
|
+
output = quay("run redis_info --config #{EXAMPLE_FILE}")
|
113
|
+
output.should match(/used_memory/)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "returns an error if the name is unknown" do
|
117
|
+
quay("run unknown --config #{EXAMPLE_FILE}").should match(/unknown task "unknown"/)
|
118
|
+
$?.exitstatus.should == 1
|
119
|
+
end
|
120
|
+
|
121
|
+
it "can mount a volume" do
|
122
|
+
quay("run ls_volume --config #{EXAMPLE_FILE}").should match(/quay.gemspec/)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "will pull an image that doesn't exist" do
|
126
|
+
images = Docker::Image.search('ubuntu')
|
127
|
+
images.each(&:remove)
|
128
|
+
quay("run sayhi --config #{EXAMPLE_FILE}").should match(/hello world/)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Quay::Config do
|
4
|
+
describe ".evaluate" do
|
5
|
+
context "service" do
|
6
|
+
it "is an empty hash by default" do
|
7
|
+
config = Quay::Config.evaluate("")
|
8
|
+
config.services.should == {}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "adds a dependency" do
|
12
|
+
config = Quay::Config.evaluate <<-EOS
|
13
|
+
service "foo", image: "bar"
|
14
|
+
EOS
|
15
|
+
|
16
|
+
config.services.has_key?("foo").should be_true
|
17
|
+
config.services["foo"].should == { image: "bar" }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "task" do
|
22
|
+
it "is an empty hash by default" do
|
23
|
+
config = Quay::Config.evaluate("")
|
24
|
+
config.tasks.should == {}
|
25
|
+
end
|
26
|
+
|
27
|
+
it "defines a task" do
|
28
|
+
config = Quay::Config.evaluate <<-EOS
|
29
|
+
task "sayhi", image: "bar"
|
30
|
+
EOS
|
31
|
+
|
32
|
+
config.tasks.has_key?("sayhi").should be_true
|
33
|
+
config.tasks["sayhi"].should == { image: "bar" }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Quay::State do
|
4
|
+
around(:each) do |spec|
|
5
|
+
tmpfile = Tempfile.new('quay')
|
6
|
+
@file = tmpfile.path
|
7
|
+
tmpfile.delete
|
8
|
+
spec.run
|
9
|
+
tmpfile.delete
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "containers" do
|
13
|
+
it "is initially an empty hash" do
|
14
|
+
state = Quay::State.new(@file)
|
15
|
+
state.containers.should == {}
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can save a container for later" do
|
19
|
+
state = Quay::State.new(@file)
|
20
|
+
state.save_container("foo", "bar")
|
21
|
+
|
22
|
+
state = Quay::State.new(@file)
|
23
|
+
state.containers.should == {"foo" => "bar"}
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can remove a container" do
|
27
|
+
state = Quay::State.new(@file)
|
28
|
+
state.save_container("foo", "bar")
|
29
|
+
state.containers.should == {"foo" => "bar"}
|
30
|
+
state.remove_container("foo")
|
31
|
+
|
32
|
+
state = Quay::State.new(@file)
|
33
|
+
state.containers.should == {}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
2
|
+
require 'quay'
|
3
|
+
require 'support/cli_driver'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
7
|
+
config.run_all_when_everything_filtered = true
|
8
|
+
config.filter_run :focus
|
9
|
+
config.order = 'random'
|
10
|
+
|
11
|
+
config.include CLIDriver, type: :cli
|
12
|
+
end
|
13
|
+
|
14
|
+
EXAMPLE_FILE = File.expand_path('../Quayfile', __FILE__)
|
metadata
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: quay
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tony Pitluga
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: thor
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.18.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.18.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: docker-api
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.7.6
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.7.6
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.5'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.5'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 10.1.1
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 10.1.1
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 2.14.1
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 2.14.1
|
94
|
+
description: automation for docker dev environments
|
95
|
+
email:
|
96
|
+
- tony.pitluga@gmail.com
|
97
|
+
executables:
|
98
|
+
- quay
|
99
|
+
extensions: []
|
100
|
+
extra_rdoc_files: []
|
101
|
+
files:
|
102
|
+
- .gitignore
|
103
|
+
- .rspec
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- bin/quay
|
109
|
+
- lib/quay.rb
|
110
|
+
- lib/quay/cli.rb
|
111
|
+
- lib/quay/config.rb
|
112
|
+
- lib/quay/container.rb
|
113
|
+
- lib/quay/env_lookup.rb
|
114
|
+
- lib/quay/state.rb
|
115
|
+
- lib/quay/templates/Quayfile
|
116
|
+
- lib/quay/version.rb
|
117
|
+
- quay.gemspec
|
118
|
+
- spec/Quayfile
|
119
|
+
- spec/quay/cli_spec.rb
|
120
|
+
- spec/quay/config_spec.rb
|
121
|
+
- spec/quay/state_spec.rb
|
122
|
+
- spec/spec_helper.rb
|
123
|
+
- spec/support/cli_driver.rb
|
124
|
+
homepage: ''
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
requirements: []
|
144
|
+
rubyforge_project:
|
145
|
+
rubygems_version: 1.8.23
|
146
|
+
signing_key:
|
147
|
+
specification_version: 3
|
148
|
+
summary: automating docker dev environments
|
149
|
+
test_files:
|
150
|
+
- spec/Quayfile
|
151
|
+
- spec/quay/cli_spec.rb
|
152
|
+
- spec/quay/config_spec.rb
|
153
|
+
- spec/quay/state_spec.rb
|
154
|
+
- spec/spec_helper.rb
|
155
|
+
- spec/support/cli_driver.rb
|