Commit 1e63244d authored by Luke Duncalfe's avatar Luke Duncalfe

Merge branch 'debian_packages_endpoint' into 'master'

Add Debian API endpoint for Packages files

See merge request gitlab-org/gitlab!64068
parents 9f242c9d f836ae22
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
module Packages module Packages
module Debian module Debian
DISTRIBUTION_REGEX = %r{[a-z0-9][a-z0-9.-]*}i.freeze
COMPONENT_REGEX = DISTRIBUTION_REGEX.freeze
ARCHITECTURE_REGEX = %r{[a-z0-9][-a-z0-9]*}.freeze
def self.table_name_prefix def self.table_name_prefix
'packages_debian_' 'packages_debian_'
end end
......
...@@ -6,20 +6,17 @@ module API ...@@ -6,20 +6,17 @@ module API
module DebianPackageEndpoints module DebianPackageEndpoints
extend ActiveSupport::Concern extend ActiveSupport::Concern
DISTRIBUTION_REGEX = %r{[a-zA-Z0-9][a-zA-Z0-9.-]*}.freeze
COMPONENT_REGEX = %r{[a-z-]+}.freeze
ARCHITECTURE_REGEX = %r{[a-z][a-z0-9]*}.freeze
LETTER_REGEX = %r{(lib)?[a-z0-9]}.freeze LETTER_REGEX = %r{(lib)?[a-z0-9]}.freeze
PACKAGE_REGEX = API::NO_SLASH_URL_PART_REGEX PACKAGE_REGEX = API::NO_SLASH_URL_PART_REGEX
DISTRIBUTION_REQUIREMENTS = { DISTRIBUTION_REQUIREMENTS = {
distribution: DISTRIBUTION_REGEX distribution: ::Packages::Debian::DISTRIBUTION_REGEX
}.freeze }.freeze
COMPONENT_ARCHITECTURE_REQUIREMENTS = { COMPONENT_ARCHITECTURE_REQUIREMENTS = {
component: COMPONENT_REGEX, component: ::Packages::Debian::COMPONENT_REGEX,
architecture: ARCHITECTURE_REGEX architecture: ::Packages::Debian::ARCHITECTURE_REGEX
}.freeze }.freeze
COMPONENT_LETTER_SOURCE_PACKAGE_REQUIREMENTS = { COMPONENT_LETTER_SOURCE_PACKAGE_REQUIREMENTS = {
component: COMPONENT_REGEX, component: ::Packages::Debian::COMPONENT_REGEX,
letter: LETTER_REGEX, letter: LETTER_REGEX,
source_package: PACKAGE_REGEX source_package: PACKAGE_REGEX
}.freeze }.freeze
...@@ -100,8 +97,20 @@ module API ...@@ -100,8 +97,20 @@ module API
route_setting :authentication, authenticate_non_public: true route_setting :authentication, authenticate_non_public: true
get 'Packages' do get 'Packages' do
# https://gitlab.com/gitlab-org/gitlab/-/issues/5835#note_414103286 relation = "::Packages::Debian::#{project_or_group.class.name}ComponentFile".constantize
'TODO Packages'
component_file = relation
.preload_distribution
.with_container(project_or_group)
.with_codename_or_suite(params[:distribution])
.with_component_name(params[:component])
.with_file_type(:packages)
.with_architecture_name(params[:architecture])
.with_compression_type(nil)
.order_created_asc
.last!
present_carrierwave_file!(component_file.file)
end end
end end
end end
......
...@@ -118,15 +118,15 @@ module Gitlab ...@@ -118,15 +118,15 @@ module Gitlab
def debian_architecture_regex def debian_architecture_regex
# See official parser: https://git.dpkg.org/cgit/dpkg/dpkg.git/tree/lib/dpkg/arch.c?id=9e0c88ec09475f4d1addde9cdba1ad7849720356#n43 # See official parser: https://git.dpkg.org/cgit/dpkg/dpkg.git/tree/lib/dpkg/arch.c?id=9e0c88ec09475f4d1addde9cdba1ad7849720356#n43
# But we limit to lower case # But we limit to lower case
@debian_architecture_regex ||= %r{\A[a-z0-9][-a-z0-9]*\z}.freeze @debian_architecture_regex ||= %r{\A#{::Packages::Debian::ARCHITECTURE_REGEX}\z}.freeze
end end
def debian_distribution_regex def debian_distribution_regex
@debian_distribution_regex ||= %r{\A[a-z0-9][a-z0-9\.-]*\z}i.freeze @debian_distribution_regex ||= %r{\A#{::Packages::Debian::DISTRIBUTION_REGEX}\z}i.freeze
end end
def debian_component_regex def debian_component_regex
@debian_component_regex ||= %r{#{debian_distribution_regex}}.freeze @debian_component_regex ||= %r{\A#{::Packages::Debian::COMPONENT_REGEX}\z}.freeze
end end
def helm_channel_regex def helm_channel_regex
......
...@@ -25,13 +25,13 @@ RSpec.describe API::DebianGroupPackages do ...@@ -25,13 +25,13 @@ RSpec.describe API::DebianGroupPackages do
end end
describe 'GET groups/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do describe 'GET groups/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/#{component}/binary-#{architecture}/Packages" } let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/#{component.name}/binary-#{architecture.name}/Packages" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO Packages$/ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /Description: This is an incomplete Packages file/
end end
describe 'GET groups/:id/-/packages/debian/pool/:component/:letter/:source_package/:file_name' do describe 'GET groups/:id/-/packages/debian/pool/:component/:letter/:source_package/:file_name' do
let(:url) { "/groups/#{container.id}/-/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" } let(:url) { "/groups/#{container.id}/-/packages/debian/pool/#{component.name}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture.name}.deb" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO File$/ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO File$/
end end
......
...@@ -25,13 +25,13 @@ RSpec.describe API::DebianProjectPackages do ...@@ -25,13 +25,13 @@ RSpec.describe API::DebianProjectPackages do
end end
describe 'GET projects/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do describe 'GET projects/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/#{component}/binary-#{architecture}/Packages" } let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/#{component.name}/binary-#{architecture.name}/Packages" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO Packages$/ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /Description: This is an incomplete Packages file/
end end
describe 'GET projects/:id/packages/debian/pool/:component/:letter/:source_package/:file_name' do describe 'GET projects/:id/packages/debian/pool/:component/:letter/:source_package/:file_name' do
let(:url) { "/projects/#{container.id}/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" } let(:url) { "/projects/#{container.id}/packages/debian/pool/#{component.name}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture.name}.deb" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO File$/ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO File$/
end end
......
...@@ -16,11 +16,13 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_ ...@@ -16,11 +16,13 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_
let_it_be(:private_component, freeze: true) { create("debian_#{container_type}_component", distribution: private_distribution, name: 'existing-component') } let_it_be(:private_component, freeze: true) { create("debian_#{container_type}_component", distribution: private_distribution, name: 'existing-component') }
let_it_be(:private_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'all') } let_it_be(:private_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'all') }
let_it_be(:private_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'existing-arch') } let_it_be(:private_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'existing-arch') }
let_it_be(:private_component_file) { create("debian_#{container_type}_component_file", component: private_component, architecture: private_architecture) }
let_it_be(:public_distribution, freeze: true) { create("debian_#{container_type}_distribution", :with_file, container: public_container, codename: 'existing-codename') } let_it_be(:public_distribution, freeze: true) { create("debian_#{container_type}_distribution", :with_file, container: public_container, codename: 'existing-codename') }
let_it_be(:public_component, freeze: true) { create("debian_#{container_type}_component", distribution: public_distribution, name: 'existing-component') } let_it_be(:public_component, freeze: true) { create("debian_#{container_type}_component", distribution: public_distribution, name: 'existing-component') }
let_it_be(:public_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'all') } let_it_be(:public_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'all') }
let_it_be(:public_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'existing-arch') } let_it_be(:public_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'existing-arch') }
let_it_be(:public_component_file) { create("debian_#{container_type}_component_file", component: public_component, architecture: public_architecture) }
if container_type == :group if container_type == :group
let_it_be(:private_project) { create(:project, :private, group: private_container) } let_it_be(:private_project) { create(:project, :private, group: private_container) }
...@@ -40,14 +42,15 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_ ...@@ -40,14 +42,15 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_
let(:visibility_level) { :public } let(:visibility_level) { :public }
let(:distribution) { { private: private_distribution, public: public_distribution }[visibility_level] } let(:distribution) { { private: private_distribution, public: public_distribution }[visibility_level] }
let(:architecture) { { private: private_architecture, public: public_architecture }[visibility_level] }
let(:component) { { private: private_component, public: public_component }[visibility_level] }
let(:component_file) { { private: private_component_file, public: public_component_file }[visibility_level] }
let(:component) { 'main' }
let(:architecture) { 'amd64' }
let(:source_package) { 'sample' } let(:source_package) { 'sample' }
let(:letter) { source_package[0..2] == 'lib' ? source_package[0..3] : source_package[0] } let(:letter) { source_package[0..2] == 'lib' ? source_package[0..3] : source_package[0] }
let(:package_name) { 'libsample0' } let(:package_name) { 'libsample0' }
let(:package_version) { '1.2.3~alpha2' } let(:package_version) { '1.2.3~alpha2' }
let(:file_name) { "#{package_name}_#{package_version}_#{architecture}.deb" } let(:file_name) { "#{package_name}_#{package_version}_#{architecture.name}.deb" }
let(:method) { :get } let(:method) { :get }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment