diff --git a/.gitlab/ci/container-boot.gitlab-ci.yml b/.gitlab/ci/container-boot.gitlab-ci.yml index 743be47c..68aee6e1 100644 --- a/.gitlab/ci/container-boot.gitlab-ci.yml +++ b/.gitlab/ci/container-boot.gitlab-ci.yml @@ -2,7 +2,7 @@ extends: - .dind stage: container:boot - image: ghcr.io/code0-tech/build-images/reticulum-builder:171.1-ruby-3.2.2 + image: ghcr.io/code0-tech/build-images/reticulum-builder:177.1-ruby-3.2.2 .container:boot:sagittarius: extends: @@ -17,6 +17,7 @@ variables: SAGITTARIUS_IMAGE: ghcr.io/code0-tech/reticulum/ci-builds/sagittarius:${CI_PIPELINE_ID}-${VARIANT} CURL_IMAGE: curlimages/curl:8.5.0 + DOCKER_ARGS: "" before_script: - docker network create boot - > @@ -33,12 +34,16 @@ - docker pull $CURL_IMAGE - > docker run + --detach --name sagittarius --network boot --network-alias sagittarius --volume $(pwd)/container/sagittarius/sagittarius.yml:/sagittarius/config/sagittarius.yml + $DOCKER_ARGS $SAGITTARIUS_IMAGE - $SAGITTARIUS_CMD & + $SAGITTARIUS_CMD + - docker ps --all + - docker logs -f sagittarius & container:boot:sagittarius:rails-web: extends: @@ -58,3 +63,17 @@ container:boot:sagittarius:rails-web: --retry-delay 3 --retry-connrefused http://sagittarius:3000/health/liveness + +container:boot:sagittarius:grpc: + extends: + - .container:boot:sagittarius + variables: + SAGITTARIUS_CMD: "bin/grpc_server" + DOCKER_ARGS: "--publish 50051:50051 --env SAGITTARIUS_PREPARE_DATABASE=true" + before_script: + - bundle config set --local force_ruby_platform true + - bundle install + - !reference [.container:boot:sagittarius, before_script] + script: + - scripts/grpc_check_health --host docker:50051 --service liveness --retries 20 + - scripts/grpc_check_health --host docker:50051 --service readiness --retries 20 diff --git a/Gemfile b/Gemfile index 53ea9491..33459c33 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,7 @@ source "https://rubygems.org" gem "erb" + +gem "grpc", "~> 1.73" + +gem "optparse", "~> 0.6.0" diff --git a/Gemfile.lock b/Gemfile.lock index f85dff00..1d23d4c6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,26 @@ GEM remote: https://rubygems.org/ specs: + bigdecimal (3.2.2) erb (5.0.1) + google-protobuf (4.31.1) + bigdecimal + rake (>= 13) + googleapis-common-protos-types (1.20.0) + google-protobuf (>= 3.18, < 5.a) + grpc (1.73.0) + google-protobuf (>= 3.25, < 5.0) + googleapis-common-protos-types (~> 1.0) + optparse (0.6.0) + rake (13.3.0) PLATFORMS ruby DEPENDENCIES erb + grpc (~> 1.73) + optparse (~> 0.6.0) BUNDLED WITH 2.6.6 diff --git a/scripts/grpc_check_health b/scripts/grpc_check_health new file mode 100755 index 00000000..dbefc806 --- /dev/null +++ b/scripts/grpc_check_health @@ -0,0 +1,76 @@ +#!/usr/bin/env ruby + +require 'grpc' +require 'optparse' +require 'grpc/health/v1/health_services_pb' + +options = { + retries: 5, + backoff: 3, + service: '', +} + +optparse = OptionParser.new do |opts| + opts.banner = 'Usage: grpc_check_health [options]' + + opts.on('-h', '--host [HOST]', String, 'Host of the grpc server to check') do |host| + options[:host] = host + end + + opts.on('-r', '--retries [RETRIES]', Integer, "Amount of retries (Default: #{options[:retries]})") do |retries| + options[:retries] = retries + end + + opts.on('-b', '--backoff [BACKOFF]', Integer, "Backoff in seconds for each attempt (Default: #{options[:backoff]})") do |backoff| + options[:backoff] = backoff + end + + opts.on('-s', '--service [SERVICE]', String, "Service check health for (Default: '#{options[:service]}')") do |service| + options[:service] = service + end +end +optparse.parse! + +missing = %i[host].select{ |param| options[param].nil? } +unless missing.empty? + puts "Missing arguments: #{missing.join(', ')}" + puts + puts optparse + exit +end + +RetryException = Class.new(StandardError) + +attempt = 1 + +begin + puts + puts "Attempt #{attempt}/#{options[:retries]} to check if '#{options[:service]}' on #{options[:host]} is serving" + stub = Grpc::Health::V1::Health::Stub.new(options[:host], :this_channel_is_insecure) + message = Grpc::Health::V1::HealthCheckRequest.new(service: options[:service]) + + response = stub.check(message) + + if response.status == :SERVING + puts "Service '#{options[:service]}' on #{options[:host]} is #{response.status}" + else + raise RetryException + end +rescue GRPC::BadStatus, RetryException => e + if e.is_a?(GRPC::BadStatus) + message = e.inspect + else + message = "Service #{options[:service]} on #{options[:host]} is not SERVING (status is #{response&.status})" + end + + puts message + + if attempt < options[:retries] + attempt += 1 + puts "Retrying in #{options[:backoff]}s" + sleep options[:backoff] + retry + end + + abort +end diff --git a/versions/sagittarius b/versions/sagittarius index 0fb5b950..1acdf250 100644 --- a/versions/sagittarius +++ b/versions/sagittarius @@ -1 +1 @@ -8387fcc7969e9e53ab28e04d9e8316b527d111b5 \ No newline at end of file +02fd861ffe1465cba09b952532ac8d811639fbf7 \ No newline at end of file