build-labels 0.0.84 → 0.0.85

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71200ab2745bc6b72e3713bd05be3dfc01335ace3d0e69a812b0543cabb2dcb5
4
- data.tar.gz: 114e09c1f436d4d213b1b70598677f85a2c78960f0c518a5acbb8a479135c5b3
3
+ metadata.gz: e3a02e5fbc875e7810f24fd48b1d054e1ba42c4fc31830d37f1131da08033305
4
+ data.tar.gz: b810cae6b722b0f962684197fedf83cb7eacf3da71ee52c7a61c1dbac3a3b689
5
5
  SHA512:
6
- metadata.gz: c92119e261e7d30b83efd45dd59947c5da00b5af72f7dd7ff864c98328e73c5530160e0707677382807fe07d21c4a8bf91b5f1f844adbc2b7cfb9749f08275b0
7
- data.tar.gz: 6b335e9538786713aed349357ed2a4bb7491785454f9e6817f49377291670b128b4e326e28f52a89f475afa3a5246420a7160e8625c1f4dcd56dfc29c3d9e90a
6
+ metadata.gz: 5513b81dda0b4547c93953ef3e907f4c55b32fd632e5a7f7896b6c8a4fcc52370912a156a2d54b74928bcd364d11fdfa210f8cf4a7376a56971a5cb3fe1db8d9
7
+ data.tar.gz: 863c93ea012458fc841035e8e21a3153cdc6328bd2c932daa30a20c77b29caeb009474e0dfb318cbb1f56c3ab771ea61bbee00b88ab94e057324010896edd692
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+ text = File.read(__FILE__)
3
+ shell = text.split(/^__END__\s*$/, 2)[1] or abort('missing __END__')
4
+ exec 'sh', '-eu', '-c', shell, 'sh', *ARGV
5
+
6
+ __END__
7
+ set -eu
8
+
9
+ trivy_version="0.74.0"
10
+
11
+ curl_fetch() {
12
+ curl -fsSL \
13
+ --retry "${CURL_RETRIES:-3}" \
14
+ --retry-delay "${CURL_RETRY_DELAY:-2}" \
15
+ --retry-all-errors \
16
+ --connect-timeout "${CURL_CONNECT_TIMEOUT:-10}" \
17
+ --max-time "${CURL_MAX_TIME:-120}" \
18
+ "$@"
19
+ }
20
+
21
+ usage() {
22
+ cat <<USAGE
23
+ Usage: install-trivy-static
24
+
25
+ Installs pinned Trivy ${trivy_version} to /usr/local/bin/trivy.
26
+
27
+ Options:
28
+ -h, --help Show this help
29
+ USAGE
30
+ }
31
+
32
+ if [ "$#" -gt 0 ]; then
33
+ case "$1" in
34
+ -h|--help)
35
+ usage
36
+ exit 0
37
+ ;;
38
+ *)
39
+ echo "Unexpected argument: $1" >&2
40
+ usage
41
+ exit 1
42
+ ;;
43
+ esac
44
+ fi
45
+
46
+ case "$(uname -m)" in
47
+ x86_64|amd64)
48
+ trivy_arch="64bit"
49
+ trivy_sha256="2ae6fe3ee734b7fdf11335663e18c75ea12dccc76062f09f164a3b0f8be4371a"
50
+ ;;
51
+ aarch64|arm64)
52
+ trivy_arch="ARM64"
53
+ trivy_sha256="b94ce1976bbf3c15b514b605ee88be7c6d94a29be2302847ff01cb794d47aad5"
54
+ ;;
55
+ armv7l|armv7|armv6l|armv6)
56
+ trivy_arch="ARM"
57
+ trivy_sha256="99adbe319fa685cb4bff04dd0077e31cb94828338cab5db7f78fe6dcecca8ec1"
58
+ ;;
59
+ ppc64le)
60
+ trivy_arch="PPC64LE"
61
+ trivy_sha256="c5aabfe8789d0d43f578ef2d01174884c8ff0f2106c627a220a43f7bf9054959"
62
+ ;;
63
+ s390x)
64
+ trivy_arch="s390x"
65
+ trivy_sha256="516cfe38eaede79c178088265657aad12be6c155271ac68ff728a141961ef197"
66
+ ;;
67
+ *)
68
+ echo "Unsupported architecture: $(uname -m)" >&2
69
+ exit 1
70
+ ;;
71
+ esac
72
+
73
+ if command -v apt-get >/dev/null 2>&1; then
74
+ apt-get update
75
+ apt-get install -y --no-install-recommends ca-certificates coreutils curl tar
76
+ cleanup_packages="apt"
77
+ elif command -v apk >/dev/null 2>&1; then
78
+ apk add --no-cache ca-certificates coreutils curl tar
79
+ cleanup_packages=""
80
+ else
81
+ echo "Unsupported package manager: expected apt or apk." >&2
82
+ exit 1
83
+ fi
84
+
85
+ tmp_dir="$(mktemp -d)"
86
+ trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM
87
+ archive="trivy_${trivy_version}_Linux-${trivy_arch}.tar.gz"
88
+ archive_path="${tmp_dir}/${archive}"
89
+ curl_fetch "https://github.com/aquasecurity/trivy/releases/download/v${trivy_version}/${archive}" -o "$archive_path"
90
+ printf '%s %s\n' "$trivy_sha256" "$archive_path" | sha256sum -c -
91
+ tar -xzf "$archive_path" -C "$tmp_dir" trivy
92
+ install -m 0755 "$tmp_dir/trivy" /usr/local/bin/trivy
93
+
94
+ if [ "$cleanup_packages" = "apt" ]; then
95
+ rm -rf /var/lib/apt/lists/*
96
+ fi
97
+
98
+ trivy --version
data/lib/trivy-runner.rb CHANGED
@@ -6,9 +6,21 @@ require 'yaml'
6
6
  require_relative 'version'
7
7
 
8
8
  class TrivyRunner
9
+ DEFAULT_CACHE_DIR = '/root/.cache/trivy'.freeze
9
10
  IMAGE_ID = /\Asha256:[0-9a-f]{64}\z/
10
11
 
11
12
  def run(args)
13
+ return run_filesystems(args.drop(1)) if args.first == 'fs'
14
+
15
+ run_images(args)
16
+ rescue StandardError => error
17
+ warn error.message
18
+ 1
19
+ end
20
+
21
+ private
22
+
23
+ def run_images(args)
12
24
  file = 'bake.yml'
13
25
  metadata_file = nil
14
26
  tty = true
@@ -41,16 +53,43 @@ class TrivyRunner
41
53
  verify_images(images)
42
54
  warn "\e[32mTrivy checks passed.#{trivy_args.empty? ? '' : " Options: #{trivy_args.shelljoin}"}\e[0m"
43
55
  0
44
- rescue StandardError => error
45
- warn error.message
46
- 1
47
56
  end
48
57
 
49
- private
58
+ def run_filesystems(args)
59
+ file = 'bake.yml'
60
+ cache_dir = nil
61
+ parser = OptionParser.new do |options|
62
+ options.banner = 'Usage: trivy-runner fs -f COMPOSE_FILE [--cache-dir DIR] [-- TRIVY_OPTIONS ...]'
63
+ options.separator 'Scans every unique local service build context with native trivy fs.'
64
+ options.separator 'Options after -- are forwarded to trivy fs.'
65
+ options.on('-f', '--file FILE', 'Compose file (default: bake.yml)') { file = _1 }
66
+ options.on('--cache-dir DIR', 'Trivy cache directory (default: TRIVY_CACHE_DIR or /root/.cache/trivy)') do
67
+ cache_dir = _1
68
+ end
69
+ options.on('-v', '--version', 'Print version') { puts BuildLabels::Builder::VERSION; return 0 }
70
+ options.on('-h', '--help', 'Print help') { puts options; return 0 }
71
+ end
72
+ separator = args.index('--') || args.length
73
+ trivy_args = args.drop(separator + 1)
74
+ unexpected = parser.parse!(args.take(separator))
75
+ raise OptionParser::InvalidOption, "Unexpected argument: #{unexpected.first}" unless unexpected.empty?
76
+
77
+ contexts = filesystem_contexts(file)
78
+ return 0 if contexts.empty?
79
+
80
+ cache_dir ||= ENV.fetch('TRIVY_CACHE_DIR', DEFAULT_CACHE_DIR)
81
+ contexts.each do |path, services|
82
+ warn "\n\e[36m=== Trivy fs scan: #{services.join(', ')} ===\nPath: #{path}\e[0m"
83
+ status = scan_filesystem(path, cache_dir, trivy_args)
84
+ return status unless status.zero?
85
+ end
86
+ warn "\e[32mTrivy fs checks passed.#{trivy_args.empty? ? '' : " Options: #{trivy_args.shelljoin}"}\e[0m"
87
+ 0
88
+ end
50
89
 
51
90
  def scan(image_id, trivy_args, tty)
52
91
  environment = ENV.keys.grep(/\ATRIVY_/) - %w[TRIVY_IMAGE]
53
- cache_dir = ENV.fetch('TRIVY_CACHE_DIR', '/root/.cache/trivy')
92
+ cache_dir = ENV.fetch('TRIVY_CACHE_DIR', DEFAULT_CACHE_DIR)
54
93
  system('docker', 'run', '--rm', '--pull', 'always', *(tty ? ['--tty'] : []),
55
94
  '--mount', 'type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock,readonly',
56
95
  '--mount', "type=volume,src=trivy-cache,dst=#{cache_dir}",
@@ -59,6 +98,50 @@ class TrivyRunner
59
98
  '--exit-code', '1', *trivy_args, image_id)
60
99
  end
61
100
 
101
+ def scan_filesystem(path, cache_dir, trivy_args)
102
+ pid = Process.spawn('trivy', 'fs', '--cache-dir', cache_dir, *trivy_args, path)
103
+ status = Process.wait2(pid).last
104
+ status.exited? ? status.exitstatus : 128 + status.termsig
105
+ rescue Errno::ENOENT
106
+ warn 'Trivy executable not found. Install it with install-trivy-static.'
107
+ 127
108
+ end
109
+
110
+ def filesystem_contexts(file)
111
+ compose = YAML.safe_load(File.read(file), aliases: true)
112
+ services = compose.is_a?(Hash) && compose['services']
113
+ raise 'Invalid Compose services map' unless services.is_a?(Hash)
114
+
115
+ base_dir = File.dirname(File.expand_path(file))
116
+ services.each_with_object({}) do |(name, service), contexts|
117
+ raise "Invalid Compose service: #{name}" unless service.is_a?(Hash)
118
+ next unless service.key?('build')
119
+
120
+ context = build_context(name, service['build'])
121
+ raise "Unresolved build context for service #{name}: #{context}" if context.include?('$')
122
+ raise "Remote build context is not supported for service #{name}: #{context}" if remote_context?(context)
123
+
124
+ path = File.expand_path(context, base_dir)
125
+ raise "Build context is not a directory for service #{name}: #{path}" unless File.directory?(path)
126
+
127
+ (contexts[File.realpath(path)] ||= []) << name
128
+ end
129
+ end
130
+
131
+ def build_context(name, build)
132
+ context = case build
133
+ when String then build
134
+ when Hash then build.fetch('context', '.')
135
+ end
136
+ raise "Invalid build configuration for service #{name}" unless context.is_a?(String) && !context.empty?
137
+
138
+ context
139
+ end
140
+
141
+ def remote_context?(context)
142
+ context.match?(%r{\A(?:[a-z][a-z0-9+.-]*://|git@|service:)}i)
143
+ end
144
+
62
145
  def empty_compose?(file)
63
146
  document = YAML.safe_load(File.read(file), aliases: true)
64
147
  document.is_a?(Hash) && document['services'] == {}
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module BuildLabels
2
2
  class Builder
3
- VERSION = '0.0.84'
3
+ VERSION = '0.0.85'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: build-labels
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.84
4
+ version: 0.0.85
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artyom B
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-09 00:00:00.000000000 Z
11
+ date: 2026-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -101,12 +101,14 @@ executables:
101
101
  - helm-push
102
102
  - trivy-runner
103
103
  - install-docker-static
104
+ - install-trivy-static
104
105
  extensions: []
105
106
  extra_rdoc_files: []
106
107
  files:
107
108
  - bin/build-labels
108
109
  - bin/helm-push
109
110
  - bin/install-docker-static
111
+ - bin/install-trivy-static
110
112
  - bin/trivy-runner
111
113
  - examples/Dockerfile
112
114
  - examples/common-compose.yml