elders 0.0.0
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/.travis.yml +11 -0
- data/Dockerfile +17 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +40 -0
- data/README.md +9 -0
- data/elders.gemspec +24 -0
- data/lib/elders/stack.rb +69 -0
- data/lib/elders/task.rb +106 -0
- data/lib/elders/version.rb +7 -0
- data/lib/elders.rb +13 -0
- data/spec/elders/stack_spec.rb +46 -0
- data/spec/elders/task_spec.rb +54 -0
- data/spec/spec_helper.rb +8 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7d5f64b6b4e554a5e73d5262466b503430a03c4f
|
4
|
+
data.tar.gz: b81f05d2015f8afd189c216fcea139d7492f4b51
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05ad36e734a945b2c8c5eab2136cc926f0ce1886ec67fbdf3e3c899bdddac3ea5d025070922ef2a5238e02fdb38037d5d682712f3d9eecefbb7039a8ee70e24f
|
7
|
+
data.tar.gz: 67694110b341ffc277eb04afce37ba38406e4410a8f64a53fdcd330cbde443609823decc90091b367ec9f5219f1913221fc8f681feea7d6a1c7734585c0569cf
|
data/.travis.yml
ADDED
data/Dockerfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Ruby Image
|
2
|
+
FROM ruby:2.2.0
|
3
|
+
|
4
|
+
# Install Bundler
|
5
|
+
RUN gem install bundler --no-ri --no-rdoc
|
6
|
+
|
7
|
+
# Make the app folder
|
8
|
+
RUN mkdir elders/
|
9
|
+
|
10
|
+
# Set workdir
|
11
|
+
WORKDIR elders/
|
12
|
+
|
13
|
+
# Add the rest of the source
|
14
|
+
ADD . .
|
15
|
+
|
16
|
+
# Bundle install it
|
17
|
+
RUN bundle install
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
elders (0.0.0)
|
5
|
+
concurrent-ruby (~> 1.0)
|
6
|
+
docker-api (~> 1.26)
|
7
|
+
json (~> 1.8)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
concurrent-ruby (1.0.0)
|
13
|
+
diff-lcs (1.2.5)
|
14
|
+
docker-api (1.26.0)
|
15
|
+
excon (>= 0.38.0)
|
16
|
+
json
|
17
|
+
excon (0.45.4)
|
18
|
+
json (1.8.3)
|
19
|
+
rspec (3.0.0)
|
20
|
+
rspec-core (~> 3.0.0)
|
21
|
+
rspec-expectations (~> 3.0.0)
|
22
|
+
rspec-mocks (~> 3.0.0)
|
23
|
+
rspec-core (3.0.4)
|
24
|
+
rspec-support (~> 3.0.0)
|
25
|
+
rspec-expectations (3.0.4)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.0.0)
|
28
|
+
rspec-mocks (3.0.4)
|
29
|
+
rspec-support (~> 3.0.0)
|
30
|
+
rspec-support (3.0.4)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
elders!
|
37
|
+
rspec (~> 3.0)
|
38
|
+
|
39
|
+
BUNDLED WITH
|
40
|
+
1.11.2
|
data/README.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
## Development
|
2
|
+
* Running tests:
|
3
|
+
1. Build the Docker image: `docker build -t elders .`
|
4
|
+
2. Run the RSpec: `docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock elders bundle exec rspec`
|
5
|
+
|
6
|
+
### Extra
|
7
|
+
Interactive mode in the conteiner.
|
8
|
+
|
9
|
+
* `docker run --rm -it -v (PWD):/elders -v /var/run/docker.sock:/var/run/docker.sock elders /bin/bash`
|
data/elders.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require './lib/elders/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'elders'
|
5
|
+
s.version = Elders.version
|
6
|
+
|
7
|
+
s.summary = 'Docker based task runner.'
|
8
|
+
s.description = 'Docker based task runner.'
|
9
|
+
|
10
|
+
s.author = 'Gabriel Corado'
|
11
|
+
s.email = 'gabrielcorado@mail.com'
|
12
|
+
s.homepage = 'http://github.com/gabrielcorado/elders'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.strip.split("\n")
|
15
|
+
s.executables = Dir["bin/*"].map { |f| File.basename(f) }
|
16
|
+
|
17
|
+
# Dependencies
|
18
|
+
s.add_dependency 'concurrent-ruby', '~> 1.0'
|
19
|
+
s.add_dependency 'docker-api', '~> 1.26'
|
20
|
+
s.add_dependency 'json', '~> 1.8'
|
21
|
+
|
22
|
+
# Development depencies
|
23
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
24
|
+
end
|
data/lib/elders/stack.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
#
|
2
|
+
module Elders
|
3
|
+
#
|
4
|
+
class Stack
|
5
|
+
# Attributes
|
6
|
+
attr_reader :tasks
|
7
|
+
attr_accessor :promise
|
8
|
+
|
9
|
+
# Create a new the stack
|
10
|
+
# @param {Array<Task>} tasks - The tasks from the stack
|
11
|
+
def initialize(tasks)
|
12
|
+
# Set tasks
|
13
|
+
@tasks = tasks
|
14
|
+
end
|
15
|
+
|
16
|
+
# Start
|
17
|
+
# @param {String} params - Params used by all the tasks
|
18
|
+
def start(params = nil)
|
19
|
+
# Start the tasks and get it promises
|
20
|
+
promises = @tasks.map do |task|
|
21
|
+
# Start the task
|
22
|
+
task.start params
|
23
|
+
|
24
|
+
# Get the promise
|
25
|
+
task.promise
|
26
|
+
end
|
27
|
+
|
28
|
+
# Wait for all the tasks
|
29
|
+
@promise = Concurrent::Promise.all? *promises
|
30
|
+
|
31
|
+
# Execute the promises
|
32
|
+
@promise.execute
|
33
|
+
end
|
34
|
+
|
35
|
+
# Clean all the stack tasks
|
36
|
+
def clean
|
37
|
+
# Each the tasks
|
38
|
+
@tasks.each do |task|
|
39
|
+
# Clean all of them
|
40
|
+
task.clean
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Wait until all the promises to finish
|
45
|
+
# @param {Integer} limit - Limit of waiting in seconds
|
46
|
+
def wait(limit = nil)
|
47
|
+
# Define the timeout
|
48
|
+
timeout = Time.now.to_i + limit unless limit.nil?
|
49
|
+
|
50
|
+
# Success?
|
51
|
+
success = false
|
52
|
+
|
53
|
+
# Inifiny loop
|
54
|
+
loop do
|
55
|
+
# Timeout?
|
56
|
+
break if !timeout.nil? && Time.now.to_i >= timeout
|
57
|
+
|
58
|
+
# Set the success
|
59
|
+
success = @promise.fulfilled?
|
60
|
+
|
61
|
+
# Completed?
|
62
|
+
break if success
|
63
|
+
end
|
64
|
+
|
65
|
+
# Return the success
|
66
|
+
success
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/elders/task.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
#
|
2
|
+
class Elders::Task
|
3
|
+
# Task timeout
|
4
|
+
TIMEOUT = 1500
|
5
|
+
|
6
|
+
# Attributes
|
7
|
+
attr_reader :name, :command, :promise
|
8
|
+
|
9
|
+
# Creates a new task, but not start it
|
10
|
+
# @param {String} name - Task name
|
11
|
+
# @param {String} image - Docker image that the command
|
12
|
+
# is going to be runned on.
|
13
|
+
# @param {String} command - The `bash` command that is
|
14
|
+
# going to be runned.
|
15
|
+
def initialize(name, image, command)
|
16
|
+
# Define the values
|
17
|
+
@name = name
|
18
|
+
@image_name = image
|
19
|
+
@command = command
|
20
|
+
end
|
21
|
+
|
22
|
+
# Start the task
|
23
|
+
# Shellwords.escape
|
24
|
+
# @param {String} params - Params for the task/command
|
25
|
+
def start(params = nil, env = nil)
|
26
|
+
# Clean
|
27
|
+
clean
|
28
|
+
|
29
|
+
# Add params to the command
|
30
|
+
command = @command
|
31
|
+
command = "#{command} #{params}" unless params.nil?
|
32
|
+
|
33
|
+
# Create the container
|
34
|
+
@container = Docker::Container.create 'Image' => @image_name, 'Cmd' => Shellwords.split(command), 'Env' => env
|
35
|
+
|
36
|
+
# Start it
|
37
|
+
@container.start
|
38
|
+
|
39
|
+
# Wait for the container to end
|
40
|
+
@promise = Concurrent::Promise.execute { @container.wait }
|
41
|
+
end
|
42
|
+
|
43
|
+
# Stop the task
|
44
|
+
def stop
|
45
|
+
container.stop
|
46
|
+
end
|
47
|
+
|
48
|
+
# Task logs
|
49
|
+
def logs
|
50
|
+
container.logs stdout: true
|
51
|
+
end
|
52
|
+
|
53
|
+
# Delete the container
|
54
|
+
def delete
|
55
|
+
# Delete the containe
|
56
|
+
res = container.delete force: true
|
57
|
+
|
58
|
+
# Clean it
|
59
|
+
@container = nil if res == nil
|
60
|
+
|
61
|
+
# Return the result
|
62
|
+
res
|
63
|
+
end
|
64
|
+
|
65
|
+
# Clean the task
|
66
|
+
def clean
|
67
|
+
# There is nothing to clean
|
68
|
+
return true unless container?
|
69
|
+
|
70
|
+
# Delete the container
|
71
|
+
delete == nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# Get the task container
|
75
|
+
def container
|
76
|
+
# Check if @container exists
|
77
|
+
raise 'Task was not started' unless container?
|
78
|
+
|
79
|
+
# Return the container
|
80
|
+
@container
|
81
|
+
end
|
82
|
+
|
83
|
+
# Check if the container exists
|
84
|
+
def container?
|
85
|
+
!@container.nil?
|
86
|
+
end
|
87
|
+
|
88
|
+
# Error in running the task?
|
89
|
+
def error?
|
90
|
+
# Check if the task is completed
|
91
|
+
return nil unless completed?
|
92
|
+
|
93
|
+
# Check the task status code
|
94
|
+
@promise.value['StatusCode'] > 0
|
95
|
+
end
|
96
|
+
|
97
|
+
# Completed the task?
|
98
|
+
def completed?
|
99
|
+
@promise.fulfilled?
|
100
|
+
end
|
101
|
+
|
102
|
+
# Check if the task was a success
|
103
|
+
def success?
|
104
|
+
completed? && !error?
|
105
|
+
end
|
106
|
+
end
|
data/lib/elders.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Include the helper
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
# Tests
|
5
|
+
describe 'Stack' do
|
6
|
+
# Time to complete the task
|
7
|
+
let(:time) { 3 }
|
8
|
+
|
9
|
+
# Create the task before the tests
|
10
|
+
before(:all) do
|
11
|
+
# Commands list
|
12
|
+
@tasks = ['sleep 2', 'ls', 'ls /bin'].map do |command|
|
13
|
+
# Generate a task for this command
|
14
|
+
Elders::Task.new("#{command[0..1]}-task", 'busybox', command)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Generate the stack
|
18
|
+
@stack = Elders::Stack.new @tasks
|
19
|
+
end
|
20
|
+
|
21
|
+
# Delete the task
|
22
|
+
after(:all) do
|
23
|
+
@stack.clean
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should be created' do
|
27
|
+
# Assertions
|
28
|
+
expect(@stack.tasks[0]).to eq(@tasks[0])
|
29
|
+
expect(@stack.tasks[1]).to eq(@tasks[1])
|
30
|
+
expect(@stack.tasks[2]).to eq(@tasks[2])
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should be started' do
|
34
|
+
# Start it
|
35
|
+
@stack.start
|
36
|
+
|
37
|
+
# Wait for it run
|
38
|
+
@stack.wait
|
39
|
+
|
40
|
+
# Assertions
|
41
|
+
expect(@stack.promise.state).to be(:fulfilled)
|
42
|
+
expect(@stack.tasks[0].completed?).to eq(true)
|
43
|
+
expect(@stack.tasks[1].completed?).to eq(true)
|
44
|
+
expect(@stack.tasks[2].completed?).to eq(true)
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Include the helper
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
# Tests
|
5
|
+
describe 'Task' do
|
6
|
+
# Time to complete the task
|
7
|
+
let(:time) { 0.1 }
|
8
|
+
|
9
|
+
# Create the task before the tests
|
10
|
+
before(:all) do
|
11
|
+
@task = Elders::Task.new 'test-task', 'busybox', 'printenv'
|
12
|
+
end
|
13
|
+
|
14
|
+
# Delete the task
|
15
|
+
after(:all) do
|
16
|
+
@task.clean
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should be created' do
|
20
|
+
# Assertions
|
21
|
+
expect(@task.name).to eq('test-task')
|
22
|
+
expect(@task.command).to eq('printenv')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should be started' do
|
26
|
+
# Start it
|
27
|
+
@task.start nil, ['APP_ENV=test']
|
28
|
+
|
29
|
+
# Wait for it run
|
30
|
+
sleep time
|
31
|
+
|
32
|
+
# Assertions
|
33
|
+
expect(@task.container).to be_a(Docker::Container)
|
34
|
+
expect(@task.completed?).to eq(true)
|
35
|
+
expect(@task.success?).to eq(true)
|
36
|
+
expect(@task.promise.state).to eq(:fulfilled)
|
37
|
+
expect(@task.logs.size).to be > 1
|
38
|
+
expect(@task.logs).to match(/APP_ENV/)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should be deleted' do
|
42
|
+
# Start the task
|
43
|
+
@task.start
|
44
|
+
|
45
|
+
# Wait for the task
|
46
|
+
sleep time
|
47
|
+
|
48
|
+
# Delete it
|
49
|
+
@task.delete
|
50
|
+
|
51
|
+
# Container
|
52
|
+
expect { @task.container }.to raise_error
|
53
|
+
end
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: elders
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gabriel Corado
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: concurrent-ruby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: docker-api
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.26'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.26'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: json
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
description: Docker based task runner.
|
70
|
+
email: gabrielcorado@mail.com
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- ".travis.yml"
|
76
|
+
- Dockerfile
|
77
|
+
- Gemfile
|
78
|
+
- Gemfile.lock
|
79
|
+
- README.md
|
80
|
+
- elders.gemspec
|
81
|
+
- lib/elders.rb
|
82
|
+
- lib/elders/stack.rb
|
83
|
+
- lib/elders/task.rb
|
84
|
+
- lib/elders/version.rb
|
85
|
+
- spec/elders/stack_spec.rb
|
86
|
+
- spec/elders/task_spec.rb
|
87
|
+
- spec/spec_helper.rb
|
88
|
+
homepage: http://github.com/gabrielcorado/elders
|
89
|
+
licenses: []
|
90
|
+
metadata: {}
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options: []
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 2.4.5.1
|
108
|
+
signing_key:
|
109
|
+
specification_version: 4
|
110
|
+
summary: Docker based task runner.
|
111
|
+
test_files: []
|