Class: OCIRegistry::Remote
- Inherits:
-
Object
- Object
- OCIRegistry::Remote
- Defined in:
- lib/oci_registry/remote.rb
Class Method Summary collapse
-
.display_metadata(config_json) ⇒ Object
Step 5: Extract Labels and Metadata.
-
.download_and_extract_layers(host, token, repository, layers, file_name) ⇒ Object
Function to download and extract layers.
-
.extract_layer(layer_data, file_name) ⇒ Object
Function to extract a layer and search for the specified file.
-
.get_blob(host, token, repository, blob_digest) ⇒ Object
Step 4: Retrieve the Image Configuration.
-
.get_docker_token(repository, username = nil, password = nil) ⇒ Object
Step 1: Obtain an Access Token.
-
.get_manifest(host, token, repository, tag) ⇒ Object
Step 2: Fetch the Image Manifest.
-
.get_tags(host, token, repository) ⇒ Object
Function to fetch the list of tags for the repository.
-
.http_get(uri, headers = {}, limit = 10) ⇒ Object
Helper method to handle HTTP GET requests with redirect support.
Class Method Details
.display_metadata(config_json) ⇒ Object
Step 5: Extract Labels and Metadata
136 137 138 139 140 141 142 143 144 |
# File 'lib/oci_registry/remote.rb', line 136 def self.(config_json) labels = config_json['config']['Labels'] puts "Labels:" puts JSON.pretty_generate(labels) puts "\nOther Metadata:" = config_json['config'] puts JSON.pretty_generate() end |
.download_and_extract_layers(host, token, repository, layers, file_name) ⇒ Object
Function to download and extract layers
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/oci_registry/remote.rb', line 147 def self.download_and_extract_layers(host, token, repository, layers, file_name) layers.each_with_index do |layer, index| digest = layer['digest'] puts "Processing layer #{index + 1}/#{layers.size}: #{digest}" # Download the layer blob uri = URI("https://#{host}/v2/#{repository}/blobs/#{digest}") headers = { 'Authorization' => "Bearer #{token}" } response = http_get(uri, headers) if response.is_a?(Net::HTTPSuccess) # Decompress and extract the tar.gz layer found = extract_layer(response.body, file_name) return true if found else puts "Failed to download layer #{digest}: #{response.code} #{response.}" end end false end |
.extract_layer(layer_data, file_name) ⇒ Object
Function to extract a layer and search for the specified file
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/oci_registry/remote.rb', line 170 def self.extract_layer(layer_data, file_name) # Decompress the gzip layer data gz = Zlib::GzipReader.new(StringIO.new(layer_data)) tar_io = StringIO.new(gz.read) # Extract tar contents Minitar::Input.open(tar_io) do |tar| tar.each do |entry| # Normalize file paths to handle different directory structures entry_path = entry.full_name.sub(/^\.\//, '').sub(/^\/+/, '') if File.basename(entry_path) == file_name puts "\nFound '#{file_name}' in layer:" contents = entry.read puts contents return true end end end false end |
.get_blob(host, token, repository, blob_digest) ⇒ Object
Step 4: Retrieve the Image Configuration
88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/oci_registry/remote.rb', line 88 def self.get_blob(host, token, repository, blob_digest) uri = URI("https://#{host}/v2/#{repository}/blobs/#{blob_digest}") headers = { 'Authorization' => "Bearer #{token}" } response = http_get(uri, headers) if response.is_a?(Net::HTTPSuccess) JSON.parse(response.body) else raise "Failed to retrieve image configuration for #{uri.inspect}: #{response.code} #{response.}" end end |
.get_docker_token(repository, username = nil, password = nil) ⇒ Object
Step 1: Obtain an Access Token
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/oci_registry/remote.rb', line 46 def self.get_docker_token(repository, username = nil, password = nil) uri = URI("https://auth.docker.io/token?service=registry.docker.io&scope=repository:#{repository}:pull") headers = {} if username && password encoded_credentials = Base64.strict_encode64("#{username}:#{password}") headers['Authorization'] = "Basic #{encoded_credentials}" end response = http_get(uri, headers) if response.is_a?(Net::HTTPSuccess) json = JSON.parse(response.body) json['token'] else raise "Failed to obtain token: #{response.code} #{response.}" end end |
.get_manifest(host, token, repository, tag) ⇒ Object
Step 2: Fetch the Image Manifest
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/oci_registry/remote.rb', line 66 def self.get_manifest(host, token, repository, tag) uri = URI("https://#{host}/v2/#{repository}/manifests/#{tag}") headers = { 'Authorization' => "Bearer #{token}", 'Accept' => [ 'application/vnd.oci.image.index.v1+json', 'application/vnd.docker.distribution.manifest.list.v2+json', 'application/vnd.oci.image.manifest.v1+json', 'application/vnd.docker.distribution.manifest.v2+json' ].join(', ') } response = http_get(uri, headers) if response.is_a?(Net::HTTPSuccess) JSON.parse(response.body) else raise "Failed to fetch manifest: #{response.code} #{response.}" end end |
.get_tags(host, token, repository) ⇒ Object
Function to fetch the list of tags for the repository
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/oci_registry/remote.rb', line 102 def self.(host, token, repository) = [] batch_size = 100 next_url = "/v2/#{repository}/tags/list?n=#{batch_size}" headers = { 'Authorization' => "Bearer #{token}", 'Accept' => 'application/json' } loop do uri = URI("https://#{host}#{next_url}") response = http_get(uri, headers) if response.is_a?(Net::HTTPSuccess) json = JSON.parse(response.body) .concat(json['tags'] || []) # Check for pagination link_header = response['Link'] if link_header && link_header.include?('rel="next"') next_url = link_header.match(/<(.+)>;/)[1] else break end else puts "Failed to fetch tags for #{repository}: https://#{host}#{next_url} #{response.code} #{response.}" break end end end |
.http_get(uri, headers = {}, limit = 10) ⇒ Object
Helper method to handle HTTP GET requests with redirect support
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/oci_registry/remote.rb', line 16 def self.http_get(uri, headers = {}, limit = 10) raise 'Too many HTTP redirects' if limit == 0 request = Net::HTTP::Get.new(uri) headers.each { |k, v| request[k] = v } response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http| http.request(request) end case response when Net::HTTPRedirection location = response['location'] # warn "Redirected to #{location}" # Handle the case where location is a relative URL by reconstructing the full URL new_uri = ::URI.join(uri, location) http_get(new_uri, headers, limit - 1) # 429 when Net::HTTPTooManyRequests puts "Rate limited: #{response.code} #{response.}" # Retry after the specified time retry_after = response['Retry-After'].to_i || 10 sleep(retry_after) http_get(uri, headers, limit - 1) else response end end |