Resolve Gitea Docker gateway without iproute2
All checks were successful
Candidate compatibility / prepare (push) Successful in 30s
Candidate compatibility / image ${{ matrix.id }} (push) Has been skipped
Candidate compatibility / fixture-contract (push) Successful in 1m9s
Candidate compatibility / lockstep clients Ruby 3.3 (push) Successful in 1m15s
Candidate compatibility / repository (push) Successful in 1m50s
Candidate compatibility / lockstep clients Ruby 3.4 (push) Successful in 1m49s
Candidate compatibility / Gitea full exact image matrix (push) Successful in 1m53s
Candidate compatibility / lockstep clients Ruby 4.0 (push) Successful in 2m16s
Candidate compatibility / lockstep clients Ruby 3.2 (push) Successful in 2m20s
All checks were successful
Candidate compatibility / prepare (push) Successful in 30s
Candidate compatibility / image ${{ matrix.id }} (push) Has been skipped
Candidate compatibility / fixture-contract (push) Successful in 1m9s
Candidate compatibility / lockstep clients Ruby 3.3 (push) Successful in 1m15s
Candidate compatibility / repository (push) Successful in 1m50s
Candidate compatibility / lockstep clients Ruby 3.4 (push) Successful in 1m49s
Candidate compatibility / Gitea full exact image matrix (push) Successful in 1m53s
Candidate compatibility / lockstep clients Ruby 4.0 (push) Successful in 2m16s
Candidate compatibility / lockstep clients Ruby 3.2 (push) Successful in 2m20s
This commit is contained in:
5
.github/workflows/candidate.yml
vendored
5
.github/workflows/candidate.yml
vendored
@@ -300,10 +300,7 @@ jobs:
|
|||||||
echo "value=$actual_client_sha" >> "$GITHUB_OUTPUT"
|
echo "value=$actual_client_sha" >> "$GITHUB_OUTPUT"
|
||||||
- name: Resolve the private Docker host transport
|
- name: Resolve the private Docker host transport
|
||||||
run: |
|
run: |
|
||||||
probe_host="$(ip -4 route show default | awk '/^default / {print $3; exit}')"
|
probe_host="$(ruby scripts/private_default_gateway.rb)"
|
||||||
ruby -ripaddr -e \
|
|
||||||
'address = IPAddr.new(ARGV.fetch(0)); exit(address.ipv4? && address.private? ? 0 : 1)' \
|
|
||||||
"$probe_host"
|
|
||||||
echo "OPENCODE_PROBE_HOST=$probe_host" >> "$GITHUB_ENV"
|
echo "OPENCODE_PROBE_HOST=$probe_host" >> "$GITHUB_ENV"
|
||||||
- name: Exercise the complete manifest matrix without artifact claims
|
- name: Exercise the complete manifest matrix without artifact claims
|
||||||
env:
|
env:
|
||||||
|
|||||||
28
scripts/private_default_gateway.rb
Executable file
28
scripts/private_default_gateway.rb
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "ipaddr"
|
||||||
|
|
||||||
|
route_path = ARGV.fetch(0, "/proc/net/route")
|
||||||
|
routes = File.foreach(route_path).drop(1).filter_map do |line|
|
||||||
|
fields = line.split
|
||||||
|
next unless fields.length >= 8
|
||||||
|
next unless fields.fetch(1) == "00000000"
|
||||||
|
next unless (fields.fetch(3).to_i(16) & 0x2) == 0x2
|
||||||
|
|
||||||
|
fields
|
||||||
|
end
|
||||||
|
|
||||||
|
routes.sort_by { |fields| fields.fetch(6).to_i }.each do |fields|
|
||||||
|
gateway_hex = fields.fetch(2)
|
||||||
|
next unless gateway_hex.match?(/\A[0-9A-Fa-f]{8}\z/)
|
||||||
|
|
||||||
|
gateway = gateway_hex.scan(/../).reverse.map { |octet| octet.to_i(16) }.join(".")
|
||||||
|
address = IPAddr.new(gateway)
|
||||||
|
next unless address.ipv4? && address.private?
|
||||||
|
|
||||||
|
puts address
|
||||||
|
exit 0
|
||||||
|
end
|
||||||
|
|
||||||
|
abort "no private IPv4 default-route gateway found in #{route_path}"
|
||||||
@@ -4,11 +4,13 @@ require "fileutils"
|
|||||||
require "json"
|
require "json"
|
||||||
require "minitest/autorun"
|
require "minitest/autorun"
|
||||||
require "open3"
|
require "open3"
|
||||||
|
require "rbconfig"
|
||||||
require "tmpdir"
|
require "tmpdir"
|
||||||
|
|
||||||
class ImageContractEvidenceTest < Minitest::Test
|
class ImageContractEvidenceTest < Minitest::Test
|
||||||
ROOT = File.expand_path("..", __dir__)
|
ROOT = File.expand_path("..", __dir__)
|
||||||
RUNNER = File.join(ROOT, "scripts/run_image_contract.sh")
|
RUNNER = File.join(ROOT, "scripts/run_image_contract.sh")
|
||||||
|
GATEWAY_RESOLVER = File.join(ROOT, "scripts/private_default_gateway.rb")
|
||||||
VALID_IMAGE = "ghcr.io/anomalyco/opencode@sha256:#{'a' * 64}"
|
VALID_IMAGE = "ghcr.io/anomalyco/opencode@sha256:#{'a' * 64}"
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@@ -125,6 +127,32 @@ class ImageContractEvidenceTest < Minitest::Test
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_resolves_a_private_default_gateway_from_linux_route_hex
|
||||||
|
route_path = File.join(@tmp, "route")
|
||||||
|
File.write(route_path, <<~ROUTES)
|
||||||
|
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth0 00000000 010011AC 0003 0 0 10 00000000 0 0 0
|
||||||
|
ROUTES
|
||||||
|
|
||||||
|
output, error, status = Open3.capture3(RbConfig.ruby, GATEWAY_RESOLVER, route_path)
|
||||||
|
|
||||||
|
assert status.success?, error
|
||||||
|
assert_equal "172.17.0.1\n", output
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_gateway_resolver_rejects_a_public_default_gateway
|
||||||
|
route_path = File.join(@tmp, "public-route")
|
||||||
|
File.write(route_path, <<~ROUTES)
|
||||||
|
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
|
||||||
|
eth0 00000000 08080808 0003 0 0 10 00000000 0 0 0
|
||||||
|
ROUTES
|
||||||
|
|
||||||
|
_output, error, status = Open3.capture3(RbConfig.ruby, GATEWAY_RESOLVER, route_path)
|
||||||
|
|
||||||
|
refute status.success?
|
||||||
|
assert_match(/no private IPv4 default-route gateway found/, error)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def base_environment(checkout, commit, evidence_path)
|
def base_environment(checkout, commit, evidence_path)
|
||||||
|
|||||||
@@ -287,8 +287,7 @@ class RepositoryTest < Minitest::Test
|
|||||||
assert_includes workflow, "exact-image-contract-gitea:"
|
assert_includes workflow, "exact-image-contract-gitea:"
|
||||||
assert_includes workflow, "if: github.server_url != 'https://github.com'"
|
assert_includes workflow, "if: github.server_url != 'https://github.com'"
|
||||||
assert_includes workflow, "run: scripts/run_image_matrix_contract.sh"
|
assert_includes workflow, "run: scripts/run_image_matrix_contract.sh"
|
||||||
assert_includes workflow, "ip -4 route show default"
|
assert_includes workflow, 'probe_host="$(ruby scripts/private_default_gateway.rb)"'
|
||||||
assert_includes workflow, "address.ipv4? && address.private?"
|
|
||||||
assert_includes workflow, 'echo "OPENCODE_PROBE_HOST=$probe_host" >> "$GITHUB_ENV"'
|
assert_includes workflow, 'echo "OPENCODE_PROBE_HOST=$probe_host" >> "$GITHUB_ENV"'
|
||||||
assert_operator workflow.scan('BUNDLE_GEMFILE: ${{ github.workspace }}/ruby-client/Gemfile').length, :>=, 2
|
assert_operator workflow.scan('BUNDLE_GEMFILE: ${{ github.workspace }}/ruby-client/Gemfile').length, :>=, 2
|
||||||
assert_operator workflow.scan("generated JSON is transient and is not review evidence").length, :>=, 3
|
assert_operator workflow.scan("generated JSON is transient and is not review evidence").length, :>=, 3
|
||||||
|
|||||||
Reference in New Issue
Block a user