diff --git a/.dockerignore b/.dockerignore index 2c72a5f..17fc17c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ .dockerignore .DS_Store +.env .git* .gitignore docker-compose* diff --git a/.gitignore b/.gitignore index fd5106f..0baf78e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .DS_STORE +.env +app.rb diff --git a/Gemfile b/Gemfile index 116cd7f..4d7b858 100644 --- a/Gemfile +++ b/Gemfile @@ -2,8 +2,12 @@ source "https://rubygems.org" +gem "octokit", "~> 10.0" gem "puma" gem "rack-test" gem "rackup" gem "rspec" +gem "sinatra-contrib", "~> 4.1" gem "sinatra" + +gem "pry", "~> 0.15.2", :group => :development diff --git a/Gemfile.lock b/Gemfile.lock index 7506843..a631956 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,12 +1,33 @@ GEM remote: https://rubygems.org/ specs: + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) base64 (0.3.0) + coderay (1.1.3) diff-lcs (1.6.2) + faraday (2.13.4) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.1) + net-http (>= 0.5.0) + json (2.13.2) logger (1.7.0) + method_source (1.1.0) + multi_json (1.17.0) mustermann (3.0.4) ruby2_keywords (~> 0.0.1) + net-http (0.6.0) + uri nio4r (2.7.4) + octokit (10.0.0) + faraday (>= 1, < 3) + sawyer (~> 0.9) + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + public_suffix (6.0.2) puma (6.6.1) nio4r (~> 2.0) rack (3.2.0) @@ -35,6 +56,9 @@ GEM rspec-support (~> 3.13.0) rspec-support (3.13.5) ruby2_keywords (0.0.5) + sawyer (0.9.2) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) sinatra (4.1.1) logger (>= 1.6.0) mustermann (~> 3.0) @@ -42,18 +66,28 @@ GEM rack-protection (= 4.1.1) rack-session (>= 2.0.0, < 3) tilt (~> 2.0) + sinatra-contrib (4.1.1) + multi_json (>= 0.0.2) + mustermann (~> 3.0) + rack-protection (= 4.1.1) + sinatra (= 4.1.1) + tilt (~> 2.0) tilt (2.6.1) + uri (1.0.3) PLATFORMS aarch64-linux ruby DEPENDENCIES + octokit (~> 10.0) + pry (~> 0.15.2) puma rack-test rackup rspec sinatra + sinatra-contrib (~> 4.1) BUNDLED WITH - 2.6.9 + 2.6.5 diff --git a/app.rb b/app.rb index 0651bdf..c850917 100644 --- a/app.rb +++ b/app.rb @@ -1,5 +1,60 @@ +require 'date' +require 'octokit' require 'sinatra' +require 'sinatra/json' + +configure :development do + set :logging, Logger::DEBUG + set :server_settings, timeout: 60 +end + +def has_permatag?(version, permatags) + (version['metadata']['container']['tags'] & permatags).any? +end + +def younger_than?(version, days_old) + cutoff = Time.now - 60*60*24*days_old + version['created_at'] > cutoff +end + +github = Octokit::Client.new(per_page: 100, auto_paginate: true) get '/' do - "Hello, world!" + 'Hello, world!' +end + +# Returns all container packages along with their pruning status, i.e. whether they can/can't be pruned and why +get '/images' do + packages = github.get('orgs/BerkeleyLibrary/packages', {package_type: :container}) + logger.info "Scanning #{packages.size} packages for prunable images: #{packages.collect(&:name).sort}" + + prunables = [].tap do |sofar| + packages.each do |pkg| + logger.info "Determining prunable images for #{pkg.name}" + + next unless pkg.repository + + permatags = %w(latest edge) + permatags += github.branches(pkg.repository.full_name).collect(&:name) + permatags += github.tags(pkg.repository.full_name).collect(&:name) + + github.get("orgs/#{pkg.owner.login}/packages/#{pkg.package_type}/#{pkg.name}/versions").each do |image| + if has_permatag? image, permatags + pruning_status = :permatagged + elsif younger_than? image, 7 + pruning_status = :recent + else + pruning_status = :prunable + end + + sofar << { + image: image.to_attrs, + pruning_status: pruning_status, + can_be_pruned: pruning_status == :prunable, + } + end + end + end + + json prunables end diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 9f04aa0..3305ff2 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -4,6 +4,7 @@ services: app: build: !reset image: ${DOCKER_APP_IMAGE} + env_file: !reset ports: !reset volumes: !override - $ARTIFACTS_DIR:/tmp/artifacts diff --git a/docker-compose.yml b/docker-compose.yml index c504ee5..aa1016d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,13 @@ services: app: build: . + env_file: + - .env ports: - 4567:4567 volumes: - ./:/opt/app + develop: + watch: + - action: rebuild + path: .