Skip to content

Commit

Permalink
Enable using this runner on-premises
Browse files Browse the repository at this point in the history
  • Loading branch information
svenne87 committed Oct 5, 2023
1 parent 36fb679 commit e2834c0
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 8 deletions.
30 changes: 29 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
FROM ruby:2.7-alpine

MAINTAINER [email protected]

ENV USER=runner
ENV GROUP=runner
ENV UID=10000
ENV GID=10000

RUN apk --update add --no-cache git build-base && \
rm -rf /var/lib/apt/lists/*

COPY src/ /usr/local/src/integrationer-helpers/
RUN addgroup -g $GID $GROUP && \
adduser \
--disabled-password \
--gecos "" \
--home "$(pwd)" \
--ingroup "$USER" \
--uid "$UID" \
"$USER"

USER $USER

COPY config/gemrc /etc/gemrc
COPY config/gemrc /usr/local/etc/gemrc

COPY src/ /home/runner/

RUN gem update --system && gem install activesupport faraday faraday-retry money nokogiri pry-byebug rexml --no-doc

ENV HOME=/tmp/app-tmp
ENV TMPDIR=/tmp/app-tmp
ENV GEM_HOME=/tmp/gem-home
ENV GEM_PATH=/tmp/gem-home:/usr/local/bundle:/usr/local/lib/ruby/gems/2.7.0
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
# integrationer-steps-ruby-runner

### Running the image
The container image must be able to run on a read-only file system.

Running shell locally:
```bash
docker run -it --platform linux/amd64 --tmpfs "/tmp" --read-only --rm ghcr.io/standout/integrationer-steps-ruby-runner:<version> sh
```

When mounted in the Kubernetes cluster the folder `/tmp` is mounted as a `emptyDir`.
Kubernetes does not set the correct permissions for `/tmp`.
This will affect for example the Ruby Temp-folder lookup.

To correct this we use a initContainer to set the correct permission.
`sticky-bit` is set on the `/tmp/app-tmp` folder. And this folder is set as out temp-folder using environment variable `TMPDIR` in this container.

### Build and push to GitHub packages
A new release will publish a new image on GitHub packages.

Creating manual release:
```bash
docker build -t ghcr.io/standout/integrationer-steps-ruby-runner:latest -t ghcr.io/standout/integrationer-steps-ruby-runner:<version> .
```

Using Mac M1:
```bash
docker buildx build --platform linux/amd64 -t ghcr.io/standout/integrationer-steps-ruby-runner:latest -t ghcr.io/standout/integrationer-steps-ruby-runner:<version> .
```

Pushing:
```bash
docker push ghcr.io/standout/integrationer-steps-ruby-runner:latest
docker push ghcr.io/standout/integrationer-steps-ruby-runner:<version>
```
4 changes: 4 additions & 0 deletions config/gemrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
gem: --no-document --without development
install: --no-document
update: --no-document
84 changes: 84 additions & 0 deletions src/app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# frozen_string_literal: true

require 'json'
require 'open3'
require 'stringio'

# RubyEvaluator
class RubyEvaluator
NOTIFY_EXIT_CODE = 101
NOTIFY_RETRYABLE_EXIT_CODE = 102

def initialize(event)
@event = event
end

def evaluate
stdin, stdout, stderr, wait_thr = Open3.popen3(*command)

stdin.write(stdin_content)
stdin.close

stdout_content = stdout.read
stdout.close

stderr_content = stderr.read
stderr.close

exit_code = wait_thr.value.exitstatus.to_i

{
data: exit_code == 1 ? stderr_content : stdout_content,
exit_code: special_exit_code(exit_code, stderr_content)
}
end

private

def special_exit_code(exit_code, stderr_content)
return exit_code unless exit_code == 1
return NOTIFY_EXIT_CODE if stderr_content.include?('NotifyOrganizationError')
return NOTIFY_RETRYABLE_EXIT_CODE if stderr_content.include?('NotifyOrganizationRetryableError')

exit_code
end

def stdin_content
{
code: @event['code'],
fields: @event['fields'],
account: @event['account']
}.to_json
end

def command
['ruby', '-W0', '-r/home/runner/runner.rb', '-e', 'eval(RUNNER_CODE)']
end
end

# Handler
class Handler
def self.process(event: {})
old_stdout = $stdout.dup

$stdout = StringIO.new

eval_result = RubyEvaluator.new(event).evaluate

$stdout = old_stdout

response_message('success', eval_result[:data], eval_result[:exit_code])
rescue SystemExit => e
response_message('success', '{}', e.status)
end

def self.response_message(result, data, exit_code)
puts JSON.dump({ 'result': result, 'data': parse_data(data), 'exit_code': exit_code })
end

def self.parse_data(data)
JSON.parse(data)
rescue JSON::ParserError
data
end
end
3 changes: 0 additions & 3 deletions src/fields.rb

This file was deleted.

18 changes: 14 additions & 4 deletions src/runner.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
# frozen_string_literal: true

require 'json'

class NotifyOrganizationError < StandardError; end
class NotifyOrganizationRetryableError < StandardError; end

stdin = ''

while s=(ARGV.shift or (!STDIN.tty? and STDIN.gets) )
while s = (ARGV.shift or (!STDIN.tty? and STDIN.gets))
stdin += s
end

RUNNER_INPUT = JSON.parse(stdin)
RUNNER_CODE = RUNNER_INPUT.fetch('code', '')
FIELDS = RUNNER_INPUT.fetch('fields', {})
begin
RUNNER_INPUT = JSON.parse(stdin)
rescue JSON::ParserError
RUNNER_INPUT = {}.freeze
end

RUNNER_CODE = RUNNER_INPUT.fetch('code', nil) || ENV.fetch('RUNNER_CODE', '')
FIELDS = RUNNER_INPUT.fetch('fields', nil) || ENV.fetch('RUNNER_FIELDS', {})
ACCOUNT = RUNNER_INPUT.fetch('account', nil) || ENV.fetch('RUNNER_ACCOUNT', {})

0 comments on commit e2834c0

Please sign in to comment.