Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
d46eebd8
Commit
d46eebd8
authored
Sep 20, 2020
by
Mathieu Parent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Debian Group and Project Distributions
See #5835
parent
1c8deba0
Changes
21
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
752 additions
and
0 deletions
+752
-0
app/models/concerns/packages/debian/distribution.rb
app/models/concerns/packages/debian/distribution.rb
+109
-0
app/models/group.rb
app/models/group.rb
+3
-0
app/models/packages/debian/group_distribution.rb
app/models/packages/debian/group_distribution.rb
+9
-0
app/models/packages/debian/project_distribution.rb
app/models/packages/debian/project_distribution.rb
+9
-0
app/models/project.rb
app/models/project.rb
+2
-0
app/uploaders/packages/debian/distribution_release_file_uploader.rb
...ers/packages/debian/distribution_release_file_uploader.rb
+27
-0
changelogs/unreleased/debian_distributions.yml
changelogs/unreleased/debian_distributions.yml
+5
-0
db/migrate/20201204110700_create_packages_debian_project_distributions.rb
...204110700_create_packages_debian_project_distributions.rb
+62
-0
db/migrate/20201204110800_create_packages_debian_group_distributions.rb
...01204110800_create_packages_debian_group_distributions.rb
+62
-0
db/schema_migrations/20201204110700
db/schema_migrations/20201204110700
+1
-0
db/schema_migrations/20201204110800
db/schema_migrations/20201204110800
+1
-0
db/structure.sql
db/structure.sql
+120
-0
locale/gitlab.pot
locale/gitlab.pot
+6
-0
spec/factories/packages/debian/distribution.rb
spec/factories/packages/debian/distribution.rb
+25
-0
spec/lib/gitlab/import_export/all_models.yml
spec/lib/gitlab/import_export/all_models.yml
+1
-0
spec/models/group_spec.rb
spec/models/group_spec.rb
+20
-0
spec/models/packages/debian/group_distribution_spec.rb
spec/models/packages/debian/group_distribution_spec.rb
+7
-0
spec/models/packages/debian/project_distribution_spec.rb
spec/models/packages/debian/project_distribution_spec.rb
+7
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+20
-0
spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
...es/models/packages/debian/distribution_shared_examples.rb
+204
-0
spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb
...ackages/debian/distribution_release_file_uploader_spec.rb
+52
-0
No files found.
app/models/concerns/packages/debian/distribution.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
module
Packages
module
Debian
module
Distribution
extend
ActiveSupport
::
Concern
included
do
include
FileStoreMounter
def
self
.
container_foreign_key
"
#{
container_type
}
_id"
.
to_sym
end
alias_attribute
:container
,
container_type
alias_attribute
:container_id
,
"
#{
container_type
}
_id"
belongs_to
container_type
belongs_to
:creator
,
class_name:
'User'
validates
:codename
,
presence:
true
,
uniqueness:
{
scope:
[
container_foreign_key
]
},
format:
{
with:
Gitlab
::
Regex
.
debian_distribution_regex
}
validates
:suite
,
allow_nil:
true
,
format:
{
with:
Gitlab
::
Regex
.
debian_distribution_regex
}
validates
:suite
,
uniqueness:
{
scope:
[
container_foreign_key
]
},
if: :suite
validate
:unique_codename_and_suite
validates
:origin
,
allow_nil:
true
,
format:
{
with:
Gitlab
::
Regex
.
debian_distribution_regex
}
validates
:label
,
allow_nil:
true
,
format:
{
with:
Gitlab
::
Regex
.
debian_distribution_regex
}
validates
:version
,
allow_nil:
true
,
format:
{
with:
Gitlab
::
Regex
.
debian_version_regex
}
# The Valid-Until field is a security measure to prevent malicious attackers to
# serve an outdated repository, with vulnerable packages
# (keeping in mind that most Debian repository are not using TLS but use GPG
# signatures instead).
# A minimum of 24 hours is simply to avoid generating indices too often
# (which generates load).
# Official Debian repositories are generated 4 times a day, and valid for 7 days.
# Full ref: https://wiki.debian.org/DebianRepository/Format#Date.2C_Valid-Until
validates
:valid_time_duration_seconds
,
allow_nil:
true
,
numericality:
{
greater_than_or_equal_to:
24
.
hours
.
to_i
}
validates
container_type
,
presence:
true
validates
:file_store
,
presence:
true
validates
:file_signature
,
absence:
true
validates
:signing_keys
,
absence:
true
scope
:with_container
,
->
(
subject
)
{
where
(
container_type
=>
subject
)
}
scope
:with_codename
,
->
(
codename
)
{
where
(
codename:
codename
)
}
scope
:with_suite
,
->
(
suite
)
{
where
(
suite:
suite
)
}
attr_encrypted
:signing_keys
,
mode: :per_attribute_iv
,
key:
Settings
.
attr_encrypted_db_key_base_truncated
,
algorithm:
'aes-256-gcm'
,
encode:
false
,
encode_iv:
false
mount_file_store_uploader
Packages
::
Debian
::
DistributionReleaseFileUploader
def
needs_update?
!
file
.
exists?
||
time_duration_expired?
end
private
def
time_duration_expired?
return
false
unless
valid_time_duration_seconds
.
present?
updated_at
+
valid_time_duration_seconds
.
seconds
+
6
.
hours
<
Time
.
current
end
def
unique_codename_and_suite
errors
.
add
(
:codename
,
_
(
'has already been taken as Suite'
))
if
codename_exists_as_suite?
errors
.
add
(
:suite
,
_
(
'has already been taken as Codename'
))
if
suite_exists_as_codename?
end
def
codename_exists_as_suite?
return
false
unless
codename
.
present?
self
.
class
.
with_container
(
container
).
with_suite
(
codename
).
exists?
end
def
suite_exists_as_codename?
return
false
unless
suite
.
present?
self
.
class
.
with_container
(
container
).
with_codename
(
suite
).
exists?
end
end
end
end
end
app/models/group.rb
View file @
d46eebd8
...
...
@@ -75,6 +75,9 @@ class Group < Namespace
has_many
:dependency_proxy_blobs
,
class_name:
'DependencyProxy::Blob'
has_many
:dependency_proxy_manifests
,
class_name:
'DependencyProxy::Manifest'
# debian_distributions must be destroyed by ruby code in order to properly remove carrierwave uploads
has_many
:debian_distributions
,
class_name:
'Packages::Debian::GroupDistribution'
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
accepts_nested_attributes_for
:variables
,
allow_destroy:
true
validate
:visibility_level_allowed_by_projects
...
...
app/models/packages/debian/group_distribution.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
class
Packages::Debian::GroupDistribution
<
ApplicationRecord
def
self
.
container_type
:group
end
include
Packages
::
Debian
::
Distribution
end
app/models/packages/debian/project_distribution.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
class
Packages::Debian::ProjectDistribution
<
ApplicationRecord
def
self
.
container_type
:project
end
include
Packages
::
Debian
::
Distribution
end
app/models/project.rb
View file @
d46eebd8
...
...
@@ -200,6 +200,8 @@ class Project < ApplicationRecord
# Packages
has_many
:packages
,
class_name:
'Packages::Package'
has_many
:package_files
,
through: :packages
,
class_name:
'Packages::PackageFile'
# debian_distributions must be destroyed by ruby code in order to properly remove carrierwave uploads
has_many
:debian_distributions
,
class_name:
'Packages::Debian::ProjectDistribution'
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_one
:import_state
,
autosave:
true
,
class_name:
'ProjectImportState'
,
inverse_of: :project
has_one
:import_export_upload
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
...
...
app/uploaders/packages/debian/distribution_release_file_uploader.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
class
Packages::Debian::DistributionReleaseFileUploader
<
GitlabUploader
extend
Workhorse
::
UploadPath
include
ObjectStorage
::
Concern
storage_options
Gitlab
.
config
.
packages
after
:store
,
:schedule_background_upload
alias_method
:upload
,
:model
def
filename
'Release'
end
def
store_dir
dynamic_segment
end
private
def
dynamic_segment
raise
ObjectNotReadyError
,
'Package model not ready'
unless
model
.
id
Gitlab
::
HashedPath
.
new
(
"debian_
#{
model
.
class
.
container_type
}
_distribution"
,
model
.
id
,
root_hash:
model
.
container_id
)
end
end
changelogs/unreleased/debian_distributions.yml
0 → 100644
View file @
d46eebd8
---
title
:
Debian Group and Project Distributions
merge_request
:
49405
author
:
Mathieu Parent
type
:
added
db/migrate/20201204110700_create_packages_debian_project_distributions.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
class
CreatePackagesDebianProjectDistributions
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
UNIQUE_CODENAME
=
'uniq_pkgs_debian_project_distributions_project_id_and_codename'
UNIQUE_SUITE
=
'uniq_pkgs_debian_project_distributions_project_id_and_suite'
disable_ddl_transaction!
def
up
with_lock_retries
do
unless
table_exists?
(
:packages_debian_project_distributions
)
create_table
:packages_debian_project_distributions
do
|
t
|
t
.
timestamps_with_timezone
t
.
references
:project
,
foreign_key:
{
to_table: :projects
,
on_delete: :restrict
},
null:
false
t
.
references
:creator
,
foreign_key:
{
to_table: :users
,
on_delete: :nullify
}
t
.
integer
:valid_time_duration_seconds
t
.
integer
:file_store
,
limit:
2
,
default:
1
,
null:
false
t
.
boolean
:automatic
,
default:
true
,
null:
false
t
.
boolean
:automatic_upgrades
,
default:
false
,
null:
false
t
.
text
:codename
,
null:
false
t
.
text
:suite
t
.
text
:origin
t
.
text
:label
t
.
text
:version
t
.
text
:description
t
.
text
:encrypted_signing_keys
t
.
text
:encrypted_signing_keys_iv
t
.
text
:file
t
.
text
:file_signature
t
.
index
%w(project_id codename)
,
name:
UNIQUE_CODENAME
,
unique:
true
,
using: :btree
t
.
index
%w(project_id suite)
,
name:
UNIQUE_SUITE
,
unique:
true
,
using: :btree
end
end
end
add_text_limit
:packages_debian_project_distributions
,
:codename
,
255
add_text_limit
:packages_debian_project_distributions
,
:suite
,
255
add_text_limit
:packages_debian_project_distributions
,
:origin
,
255
add_text_limit
:packages_debian_project_distributions
,
:label
,
255
add_text_limit
:packages_debian_project_distributions
,
:version
,
255
add_text_limit
:packages_debian_project_distributions
,
:description
,
255
add_text_limit
:packages_debian_project_distributions
,
:encrypted_signing_keys
,
2048
add_text_limit
:packages_debian_project_distributions
,
:encrypted_signing_keys_iv
,
255
add_text_limit
:packages_debian_project_distributions
,
:file
,
255
add_text_limit
:packages_debian_project_distributions
,
:file_signature
,
4096
end
def
down
drop_table
:packages_debian_project_distributions
end
end
db/migrate/20201204110800_create_packages_debian_group_distributions.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
class
CreatePackagesDebianGroupDistributions
<
ActiveRecord
::
Migration
[
5.2
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
UNIQUE_CODENAME
=
'uniq_pkgs_debian_group_distributions_group_id_and_codename'
UNIQUE_SUITE
=
'uniq_pkgs_debian_group_distributions_group_id_and_suite'
disable_ddl_transaction!
def
up
with_lock_retries
do
unless
table_exists?
(
:packages_debian_group_distributions
)
create_table
:packages_debian_group_distributions
do
|
t
|
t
.
timestamps_with_timezone
t
.
references
:group
,
foreign_key:
{
to_table: :namespaces
,
on_delete: :restrict
},
null:
false
t
.
references
:creator
,
foreign_key:
{
to_table: :users
,
on_delete: :nullify
}
t
.
integer
:valid_time_duration_seconds
t
.
integer
:file_store
,
limit:
2
,
default:
1
,
null:
false
t
.
boolean
:automatic
,
default:
true
,
null:
false
t
.
boolean
:automatic_upgrades
,
default:
false
,
null:
false
t
.
text
:codename
,
null:
false
t
.
text
:suite
t
.
text
:origin
t
.
text
:label
t
.
text
:version
t
.
text
:description
t
.
text
:encrypted_signing_keys
t
.
text
:encrypted_signing_keys_iv
t
.
text
:file
t
.
text
:file_signature
t
.
index
%w(group_id codename)
,
name:
UNIQUE_CODENAME
,
unique:
true
,
using: :btree
t
.
index
%w(group_id suite)
,
name:
UNIQUE_SUITE
,
unique:
true
,
using: :btree
end
end
end
add_text_limit
:packages_debian_group_distributions
,
:codename
,
255
add_text_limit
:packages_debian_group_distributions
,
:suite
,
255
add_text_limit
:packages_debian_group_distributions
,
:origin
,
255
add_text_limit
:packages_debian_group_distributions
,
:label
,
255
add_text_limit
:packages_debian_group_distributions
,
:version
,
255
add_text_limit
:packages_debian_group_distributions
,
:description
,
255
add_text_limit
:packages_debian_group_distributions
,
:encrypted_signing_keys
,
2048
add_text_limit
:packages_debian_group_distributions
,
:encrypted_signing_keys_iv
,
255
add_text_limit
:packages_debian_group_distributions
,
:file
,
255
add_text_limit
:packages_debian_group_distributions
,
:file_signature
,
4096
end
def
down
drop_table
:packages_debian_group_distributions
end
end
db/schema_migrations/20201204110700
0 → 100644
View file @
d46eebd8
986ffa5e3e168ce9acf9b346c94bdee05d85c71abe238b8aa21f95cc472faabc
\ No newline at end of file
db/schema_migrations/20201204110800
0 → 100644
View file @
d46eebd8
aecf517402d3decf8f7323e8f43fdfe7160cbe7542a474e392996abd75b2d70f
\ No newline at end of file
db/structure.sql
View file @
d46eebd8
...
...
@@ -14721,6 +14721,88 @@ CREATE TABLE packages_debian_file_metadata (
CONSTRAINT
check_e6e1fffcca
CHECK
((
char_length
(
architecture
)
<=
255
))
);
CREATE
TABLE
packages_debian_group_distributions
(
id
bigint
NOT
NULL
,
created_at
timestamp
with
time
zone
NOT
NULL
,
updated_at
timestamp
with
time
zone
NOT
NULL
,
group_id
bigint
NOT
NULL
,
creator_id
bigint
,
valid_time_duration_seconds
integer
,
file_store
smallint
DEFAULT
1
NOT
NULL
,
automatic
boolean
DEFAULT
true
NOT
NULL
,
automatic_upgrades
boolean
DEFAULT
false
NOT
NULL
,
codename
text
NOT
NULL
,
suite
text
,
origin
text
,
label
text
,
version
text
,
description
text
,
encrypted_signing_keys
text
,
encrypted_signing_keys_iv
text
,
file
text
,
file_signature
text
,
CONSTRAINT
check_310ac457b8
CHECK
((
char_length
(
description
)
<=
255
)),
CONSTRAINT
check_3d6f87fc31
CHECK
((
char_length
(
file_signature
)
<=
4096
)),
CONSTRAINT
check_3fdadf4a0c
CHECK
((
char_length
(
version
)
<=
255
)),
CONSTRAINT
check_590e18405a
CHECK
((
char_length
(
codename
)
<=
255
)),
CONSTRAINT
check_9b90bc0f07
CHECK
((
char_length
(
encrypted_signing_keys_iv
)
<=
255
)),
CONSTRAINT
check_b057cd840a
CHECK
((
char_length
(
origin
)
<=
255
)),
CONSTRAINT
check_b811ec1218
CHECK
((
char_length
(
encrypted_signing_keys
)
<=
2048
)),
CONSTRAINT
check_be5ed8d307
CHECK
((
char_length
(
file
)
<=
255
)),
CONSTRAINT
check_d3244bfc0b
CHECK
((
char_length
(
label
)
<=
255
)),
CONSTRAINT
check_e7c928a24b
CHECK
((
char_length
(
suite
)
<=
255
))
);
CREATE
SEQUENCE
packages_debian_group_distributions_id_seq
START
WITH
1
INCREMENT
BY
1
NO
MINVALUE
NO
MAXVALUE
CACHE
1
;
ALTER
SEQUENCE
packages_debian_group_distributions_id_seq
OWNED
BY
packages_debian_group_distributions
.
id
;
CREATE
TABLE
packages_debian_project_distributions
(
id
bigint
NOT
NULL
,
created_at
timestamp
with
time
zone
NOT
NULL
,
updated_at
timestamp
with
time
zone
NOT
NULL
,
project_id
bigint
NOT
NULL
,
creator_id
bigint
,
valid_time_duration_seconds
integer
,
file_store
smallint
DEFAULT
1
NOT
NULL
,
automatic
boolean
DEFAULT
true
NOT
NULL
,
automatic_upgrades
boolean
DEFAULT
false
NOT
NULL
,
codename
text
NOT
NULL
,
suite
text
,
origin
text
,
label
text
,
version
text
,
description
text
,
encrypted_signing_keys
text
,
encrypted_signing_keys_iv
text
,
file
text
,
file_signature
text
,
CONSTRAINT
check_6177ccd4a6
CHECK
((
char_length
(
origin
)
<=
255
)),
CONSTRAINT
check_6f6b55a4c4
CHECK
((
char_length
(
label
)
<=
255
)),
CONSTRAINT
check_834dabadb6
CHECK
((
char_length
(
codename
)
<=
255
)),
CONSTRAINT
check_96965792c2
CHECK
((
char_length
(
version
)
<=
255
)),
CONSTRAINT
check_a56ae58a17
CHECK
((
char_length
(
suite
)
<=
255
)),
CONSTRAINT
check_a5a2ac6af2
CHECK
((
char_length
(
file_signature
)
<=
4096
)),
CONSTRAINT
check_b93154339f
CHECK
((
char_length
(
description
)
<=
255
)),
CONSTRAINT
check_c25603a25b
CHECK
((
char_length
(
encrypted_signing_keys
)
<=
2048
)),
CONSTRAINT
check_cb4ac9599e
CHECK
((
char_length
(
file
)
<=
255
)),
CONSTRAINT
check_d488f8cce3
CHECK
((
char_length
(
encrypted_signing_keys_iv
)
<=
255
))
);
CREATE
SEQUENCE
packages_debian_project_distributions_id_seq
START
WITH
1
INCREMENT
BY
1
NO
MINVALUE
NO
MAXVALUE
CACHE
1
;
ALTER
SEQUENCE
packages_debian_project_distributions_id_seq
OWNED
BY
packages_debian_project_distributions
.
id
;
CREATE
TABLE
packages_dependencies
(
id
bigint
NOT
NULL
,
name
character
varying
(
255
)
NOT
NULL
,
...
...
@@ -18657,6 +18739,10 @@ ALTER TABLE ONLY packages_conan_file_metadata ALTER COLUMN id SET DEFAULT nextva
ALTER
TABLE
ONLY
packages_conan_metadata
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'packages_conan_metadata_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
packages_debian_group_distributions
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'packages_debian_group_distributions_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
packages_debian_project_distributions
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'packages_debian_project_distributions_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
packages_dependencies
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'packages_dependencies_id_seq'
::
regclass
);
ALTER
TABLE
ONLY
packages_dependency_links
ALTER
COLUMN
id
SET
DEFAULT
nextval
(
'packages_dependency_links_id_seq'
::
regclass
);
...
...
@@ -20008,6 +20094,12 @@ ALTER TABLE ONLY packages_conan_metadata
ALTER
TABLE
ONLY
packages_debian_file_metadata
ADD
CONSTRAINT
packages_debian_file_metadata_pkey
PRIMARY
KEY
(
package_file_id
);
ALTER
TABLE
ONLY
packages_debian_group_distributions
ADD
CONSTRAINT
packages_debian_group_distributions_pkey
PRIMARY
KEY
(
id
);
ALTER
TABLE
ONLY
packages_debian_project_distributions
ADD
CONSTRAINT
packages_debian_project_distributions_pkey
PRIMARY
KEY
(
id
);
ALTER
TABLE
ONLY
packages_dependencies
ADD
CONSTRAINT
packages_dependencies_pkey
PRIMARY
KEY
(
id
);
...
...
@@ -22190,6 +22282,14 @@ CREATE UNIQUE INDEX index_packages_conan_file_metadata_on_package_file_id ON pac
CREATE
UNIQUE
INDEX
index_packages_conan_metadata_on_package_id_username_channel
ON
packages_conan_metadata
USING
btree
(
package_id
,
package_username
,
package_channel
);
CREATE
INDEX
index_packages_debian_group_distributions_on_creator_id
ON
packages_debian_group_distributions
USING
btree
(
creator_id
);
CREATE
INDEX
index_packages_debian_group_distributions_on_group_id
ON
packages_debian_group_distributions
USING
btree
(
group_id
);
CREATE
INDEX
index_packages_debian_project_distributions_on_creator_id
ON
packages_debian_project_distributions
USING
btree
(
creator_id
);
CREATE
INDEX
index_packages_debian_project_distributions_on_project_id
ON
packages_debian_project_distributions
USING
btree
(
project_id
);
CREATE
UNIQUE
INDEX
index_packages_dependencies_on_name_and_version_pattern
ON
packages_dependencies
USING
btree
(
name
,
version_pattern
);
CREATE
INDEX
index_packages_dependency_links_on_dependency_id
ON
packages_dependency_links
USING
btree
(
dependency_id
);
...
...
@@ -23146,6 +23246,14 @@ CREATE INDEX tmp_index_oauth_applications_on_id_where_trusted ON oauth_applicati
CREATE
INDEX
tmp_index_on_vulnerabilities_non_dismissed
ON
vulnerabilities
USING
btree
(
id
)
WHERE
(
state
<>
2
);
CREATE
UNIQUE
INDEX
uniq_pkgs_debian_group_distributions_group_id_and_codename
ON
packages_debian_group_distributions
USING
btree
(
group_id
,
codename
);
CREATE
UNIQUE
INDEX
uniq_pkgs_debian_group_distributions_group_id_and_suite
ON
packages_debian_group_distributions
USING
btree
(
group_id
,
suite
);
CREATE
UNIQUE
INDEX
uniq_pkgs_debian_project_distributions_project_id_and_codename
ON
packages_debian_project_distributions
USING
btree
(
project_id
,
codename
);
CREATE
UNIQUE
INDEX
uniq_pkgs_debian_project_distributions_project_id_and_suite
ON
packages_debian_project_distributions
USING
btree
(
project_id
,
suite
);
CREATE
UNIQUE
INDEX
unique_merge_request_metrics_by_merge_request_id
ON
merge_request_metrics
USING
btree
(
merge_request_id
);
CREATE
UNIQUE
INDEX
vulnerability_feedback_unique_idx
ON
vulnerability_feedback
USING
btree
(
project_id
,
category
,
feedback_type
,
project_fingerprint
);
...
...
@@ -24148,6 +24256,9 @@ ALTER TABLE ONLY trending_projects
ALTER
TABLE
ONLY
project_deploy_tokens
ADD
CONSTRAINT
fk_rails_0aca134388
FOREIGN
KEY
(
deploy_token_id
)
REFERENCES
deploy_tokens
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
packages_debian_group_distributions
ADD
CONSTRAINT
fk_rails_0adf75c347
FOREIGN
KEY
(
group_id
)
REFERENCES
namespaces
(
id
)
ON
DELETE
RESTRICT
;
ALTER
TABLE
ONLY
packages_conan_file_metadata
ADD
CONSTRAINT
fk_rails_0afabd9328
FOREIGN
KEY
(
package_file_id
)
REFERENCES
packages_package_files
(
id
)
ON
DELETE
CASCADE
;
...
...
@@ -24934,6 +25045,9 @@ ALTER TABLE ONLY alert_management_alert_assignees
ALTER
TABLE
ONLY
scim_identities
ADD
CONSTRAINT
fk_rails_9421a0bffb
FOREIGN
KEY
(
user_id
)
REFERENCES
users
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
packages_debian_project_distributions
ADD
CONSTRAINT
fk_rails_94b95e1f84
FOREIGN
KEY
(
creator_id
)
REFERENCES
users
(
id
)
ON
DELETE
SET
NULL
;
ALTER
TABLE
ONLY
packages_pypi_metadata
ADD
CONSTRAINT
fk_rails_9698717cdd
FOREIGN
KEY
(
package_id
)
REFERENCES
packages_packages
(
id
)
ON
DELETE
CASCADE
;
...
...
@@ -25294,6 +25408,9 @@ ALTER TABLE ONLY user_callouts
ALTER
TABLE
ONLY
vulnerability_feedback
ADD
CONSTRAINT
fk_rails_debd54e456
FOREIGN
KEY
(
project_id
)
REFERENCES
projects
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
packages_debian_project_distributions
ADD
CONSTRAINT
fk_rails_df44271a30
FOREIGN
KEY
(
project_id
)
REFERENCES
projects
(
id
)
ON
DELETE
RESTRICT
;
ALTER
TABLE
ONLY
incident_management_oncall_shifts
ADD
CONSTRAINT
fk_rails_df4feb286a
FOREIGN
KEY
(
rotation_id
)
REFERENCES
incident_management_oncall_rotations
(
id
)
ON
DELETE
CASCADE
;
...
...
@@ -25369,6 +25486,9 @@ ALTER TABLE ONLY snippet_statistics
ALTER
TABLE
ONLY
project_security_settings
ADD
CONSTRAINT
fk_rails_ed4abe1338
FOREIGN
KEY
(
project_id
)
REFERENCES
projects
(
id
)
ON
DELETE
CASCADE
;
ALTER
TABLE
ONLY
packages_debian_group_distributions
ADD
CONSTRAINT
fk_rails_ede0bb937f
FOREIGN
KEY
(
creator_id
)
REFERENCES
users
(
id
)
ON
DELETE
SET
NULL
;
ALTER
TABLE
ONLY
experiment_subjects
ADD
CONSTRAINT
fk_rails_ede5754774
FOREIGN
KEY
(
experiment_id
)
REFERENCES
experiments
(
id
)
ON
DELETE
CASCADE
;
...
...
locale/gitlab.pot
View file @
d46eebd8
...
...
@@ -33255,6 +33255,12 @@ msgstr ""
msgid "has already been taken"
msgstr ""
msgid "has already been taken as Codename"
msgstr ""
msgid "has already been taken as Suite"
msgstr ""
msgid "has been completed."
msgstr ""
...
...
spec/factories/packages/debian/distribution.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:debian_project_distribution
,
class:
'Packages::Debian::ProjectDistribution'
do
container
{
association
(
:project
)
}
sequence
(
:codename
)
{
|
n
|
"project-dist-
#{
n
}
"
}
factory
:debian_group_distribution
,
class:
'Packages::Debian::GroupDistribution'
do
container
{
association
(
:group
)
}
sequence
(
:codename
)
{
|
n
|
"group-dist-
#{
n
}
"
}
end
trait
(
:with_file
)
do
after
(
:build
)
do
|
distribution
,
evaluator
|
distribution
.
file
=
fixture_file_upload
(
'spec/fixtures/packages/debian/README.md'
)
end
end
trait
(
:object_storage
)
do
file_store
{
Packages
::
PackageFileUploader
::
Store
::
REMOTE
}
end
end
end
spec/lib/gitlab/import_export/all_models.yml
View file @
d46eebd8
...
...
@@ -561,6 +561,7 @@ project:
-
alert_management_http_integrations
-
exported_protected_branches
-
incident_management_oncall_schedules
-
debian_distributions
award_emoji
:
-
awardable
-
user
...
...
spec/models/group_spec.rb
View file @
d46eebd8
...
...
@@ -31,6 +31,7 @@ RSpec.describe Group do
it
{
is_expected
.
to
have_one
(
:dependency_proxy_setting
)
}
it
{
is_expected
.
to
have_many
(
:dependency_proxy_blobs
)
}
it
{
is_expected
.
to
have_many
(
:dependency_proxy_manifests
)
}
it
{
is_expected
.
to
have_many
(
:debian_distributions
).
class_name
(
'Packages::Debian::GroupDistribution'
).
dependent
(
:destroy
)
}
describe
'#members & #requesters'
do
let
(
:requester
)
{
create
(
:user
)
}
...
...
@@ -1751,4 +1752,23 @@ RSpec.describe Group do
it
{
is_expected
.
to
eq
(
false
)
}
end
end
describe
'with Debian Distributions'
do
subject
{
create
(
:group
)
}
let!
(
:distributions
)
{
create_list
(
:debian_group_distribution
,
2
,
:with_file
,
container:
subject
)
}
it
'removes distribution files on removal'
do
distribution_file_paths
=
distributions
.
map
do
|
distribution
|
distribution
.
file
.
path
end
expect
{
subject
.
destroy
}
.
to
change
{
distribution_file_paths
.
select
do
|
path
|
File
.
exist?
path
end
.
length
}.
from
(
distribution_file_paths
.
length
).
to
(
0
)
end
end
end
spec/models/packages/debian/group_distribution_spec.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Packages
::
Debian
::
GroupDistribution
do
it_behaves_like
'Debian Distribution'
,
:debian_group_distribution
,
:group
,
false
end
spec/models/packages/debian/project_distribution_spec.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Packages
::
Debian
::
ProjectDistribution
do
it_behaves_like
'Debian Distribution'
,
:debian_project_distribution
,
:project
,
true
end
spec/models/project_spec.rb
View file @
d46eebd8
...
...
@@ -127,6 +127,7 @@ RSpec.describe Project, factory_default: :keep do
it
{
is_expected
.
to
have_many
(
:reviews
).
inverse_of
(
:project
)
}
it
{
is_expected
.
to
have_many
(
:packages
).
class_name
(
'Packages::Package'
)
}
it
{
is_expected
.
to
have_many
(
:package_files
).
class_name
(
'Packages::PackageFile'
)
}
it
{
is_expected
.
to
have_many
(
:debian_distributions
).
class_name
(
'Packages::Debian::ProjectDistribution'
).
dependent
(
:destroy
)
}
it
{
is_expected
.
to
have_many
(
:pipeline_artifacts
)
}
it
{
is_expected
.
to
have_many
(
:terraform_states
).
class_name
(
'Terraform::State'
).
inverse_of
(
:project
)
}
...
...
@@ -6489,6 +6490,25 @@ RSpec.describe Project, factory_default: :keep do
end
end
describe
'with Debian Distributions'
do
subject
{
create
(
:project
)
}
let!
(
:distributions
)
{
create_list
(
:debian_project_distribution
,
2
,
:with_file
,
container:
subject
)
}
it
'removes distribution files on removal'
do
distribution_file_paths
=
distributions
.
map
do
|
distribution
|
distribution
.
file
.
path
end
expect
{
subject
.
destroy
}
.
to
change
{
distribution_file_paths
.
select
do
|
path
|
File
.
exist?
path
end
.
length
}.
from
(
distribution_file_paths
.
length
).
to
(
0
)
end
end
describe
'#environments_for_scope'
do
let_it_be
(
:project
,
reload:
true
)
{
create
(
:project
)
}
...
...
spec/support/shared_examples/models/packages/debian/distribution_shared_examples.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
shared_examples
'Debian Distribution'
do
|
factory
,
container
,
can_freeze
|
let_it_be
(
:distribution_with_suite
,
freeze:
can_freeze
)
{
create
(
factory
,
suite:
'mysuite'
)
}
let_it_be
(
:distribution_with_same_container
,
freeze:
can_freeze
)
{
create
(
factory
,
container:
distribution_with_suite
.
container
)
}
let_it_be
(
:distribution_with_same_codename
,
freeze:
can_freeze
)
{
create
(
factory
,
codename:
distribution_with_suite
.
codename
)
}
let_it_be
(
:distribution_with_same_suite
,
freeze:
can_freeze
)
{
create
(
factory
,
suite:
distribution_with_suite
.
suite
)
}
let_it_be_with_refind
(
:distribution
)
{
create
(
factory
,
container:
distribution_with_suite
.
container
)
}
subject
{
distribution
}
describe
'relationships'
do
it
{
is_expected
.
to
belong_to
(
container
)
}
it
{
is_expected
.
to
belong_to
(
:creator
).
class_name
(
'User'
)
}
end
describe
'validations'
do
describe
"#
#{
container
}
"
do
it
{
is_expected
.
to
validate_presence_of
(
container
)
}
end
describe
"#creator"
do
it
{
is_expected
.
not_to
validate_presence_of
(
:creator
)
}
end
describe
'#codename'
do
it
{
is_expected
.
to
validate_presence_of
(
:codename
)
}
it
{
is_expected
.
to
allow_value
(
'buster'
).
for
(
:codename
)
}
it
{
is_expected
.
to
allow_value
(
'buster-updates'
).
for
(
:codename
)
}
it
{
is_expected
.
to
allow_value
(
'Debian10.5'
).
for
(
:codename
)
}
it
{
is_expected
.
not_to
allow_value
(
'jessie/updates'
).
for
(
:codename
)
}
it
{
is_expected
.
not_to
allow_value
(
'hé'
).
for
(
:codename
)
}
end
describe
'#suite'
do
it
{
is_expected
.
to
allow_value
(
nil
).
for
(
:suite
)
}
it
{
is_expected
.
to
allow_value
(
'testing'
).
for
(
:suite
)
}
it
{
is_expected
.
not_to
allow_value
(
'hé'
).
for
(
:suite
)
}
end
describe
'#unique_debian_suite_and_codename'
do
using
RSpec
::
Parameterized
::
TableSyntax
where
(
:with_existing_suite
,
:suite
,
:codename
,
:errors
)
do
false
|
nil
|
:keep
|
nil
false
|
'testing'
|
:keep
|
nil
false
|
nil
|
:codename
|
[
"Codename has already been taken"
]
false
|
:codename
|
:keep
|
[
"Suite has already been taken as Codename"
]
false
|
:codename
|
:codename
|
[
"Codename has already been taken"
,
"Suite has already been taken as Codename"
]
true
|
nil
|
:keep
|
nil
true
|
'testing'
|
:keep
|
nil
true
|
nil
|
:codename
|
[
"Codename has already been taken"
]
true
|
:codename
|
:keep
|
[
"Suite has already been taken as Codename"
]
true
|
:codename
|
:codename
|
[
"Codename has already been taken"
,
"Suite has already been taken as Codename"
]
true
|
nil
|
:suite
|
[
"Codename has already been taken as Suite"
]
true
|
:suite
|
:keep
|
[
"Suite has already been taken"
]
true
|
:suite
|
:suite
|
[
"Suite has already been taken"
,
"Codename has already been taken as Suite"
]
end
with_them
do
context
factory
do
let
(
:new_distribution
)
{
build
(
factory
,
container:
distribution
.
container
)
}
before
do
distribution
.
update_column
(
:suite
,
'suite-'
+
distribution
.
codename
)
if
with_existing_suite
if
suite
.
is_a?
(
Symbol
)
new_distribution
.
suite
=
distribution
.
send
suite
unless
suite
==
:keep
else
new_distribution
.
suite
=
suite
end
if
codename
.
is_a?
(
Symbol
)
new_distribution
.
codename
=
distribution
.
send
codename
unless
codename
==
:keep
else
new_distribution
.
codename
=
codename
end
end
it
do
if
errors
expect
(
new_distribution
).
not_to
be_valid
expect
(
new_distribution
.
errors
.
to_a
).
to
eq
(
errors
)
else
expect
(
new_distribution
).
to
be_valid
end
end
end
end
end
describe
'#origin'
do
it
{
is_expected
.
to
allow_value
(
nil
).
for
(
:origin
)
}
it
{
is_expected
.
to
allow_value
(
'Debian'
).
for
(
:origin
)
}
it
{
is_expected
.
not_to
allow_value
(
'hé'
).
for
(
:origin
)
}
end
describe
'#label'
do
it
{
is_expected
.
to
allow_value
(
nil
).
for
(
:label
)
}
it
{
is_expected
.
to
allow_value
(
'Debian'
).
for
(
:label
)
}
it
{
is_expected
.
not_to
allow_value
(
'hé'
).
for
(
:label
)
}
end
describe
'#version'
do
it
{
is_expected
.
to
allow_value
(
nil
).
for
(
:version
)
}
it
{
is_expected
.
to
allow_value
(
'10.6'
).
for
(
:version
)
}
it
{
is_expected
.
not_to
allow_value
(
'hé'
).
for
(
:version
)
}
end
describe
'#description'
do
it
{
is_expected
.
to
allow_value
(
nil
).
for
(
:description
)
}
it
{
is_expected
.
to
allow_value
(
'Debian 10.6 Released 26 September 2020'
).
for
(
:description
)
}
it
{
is_expected
.
to
allow_value
(
'Hé !'
).
for
(
:description
)
}
end
describe
'#valid_time_duration_seconds'
do
it
{
is_expected
.
to
allow_value
(
nil
).
for
(
:valid_time_duration_seconds
)
}
it
{
is_expected
.
to
allow_value
(
24
.
hours
.
to_i
).
for
(
:valid_time_duration_seconds
)
}
it
{
is_expected
.
not_to
allow_value
(
12
.
hours
.
to_i
).
for
(
:valid_time_duration_seconds
)
}
end
describe
'#signing_keys'
do
it
{
is_expected
.
to
validate_absence_of
(
:signing_keys
)
}
end
describe
'#file'
do
it
{
is_expected
.
not_to
validate_presence_of
(
:file
)
}
end
describe
'#file_store'
do
it
{
is_expected
.
to
validate_presence_of
(
:file_store
)
}
end
describe
'#file_signature'
do
it
{
is_expected
.
to
validate_absence_of
(
:file_signature
)
}
end
end
describe
'scopes'
do
describe
'.with_container'
do
subject
{
described_class
.
with_container
(
distribution_with_suite
.
container
)
}
it
'does not return other distributions'
do
expect
(
subject
.
to_a
).
to
eq
([
distribution_with_suite
,
distribution
,
distribution_with_same_container
])
end
end
describe
'.with_codename'
do
subject
{
described_class
.
with_codename
(
distribution_with_suite
.
codename
)
}
it
'does not return other distributions'
do
expect
(
subject
.
to_a
).
to
eq
([
distribution_with_suite
,
distribution_with_same_codename
])
end
end
describe
'.with_suite'
do
subject
{
described_class
.
with_suite
(
distribution_with_suite
.
suite
)
}
it
'does not return other distributions'
do
expect
(
subject
.
to_a
).
to
eq
([
distribution_with_suite
,
distribution_with_same_suite
])
end
end
end
describe
'#needs_update?'
do
subject
{
distribution
.
needs_update?
}
context
'with new distribution'
do
let
(
:distribution
)
{
create
(
factory
,
container:
distribution_with_suite
.
container
)
}
it
{
is_expected
.
to
be_truthy
}
end
context
'with file'
do
context
'without valid_time_duration_seconds'
do
let
(
:distribution
)
{
create
(
factory
,
:with_file
,
container:
distribution_with_suite
.
container
)
}
it
{
is_expected
.
to
be_falsey
}
end
context
'with valid_time_duration_seconds'
do
let
(
:distribution
)
{
create
(
factory
,
:with_file
,
container:
distribution_with_suite
.
container
,
valid_time_duration_seconds:
2
.
days
.
to_i
)
}
context
'when not yet expired'
do
it
{
is_expected
.
to
be_falsey
}
end
context
'when expired'
do
it
do
distribution
travel_to
(
4
.
days
.
from_now
)
do
is_expected
.
to
be_truthy
end
end
end
end
end
end
end
spec/uploaders/packages/debian/distribution_release_file_uploader_spec.rb
0 → 100644
View file @
d46eebd8
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Packages
::
Debian
::
DistributionReleaseFileUploader
do
[
:project
,
:group
].
each
do
|
container_type
|
context
"Packages::Debian::
#{
container_type
.
capitalize
}
Distribution"
do
let
(
:factory
)
{
"debian_
#{
container_type
}
_distribution"
}
let
(
:distribution
)
{
create
(
factory
,
:with_file
)
}
let
(
:uploader
)
{
described_class
.
new
(
distribution
,
:file
)
}
let
(
:path
)
{
Gitlab
.
config
.
packages
.
storage_path
}
subject
{
uploader
}
it_behaves_like
"builds correct paths"
,
store_dir:
%r[^
\h
{2}/
\h
{2}/
\h
{64}/debian_
#{
container_type
}
_distribution/
\d
+$]
,
cache_dir:
%r[/packages/tmp/cache$]
,
work_dir:
%r[/packages/tmp/work$]
context
'object store is remote'
do
before
do
stub_package_file_object_storage
end
include_context
'with storage'
,
described_class
::
Store
::
REMOTE
it_behaves_like
"builds correct paths"
,
store_dir:
%r[^
\h
{2}/
\h
{2}/
\h
{64}/debian_
#{
container_type
}
_distribution/
\d
+$]
,
cache_dir:
%r[/packages/tmp/cache$]
,
work_dir:
%r[/packages/tmp/work$]
end
describe
'remote file'
do
let
(
:distribution
)
{
create
(
factory
,
:with_file
,
:object_storage
)
}
context
'with object storage enabled'
do
before
do
stub_package_file_object_storage
end
it
'can store file remotely'
do
allow
(
ObjectStorage
::
BackgroundMoveWorker
).
to
receive
(
:perform_async
)
distribution
expect
(
distribution
.
file_store
).
to
eq
(
described_class
::
Store
::
REMOTE
)
expect
(
distribution
.
file
.
path
).
not_to
be_blank
end
end
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment