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.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/miniexec +49 -0
  3. data/lib/miniexec.rb +130 -0
  4. 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: []