fig-lock 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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +47 -0
- data/Rakefile +6 -0
- data/bin/fig-lock +4 -0
- data/fig-lock.gemspec +28 -0
- data/lib/fig/lock.rb +116 -0
- data/lib/fig/lock/cli.rb +42 -0
- data/lib/fig/lock/log.rb +18 -0
- data/lib/fig/lock/version.rb +5 -0
- data/spec/fig/lock_spec.rb +100 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c3ee68dd9533f30826adbc4476c751c7b2b2e94f
|
4
|
+
data.tar.gz: 5face655d47fc8a3bc173bcb08f73f3c1c6b656f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cd3ff4c1df4b0535ef36c7fb356d1f7466d0f699fecf93de503abf252a60f3f9b76b7a93ab20147e247b9384e25e25734c753205be43fef92619119b5460bb04
|
7
|
+
data.tar.gz: 8f174825d487d3c781887e329f568f568f3a4f5c8599b702a855720cdf87c1124ac9b69f54972a6ec99f6201b153fcdd2e49c43b65240300ee1f91c941836174
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 TODO: Write your name
|
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,47 @@
|
|
1
|
+
# Fig::Lock
|
2
|
+
|
3
|
+
Generates fig.lock files based on fig.yml files.
|
4
|
+
Gets the latest versions of all images defined in a
|
5
|
+
fig.yml file, rewrites them to include the specific tags
|
6
|
+
of those versions, generates a fig.lock file.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'fig-lock'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install fig-lock
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### Install
|
25
|
+
The *install* command uses docker to retrieve all images
|
26
|
+
defined in fig.lock. If no fig.lock file exists, one will
|
27
|
+
be generated by invoking the *update* command.
|
28
|
+
```
|
29
|
+
fig-lock install </path/to/fig.yml>
|
30
|
+
```
|
31
|
+
|
32
|
+
### Update
|
33
|
+
The *update* command uses docker to retrieve the latest versions
|
34
|
+
of all images defined in the fig.yml file and generates/updates
|
35
|
+
a corresponding fig.lock file in the same directory as the fig.yml file,
|
36
|
+
which uses specific version tags for these images.
|
37
|
+
```
|
38
|
+
fig-lock update </path/to/fig.yml>
|
39
|
+
```
|
40
|
+
|
41
|
+
## Contributing
|
42
|
+
|
43
|
+
1. Fork it ( http://github.com/<my-github-username>/fig-lock/fork )
|
44
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
45
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
46
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
47
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/fig-lock
ADDED
data/fig-lock.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'fig/lock/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "fig-lock"
|
8
|
+
spec.version = Fig::Lock::VERSION
|
9
|
+
spec.authors = ["Michael Shea"]
|
10
|
+
spec.email = ["michael.shea@salesforce.com"]
|
11
|
+
spec.summary = %q{Generates fig.lock files from fig.yml files}
|
12
|
+
spec.description = %q{Generates fig.lock files from fig.yml files}
|
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 "slop"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "simplecov"
|
27
|
+
|
28
|
+
end
|
data/lib/fig/lock.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fig/lock/log'
|
3
|
+
require 'fig/lock/version'
|
4
|
+
|
5
|
+
module Fig
|
6
|
+
class Lock
|
7
|
+
class << self
|
8
|
+
def install(opts={})
|
9
|
+
Lock.new(opts).install
|
10
|
+
end
|
11
|
+
|
12
|
+
def update(opts={})
|
13
|
+
Lock.new(opts).update
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Fig
|
20
|
+
class Lock
|
21
|
+
include Fig::Lock::Log
|
22
|
+
|
23
|
+
attr_reader :lock_file, :file
|
24
|
+
|
25
|
+
def initialize(opts)
|
26
|
+
opts = merge_opts(opts)
|
27
|
+
@file = opts[:file]
|
28
|
+
@lock_file = lock_file_name(file)
|
29
|
+
|
30
|
+
fail "File #{file} does not exist" unless File.exists?(file)
|
31
|
+
fail "File #{file} is a directory" if File.directory?(file)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Install images from a lock file on the local system
|
35
|
+
def install
|
36
|
+
if File.exists?(lock_file)
|
37
|
+
log.info "Lock file #{lock_file} found."
|
38
|
+
fetch_images(YAML.load(File.read(lock_file)))
|
39
|
+
else
|
40
|
+
log.info "No lock file found."
|
41
|
+
update
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Update an existing lock file, or create if none exists
|
46
|
+
def update
|
47
|
+
log.info "Generating lock file for #{file} ..."
|
48
|
+
hash = YAML.load(File.read(file))
|
49
|
+
|
50
|
+
fetch_images(hash)
|
51
|
+
select_latest(hash)
|
52
|
+
|
53
|
+
File.write(lock_file, hash.to_yaml)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Construct the name of the lock file from the name of the fig file
|
59
|
+
def lock_file_name(file)
|
60
|
+
index = file.rindex('.')
|
61
|
+
raise "Input file #{file} has no file extension" unless index
|
62
|
+
file[0, index] << '.lock'
|
63
|
+
end
|
64
|
+
|
65
|
+
# Select the latest version for images in the fig hash. Updates the input hash.
|
66
|
+
def select_latest(hash)
|
67
|
+
log.info "Selecting latest tags:"
|
68
|
+
hash.each do |k,v|
|
69
|
+
image = v['image']
|
70
|
+
unless image.nil?
|
71
|
+
output = `sudo docker images #{image}`
|
72
|
+
fail "Unable to list image: #{image}.\n\tExit code:#{$?.exitstatus}\n\tOutput:#{output}" unless $?.exitstatus.zero?
|
73
|
+
tag = output.split("\n")[1].split(' ')[1]
|
74
|
+
tagged_image = "#{image}:#{tag}"
|
75
|
+
log.info "Resolved: #{tagged_image}"
|
76
|
+
v['image'] = tagged_image
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Fetch all images from the fig hash.
|
82
|
+
def fetch_images(hash)
|
83
|
+
log.info "Fetching images:"
|
84
|
+
hash.each do |k,v|
|
85
|
+
image = v['image']
|
86
|
+
if image
|
87
|
+
log.info "Fetching #{image} ..."
|
88
|
+
system "sudo docker pull #{image}"
|
89
|
+
fail "Unable to fetch image: #{image}.\n\tExit code:#{$?.exitstatus}" unless $?.exitstatus.zero?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
log.info "Done fetching images."
|
93
|
+
end
|
94
|
+
|
95
|
+
def merge_opts(opts)
|
96
|
+
Defaults.opts.merge(opts).tap do |hash|
|
97
|
+
fail("file must be specified") unless hash[:file]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Default values for parameters
|
103
|
+
class Defaults
|
104
|
+
class << self
|
105
|
+
def opts
|
106
|
+
{
|
107
|
+
file: file
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
def file
|
112
|
+
ENV.fetch 'FIG_FILE', File.join(__dir__, 'fig.yml')
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/fig/lock/cli.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'slop'
|
2
|
+
require 'fig/lock'
|
3
|
+
require 'fig/lock/log'
|
4
|
+
|
5
|
+
def cmd_args(command, args)
|
6
|
+
if args.empty?
|
7
|
+
{}
|
8
|
+
elsif args.size == 1
|
9
|
+
{file: args[0]}
|
10
|
+
else
|
11
|
+
fail "Usage: fig-lock #{command} <file>"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Execute a block.
|
16
|
+
def execute(&block)
|
17
|
+
run do |opts, args|
|
18
|
+
begin
|
19
|
+
yield(opts, args)
|
20
|
+
rescue StandardError => bang
|
21
|
+
if ENV['DEBUG']
|
22
|
+
Fig::Lock::Log.log.fatal bang
|
23
|
+
else
|
24
|
+
Fig::Lock::Log.log.fatal bang.message
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
opts = Slop.parse do
|
31
|
+
command 'install' do
|
32
|
+
execute do |opts, args|
|
33
|
+
Fig::Lock.install cmd_args('install', args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
command 'update' do
|
38
|
+
execute do |opts, args|
|
39
|
+
Fig::Lock.update cmd_args('update', args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/fig/lock/log.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'fig/lock/version'
|
3
|
+
|
4
|
+
module Fig::Lock::Log
|
5
|
+
def log
|
6
|
+
Fig::Lock::Log.log
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Fig::Lock::Log
|
11
|
+
class << self
|
12
|
+
def log
|
13
|
+
@log ||= Logger.new(STDOUT).tap do |l|
|
14
|
+
l.level = Logger.const_get(ENV.fetch('LOG_LEVEL', 'INFO').upcase)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
$:.unshift(File.join(__dir__, '..', '..', 'lib'))
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
require 'simplecov'
|
5
|
+
SimpleCov.add_filter 'vendor'
|
6
|
+
SimpleCov.add_filter 'spec'
|
7
|
+
SimpleCov.start
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
require 'fig/lock'
|
12
|
+
|
13
|
+
module Fig
|
14
|
+
|
15
|
+
describe Lock do
|
16
|
+
|
17
|
+
before :each do
|
18
|
+
ENV['LOG_LEVEL'] = 'FATAL'
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'class operations' do
|
22
|
+
it 'should install' do
|
23
|
+
expect(Lock).to receive(:new).with({}){
|
24
|
+
double('lock').tap do |lock|
|
25
|
+
expect(lock).to receive(:install)
|
26
|
+
end
|
27
|
+
}
|
28
|
+
Lock.install({})
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should update' do
|
32
|
+
expect(Lock).to receive(:new).with({}){
|
33
|
+
double('lock').tap do |lock|
|
34
|
+
expect(lock).to receive(:update)
|
35
|
+
end
|
36
|
+
}
|
37
|
+
Lock.update({})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'instance operations' do
|
42
|
+
|
43
|
+
before :each do
|
44
|
+
allow(File).to receive(:exists?).with('fig.yml'){true}
|
45
|
+
allow(File).to receive(:directory?).with('fig.yml'){false}
|
46
|
+
allow(File).to receive(:read).with('fig.yml'){yaml}
|
47
|
+
allow(File).to receive(:read).with('fig.lock'){yaml}
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should install' do
|
51
|
+
lock = Fig::Lock.new(registry: 'some.docker.com', file:'fig.yml')
|
52
|
+
allow(File).to receive(:exists?).with('fig.lock'){true}
|
53
|
+
|
54
|
+
expect(lock).to receive(:system).with('sudo docker pull some.docker.com/atlas/api'){true}
|
55
|
+
|
56
|
+
lock.install
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should update if no fig.lock exists' do
|
60
|
+
lock = Fig::Lock.new(registry: 'some.docker.com', file:'fig.yml')
|
61
|
+
allow(File).to receive(:exists?).with('fig.lock'){false}
|
62
|
+
expect(lock).to receive(:update)
|
63
|
+
lock.install
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should update' do
|
67
|
+
lock = Fig::Lock.new(registry: 'some.docker.com', file:'fig.yml')
|
68
|
+
|
69
|
+
expect(lock).to receive(:system).with('sudo docker pull some.docker.com/atlas/api'){true}
|
70
|
+
expect(lock).to receive(:`).with('sudo docker images some.docker.com/atlas/api'){docker_image_output}
|
71
|
+
expect(File).to receive(:write).with('fig.lock', expected_fig_lock)
|
72
|
+
|
73
|
+
lock.update
|
74
|
+
end
|
75
|
+
|
76
|
+
def expected_fig_lock
|
77
|
+
<<-eos
|
78
|
+
---
|
79
|
+
web:
|
80
|
+
image: some.docker.com/atlas/api:20140611142604
|
81
|
+
eos
|
82
|
+
end
|
83
|
+
|
84
|
+
def docker_image_output
|
85
|
+
<<-eos
|
86
|
+
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
87
|
+
some.docker.com/atlas/api 20140611142604 784dfb100eb0 4 hours ago 376.4 MB
|
88
|
+
eos
|
89
|
+
end
|
90
|
+
|
91
|
+
def yaml
|
92
|
+
<<-eos
|
93
|
+
---
|
94
|
+
web:
|
95
|
+
image: some.docker.com/atlas/api
|
96
|
+
eos
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fig-lock
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Shea
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: slop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Generates fig.lock files from fig.yml files
|
84
|
+
email:
|
85
|
+
- michael.shea@salesforce.com
|
86
|
+
executables:
|
87
|
+
- fig-lock
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/fig-lock
|
97
|
+
- fig-lock.gemspec
|
98
|
+
- lib/fig/lock.rb
|
99
|
+
- lib/fig/lock/cli.rb
|
100
|
+
- lib/fig/lock/log.rb
|
101
|
+
- lib/fig/lock/version.rb
|
102
|
+
- spec/fig/lock_spec.rb
|
103
|
+
homepage: ''
|
104
|
+
licenses:
|
105
|
+
- MIT
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.2.2
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Generates fig.lock files from fig.yml files
|
127
|
+
test_files:
|
128
|
+
- spec/fig/lock_spec.rb
|