miniexec 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/bin/miniexec +49 -0
- data/lib/miniexec.rb +130 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0f7e4e2e4cd3529c3d39ba72db21f2290c51dffdfedef503bc7423b95a8afe5e
|
4
|
+
data.tar.gz: 28a58aad14b944600fe64573df8869b5de3a5dc94ecf1844ab7405fe4cb30be0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0eec63f1bcaacc2e548f8e2381069fba8fe8ebbad998e843a2ecbc56f26852f308332f879946cb55c59aeee9d9be94cca76c35dc1ebe89472a2ad8e2c9664a77
|
7
|
+
data.tar.gz: 5c7a796c761e8c7ef3423bf4d4d81020fdc29995345b22015337578c0319623077a7ff110395bf74af02e1c3afb82b85166a2074f91422d845e46913ffcb3057
|
data/bin/miniexec
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'miniexec'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
options = {
|
8
|
+
binds: [],
|
9
|
+
env: []
|
10
|
+
}
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = 'Usage: miniexec.rb [options]'
|
14
|
+
opts.separator ''
|
15
|
+
opts.separator 'specific options:'
|
16
|
+
|
17
|
+
opts.on('-p', '--path PATH', 'Path to the repository containing a valid .gitlab-ci.yml') do |path|
|
18
|
+
options[:path] = path
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on('-j', '--job JOBNAME', 'Specify the gitlab job to run') do |job|
|
22
|
+
options[:job] = job
|
23
|
+
end
|
24
|
+
|
25
|
+
opts.on('-b', '--bind BIND', 'Specify a bind mapping',
|
26
|
+
'Example: /some/local/dir:/mapping/in/container') do |bind|
|
27
|
+
options[:binds].push bind
|
28
|
+
end
|
29
|
+
opts.on('-e', '--environment VARIABLE',
|
30
|
+
'Specify an environment variable to be passed to the container',
|
31
|
+
'Example: SOMEVAR=thing') do |env|
|
32
|
+
options[:env].push env
|
33
|
+
end
|
34
|
+
opts.on('-d', '--docker-url URL',
|
35
|
+
'Location of the docker socket') do |sock|
|
36
|
+
options[:docker] = sock || ENV['DOCKER_HOST'] || '/run/docker.sock'
|
37
|
+
end
|
38
|
+
end.parse!
|
39
|
+
|
40
|
+
raise OptionParser::MissingArgument, 'Specify a job with -j' if options[:job].nil?
|
41
|
+
raise OptionParser::MissingArgument, 'Specify a job with -p' if options[:path].nil?
|
42
|
+
|
43
|
+
MiniExec.config(project_path: options[:path])
|
44
|
+
exec = MiniExec.new options[:job],
|
45
|
+
docker_url: options[:docker],
|
46
|
+
binds: options[:binds],
|
47
|
+
env: options[:env]
|
48
|
+
|
49
|
+
exec.run_job
|
data/lib/miniexec.rb
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Main class
|
4
|
+
class MiniExec
|
5
|
+
require 'logger'
|
6
|
+
require 'docker-api'
|
7
|
+
require 'json'
|
8
|
+
require 'tempfile'
|
9
|
+
require 'yaml'
|
10
|
+
# Class instance variables
|
11
|
+
@project_path = '.'
|
12
|
+
@workflow_file = '.gitlab-ci.yml'
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :project_path, :workflow_file
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.config(project_path: @project_path, workflow_file: @workflow_file)
|
19
|
+
@project_path = project_path
|
20
|
+
@class = workflow_file
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :script
|
25
|
+
|
26
|
+
def initialize(job,
|
27
|
+
project_path: self.class.project_path,
|
28
|
+
workflow_file: self.class.workflow_file,
|
29
|
+
docker_url: nil,
|
30
|
+
binds: [],
|
31
|
+
env: [])
|
32
|
+
@job_name = job
|
33
|
+
@project_path = project_path
|
34
|
+
workflow = YAML.load(File.read("#{@project_path}/#{workflow_file}"))
|
35
|
+
@job = workflow[job]
|
36
|
+
@job['name'] = job
|
37
|
+
@default_image = workflow['image'] || 'debian:buster-slim'
|
38
|
+
@image = set_job_image
|
39
|
+
@script = compile_script
|
40
|
+
@binds = binds
|
41
|
+
@env = env
|
42
|
+
|
43
|
+
configure_logger
|
44
|
+
|
45
|
+
Docker.options[:read_timeout] = 6000
|
46
|
+
Docker.url = docker_url if docker_url
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_job
|
50
|
+
script_path = "/tmp/#{@job['name']}.sh"
|
51
|
+
@logger.debug "Fetching image #{@image}"
|
52
|
+
Docker::Image.create(fromImage: @image)
|
53
|
+
@logger.debug 'Image fetched'
|
54
|
+
Dir.chdir(@project_path) do
|
55
|
+
@logger.debug 'Creating container'
|
56
|
+
container = Docker::Container.create(
|
57
|
+
Cmd: ['/bin/bash', script_path],
|
58
|
+
Image: @image,
|
59
|
+
Volumes: @binds.map { |b| { b => { path_parent: 'rw' } } }.inject(:merge),
|
60
|
+
Env: @env
|
61
|
+
)
|
62
|
+
container.store_file(script_path, @script)
|
63
|
+
container.start({ Binds: [@binds] })
|
64
|
+
container.tap(&:start).attach { |_, chunk| @logger.info chunk }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def set_job_image
|
71
|
+
return @job['image'] if @job['image']
|
72
|
+
|
73
|
+
@default_image
|
74
|
+
end
|
75
|
+
|
76
|
+
def configure_logger
|
77
|
+
@logger = Logger.new($stdout)
|
78
|
+
@logger.formatter = proc do |severity, _, _, msg|
|
79
|
+
"[#{severity}]: #{msg}\n"
|
80
|
+
end
|
81
|
+
@logger.level = ENV['LOGLEVEL'] || Logger::WARN
|
82
|
+
end
|
83
|
+
|
84
|
+
def compile_script
|
85
|
+
before_script = @job['before_script'] || []
|
86
|
+
script = @job['script'] || []
|
87
|
+
after_script = @job['after_script'] || []
|
88
|
+
(before_script + script + after_script).flatten.join("\n")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
options = {
|
93
|
+
binds: [],
|
94
|
+
env: []
|
95
|
+
}
|
96
|
+
|
97
|
+
OptionParser.new do |opts|
|
98
|
+
opts.banner = 'Usage: miniexec.rb [options]'
|
99
|
+
opts.separator ''
|
100
|
+
opts.separator 'specific options:'
|
101
|
+
|
102
|
+
opts.on('-p', '--path PATH', 'Path to the repository containing a valid .gitlab-ci.yml') do |path|
|
103
|
+
options[:path] = path
|
104
|
+
end
|
105
|
+
|
106
|
+
opts.on('-j', '--job JOBNAME', 'Specify the gitlab job to run') do |job|
|
107
|
+
options[:job] = job
|
108
|
+
end
|
109
|
+
|
110
|
+
opts.on('-b', '--bind BIND', 'Specify a bind mapping',
|
111
|
+
'Example: /some/local/dir:/mapping/in/container') do |bind|
|
112
|
+
options[:binds].push bind
|
113
|
+
end
|
114
|
+
opts.on('-e', '--environment VARIABLE',
|
115
|
+
'Specify an environment variable to be passed to the container',
|
116
|
+
'Example: SOMEVAR=thing') do |env|
|
117
|
+
options[:env].push env
|
118
|
+
end
|
119
|
+
end.parse!
|
120
|
+
|
121
|
+
raise OptionParser::MissingArgument, 'Specify a job with -j' if options[:job].nil?
|
122
|
+
raise OptionParser::MissingArgument, 'Specify a job with -p' if options[:path].nil?
|
123
|
+
|
124
|
+
MiniExec.config(project_path: options[:path])
|
125
|
+
exec = MiniExec.new options[:job],
|
126
|
+
docker_url: 'unix:///var/run/user/1000/podman/podman.sock',
|
127
|
+
binds: options[:binds],
|
128
|
+
env: options[:env]
|
129
|
+
|
130
|
+
exec.run_job
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: miniexec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Pugh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-02-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A minimal interpretor/executor for .gitlab-ci.yml
|
14
|
+
email: pugh@s3kr.it
|
15
|
+
executables:
|
16
|
+
- miniexec
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/miniexec
|
21
|
+
- lib/miniexec.rb
|
22
|
+
homepage: https://github.com/s3krit/miniexec
|
23
|
+
licenses:
|
24
|
+
- AGPL-3.0-or-later
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubygems_version: 3.1.2
|
42
|
+
signing_key:
|
43
|
+
specification_version: 4
|
44
|
+
summary: exec a gitlab job
|
45
|
+
test_files: []
|