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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
1f53cf7c
Commit
1f53cf7c
authored
Aug 03, 2018
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master-ce' into artifact-format-v2-with-parser
parents
d867081d
5f664759
Changes
227
Hide whitespace changes
Inline
Side-by-side
Showing
227 changed files
with
1505 additions
and
656 deletions
+1505
-656
GITLAB_SHELL_VERSION
GITLAB_SHELL_VERSION
+1
-1
Gemfile.lock
Gemfile.lock
+1
-1
app/assets/javascripts/ide/components/new_dropdown/index.vue
app/assets/javascripts/ide/components/new_dropdown/index.vue
+3
-1
app/assets/javascripts/search_autocomplete.js
app/assets/javascripts/search_autocomplete.js
+5
-1
app/controllers/admin/services_controller.rb
app/controllers/admin/services_controller.rb
+3
-1
app/controllers/projects/pipelines_controller.rb
app/controllers/projects/pipelines_controller.rb
+0
-5
app/models/ability.rb
app/models/ability.rb
+2
-0
app/models/abuse_report.rb
app/models/abuse_report.rb
+2
-0
app/models/active_session.rb
app/models/active_session.rb
+2
-0
app/models/appearance.rb
app/models/appearance.rb
+2
-0
app/models/application_setting.rb
app/models/application_setting.rb
+2
-0
app/models/audit_event.rb
app/models/audit_event.rb
+2
-0
app/models/award_emoji.rb
app/models/award_emoji.rb
+2
-0
app/models/badge.rb
app/models/badge.rb
+2
-0
app/models/blob.rb
app/models/blob.rb
+2
-0
app/models/board.rb
app/models/board.rb
+2
-0
app/models/broadcast_message.rb
app/models/broadcast_message.rb
+2
-0
app/models/chat_name.rb
app/models/chat_name.rb
+2
-0
app/models/chat_team.rb
app/models/chat_team.rb
+2
-0
app/models/clusters/applications/ingress.rb
app/models/clusters/applications/ingress.rb
+5
-1
app/models/clusters/applications/jupyter.rb
app/models/clusters/applications/jupyter.rb
+3
-1
app/models/clusters/applications/prometheus.rb
app/models/clusters/applications/prometheus.rb
+2
-1
app/models/clusters/applications/runner.rb
app/models/clusters/applications/runner.rb
+3
-1
app/models/clusters/concerns/application_version.rb
app/models/clusters/concerns/application_version.rb
+17
-0
app/models/commit.rb
app/models/commit.rb
+6
-4
app/models/commit_range.rb
app/models/commit_range.rb
+2
-0
app/models/commit_status.rb
app/models/commit_status.rb
+2
-0
app/models/compare.rb
app/models/compare.rb
+2
-0
app/models/container_repository.rb
app/models/container_repository.rb
+2
-0
app/models/cycle_analytics.rb
app/models/cycle_analytics.rb
+2
-0
app/models/dashboard_milestone.rb
app/models/dashboard_milestone.rb
+2
-0
app/models/deploy_key.rb
app/models/deploy_key.rb
+2
-0
app/models/deploy_keys_project.rb
app/models/deploy_keys_project.rb
+2
-0
app/models/deploy_token.rb
app/models/deploy_token.rb
+9
-1
app/models/deployment.rb
app/models/deployment.rb
+2
-0
app/models/diff_discussion.rb
app/models/diff_discussion.rb
+2
-0
app/models/diff_note.rb
app/models/diff_note.rb
+2
-0
app/models/directly_addressed_user.rb
app/models/directly_addressed_user.rb
+2
-0
app/models/discussion.rb
app/models/discussion.rb
+2
-0
app/models/discussion_note.rb
app/models/discussion_note.rb
+2
-0
app/models/email.rb
app/models/email.rb
+2
-0
app/models/environment.rb
app/models/environment.rb
+3
-1
app/models/epic.rb
app/models/epic.rb
+2
-0
app/models/event.rb
app/models/event.rb
+2
-0
app/models/event_collection.rb
app/models/event_collection.rb
+2
-0
app/models/external_issue.rb
app/models/external_issue.rb
+2
-0
app/models/fork_network.rb
app/models/fork_network.rb
+2
-0
app/models/fork_network_member.rb
app/models/fork_network_member.rb
+2
-0
app/models/forked_project_link.rb
app/models/forked_project_link.rb
+2
-0
app/models/generic_commit_status.rb
app/models/generic_commit_status.rb
+2
-0
app/models/global_label.rb
app/models/global_label.rb
+2
-0
app/models/global_milestone.rb
app/models/global_milestone.rb
+2
-0
app/models/gpg_key.rb
app/models/gpg_key.rb
+2
-0
app/models/gpg_key_subkey.rb
app/models/gpg_key_subkey.rb
+2
-0
app/models/gpg_signature.rb
app/models/gpg_signature.rb
+2
-0
app/models/group.rb
app/models/group.rb
+2
-0
app/models/group_custom_attribute.rb
app/models/group_custom_attribute.rb
+2
-0
app/models/group_label.rb
app/models/group_label.rb
+2
-0
app/models/group_milestone.rb
app/models/group_milestone.rb
+2
-0
app/models/guest.rb
app/models/guest.rb
+2
-0
app/models/identity.rb
app/models/identity.rb
+2
-0
app/models/import_export_upload.rb
app/models/import_export_upload.rb
+3
-0
app/models/individual_note_discussion.rb
app/models/individual_note_discussion.rb
+2
-0
app/models/instance_configuration.rb
app/models/instance_configuration.rb
+2
-0
app/models/internal_id.rb
app/models/internal_id.rb
+2
-0
app/models/issue.rb
app/models/issue.rb
+2
-0
app/models/issue_assignee.rb
app/models/issue_assignee.rb
+2
-0
app/models/issue_collection.rb
app/models/issue_collection.rb
+2
-0
app/models/key.rb
app/models/key.rb
+2
-0
app/models/label.rb
app/models/label.rb
+2
-0
app/models/label_link.rb
app/models/label_link.rb
+2
-0
app/models/label_priority.rb
app/models/label_priority.rb
+2
-0
app/models/legacy_diff_discussion.rb
app/models/legacy_diff_discussion.rb
+2
-0
app/models/legacy_diff_note.rb
app/models/legacy_diff_note.rb
+2
-0
app/models/lfs_file_lock.rb
app/models/lfs_file_lock.rb
+2
-0
app/models/lfs_object.rb
app/models/lfs_object.rb
+2
-0
app/models/lfs_objects_project.rb
app/models/lfs_objects_project.rb
+2
-0
app/models/list.rb
app/models/list.rb
+2
-0
app/models/member.rb
app/models/member.rb
+2
-0
app/models/merge_request.rb
app/models/merge_request.rb
+2
-0
app/models/merge_request_diff.rb
app/models/merge_request_diff.rb
+5
-5
app/models/merge_request_diff_commit.rb
app/models/merge_request_diff_commit.rb
+2
-0
app/models/merge_request_diff_file.rb
app/models/merge_request_diff_file.rb
+2
-0
app/models/merge_requests_closing_issues.rb
app/models/merge_requests_closing_issues.rb
+2
-0
app/models/milestone.rb
app/models/milestone.rb
+2
-0
app/models/namespace.rb
app/models/namespace.rb
+2
-0
app/models/note.rb
app/models/note.rb
+2
-0
app/models/note_diff_file.rb
app/models/note_diff_file.rb
+2
-0
app/models/notification_reason.rb
app/models/notification_reason.rb
+2
-0
app/models/notification_recipient.rb
app/models/notification_recipient.rb
+2
-0
app/models/notification_setting.rb
app/models/notification_setting.rb
+2
-0
app/models/oauth_access_grant.rb
app/models/oauth_access_grant.rb
+2
-0
app/models/oauth_access_token.rb
app/models/oauth_access_token.rb
+2
-0
app/models/out_of_context_discussion.rb
app/models/out_of_context_discussion.rb
+2
-0
app/models/pages_domain.rb
app/models/pages_domain.rb
+2
-0
app/models/personal_access_token.rb
app/models/personal_access_token.rb
+2
-0
app/models/personal_snippet.rb
app/models/personal_snippet.rb
+2
-0
app/models/project.rb
app/models/project.rb
+2
-0
app/models/project_authorization.rb
app/models/project_authorization.rb
+2
-0
app/models/project_auto_devops.rb
app/models/project_auto_devops.rb
+2
-0
app/models/project_ci_cd_setting.rb
app/models/project_ci_cd_setting.rb
+2
-0
app/models/project_custom_attribute.rb
app/models/project_custom_attribute.rb
+2
-0
app/models/project_deploy_token.rb
app/models/project_deploy_token.rb
+2
-0
app/models/project_feature.rb
app/models/project_feature.rb
+2
-0
app/models/project_group_link.rb
app/models/project_group_link.rb
+2
-0
app/models/project_import_data.rb
app/models/project_import_data.rb
+2
-0
app/models/project_import_state.rb
app/models/project_import_state.rb
+2
-0
app/models/project_label.rb
app/models/project_label.rb
+2
-0
app/models/project_snippet.rb
app/models/project_snippet.rb
+2
-0
app/models/project_statistics.rb
app/models/project_statistics.rb
+2
-0
app/models/project_team.rb
app/models/project_team.rb
+2
-0
app/models/protectable_dropdown.rb
app/models/protectable_dropdown.rb
+2
-0
app/models/protected_branch.rb
app/models/protected_branch.rb
+2
-0
app/models/protected_ref_matcher.rb
app/models/protected_ref_matcher.rb
+2
-0
app/models/protected_tag.rb
app/models/protected_tag.rb
+2
-0
app/models/push_event.rb
app/models/push_event.rb
+2
-0
app/models/push_event_payload.rb
app/models/push_event_payload.rb
+2
-0
app/models/readme_blob.rb
app/models/readme_blob.rb
+2
-0
app/models/redirect_route.rb
app/models/redirect_route.rb
+2
-0
app/models/release.rb
app/models/release.rb
+2
-0
app/models/remote_mirror.rb
app/models/remote_mirror.rb
+2
-0
app/models/repository.rb
app/models/repository.rb
+2
-0
app/models/route.rb
app/models/route.rb
+2
-0
app/models/security_event.rb
app/models/security_event.rb
+2
-0
app/models/sent_notification.rb
app/models/sent_notification.rb
+2
-0
app/models/service.rb
app/models/service.rb
+2
-0
app/models/snippet.rb
app/models/snippet.rb
+2
-0
app/models/snippet_blob.rb
app/models/snippet_blob.rb
+2
-0
app/models/spam_log.rb
app/models/spam_log.rb
+2
-0
app/models/subscription.rb
app/models/subscription.rb
+2
-0
app/models/system_note_metadata.rb
app/models/system_note_metadata.rb
+2
-0
app/models/term_agreement.rb
app/models/term_agreement.rb
+2
-0
app/models/timelog.rb
app/models/timelog.rb
+2
-0
app/models/todo.rb
app/models/todo.rb
+2
-0
app/models/tree.rb
app/models/tree.rb
+2
-0
app/models/trending_project.rb
app/models/trending_project.rb
+2
-0
app/models/u2f_registration.rb
app/models/u2f_registration.rb
+2
-0
app/models/upload.rb
app/models/upload.rb
+2
-0
app/models/user.rb
app/models/user.rb
+3
-1
app/models/user_agent_detail.rb
app/models/user_agent_detail.rb
+2
-0
app/models/user_callout.rb
app/models/user_callout.rb
+2
-0
app/models/user_custom_attribute.rb
app/models/user_custom_attribute.rb
+2
-0
app/models/user_interacted_project.rb
app/models/user_interacted_project.rb
+2
-0
app/models/user_synced_attributes_metadata.rb
app/models/user_synced_attributes_metadata.rb
+2
-0
app/models/users_star_project.rb
app/models/users_star_project.rb
+2
-0
app/models/wiki_directory.rb
app/models/wiki_directory.rb
+2
-0
app/models/wiki_page.rb
app/models/wiki_page.rb
+2
-0
app/services/projects/gitlab_projects_import_service.rb
app/services/projects/gitlab_projects_import_service.rb
+1
-2
app/services/users/activity_service.rb
app/services/users/activity_service.rb
+1
-0
app/uploaders/import_export_uploader.rb
app/uploaders/import_export_uploader.rb
+1
-1
app/views/projects/jobs/show.html.haml
app/views/projects/jobs/show.html.haml
+1
-1
app/views/projects/pipelines/_info.html.haml
app/views/projects/pipelines/_info.html.haml
+31
-34
app/views/projects/pipelines/show.html.haml
app/views/projects/pipelines/show.html.haml
+4
-2
app/views/projects/settings/ci_cd/show.html.haml
app/views/projects/settings/ci_cd/show.html.haml
+1
-1
app/workers/create_gpg_signature_worker.rb
app/workers/create_gpg_signature_worker.rb
+4
-0
changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml
...ove-ghost-notification-settings-for-group-and-project.yml
+5
-0
changelogs/unreleased/48246-osw-load-diffs-improvement.yml
changelogs/unreleased/48246-osw-load-diffs-improvement.yml
+5
-0
changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml
...48773-gitlab-project-import-should-use-object-storage.yml
+5
-0
changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml
...by-one-click-install-buttons-should-be-version-locked.yml
+6
-0
changelogs/unreleased/49830-use-helm-272.yml
changelogs/unreleased/49830-use-helm-272.yml
+5
-0
changelogs/unreleased/49851-link-to-runners.yml
changelogs/unreleased/49851-link-to-runners.yml
+6
-0
changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml
...earch-bar-produces-console-error-when-unauthenticated.yml
+5
-0
changelogs/unreleased/frozen-string-enable-app-models.yml
changelogs/unreleased/frozen-string-enable-app-models.yml
+5
-0
changelogs/unreleased/rouge-3-2-0.yml
changelogs/unreleased/rouge-3-2-0.yml
+5
-0
db/migrate/20180710162338_add_foreign_key_from_notification_settings_to_users.rb
...38_add_foreign_key_from_notification_settings_to_users.rb
+30
-0
db/schema.rb
db/schema.rb
+1
-0
doc/ci/yaml/README.md
doc/ci/yaml/README.md
+2
-2
doc/development/performance.md
doc/development/performance.md
+31
-23
doc/user/profile/account/two_factor_authentication.md
doc/user/profile/account/two_factor_authentication.md
+1
-1
lib/backup/repository.rb
lib/backup/repository.rb
+21
-150
lib/gitlab/bare_repository_import/importer.rb
lib/gitlab/bare_repository_import/importer.rb
+26
-10
lib/gitlab/bare_repository_import/repository.rb
lib/gitlab/bare_repository_import/repository.rb
+0
-2
lib/gitlab/cleanup/project_uploads.rb
lib/gitlab/cleanup/project_uploads.rb
+1
-1
lib/gitlab/git/repository.rb
lib/gitlab/git/repository.rb
+0
-13
lib/gitlab/import_export/command_line_util.rb
lib/gitlab/import_export/command_line_util.rb
+15
-0
lib/gitlab/import_export/file_importer.rb
lib/gitlab/import_export/file_importer.rb
+20
-4
lib/gitlab/import_export/importer.rb
lib/gitlab/import_export/importer.rb
+10
-2
lib/gitlab/import_export/uploads_manager.rb
lib/gitlab/import_export/uploads_manager.rb
+1
-4
lib/gitlab/kubernetes/helm.rb
lib/gitlab/kubernetes/helm.rb
+1
-1
lib/gitlab/template_helper.rb
lib/gitlab/template_helper.rb
+10
-4
spec/controllers/admin/services_controller_spec.rb
spec/controllers/admin/services_controller_spec.rb
+1
-1
spec/features/projects/import_export/import_file_object_storage_spec.rb
...projects/import_export/import_file_object_storage_spec.rb
+103
-0
spec/features/projects/import_export/import_file_spec.rb
spec/features/projects/import_export/import_file_spec.rb
+1
-0
spec/javascripts/ide/components/new_dropdown/index_spec.js
spec/javascripts/ide/components/new_dropdown/index_spec.js
+3
-1
spec/lib/backup/repository_spec.rb
spec/lib/backup/repository_spec.rb
+15
-25
spec/lib/gitlab/bare_repository_import/importer_spec.rb
spec/lib/gitlab/bare_repository_import/importer_spec.rb
+26
-28
spec/lib/gitlab/cleanup/project_uploads_spec.rb
spec/lib/gitlab/cleanup/project_uploads_spec.rb
+278
-0
spec/lib/gitlab/git/attributes_at_ref_parser_spec.rb
spec/lib/gitlab/git/attributes_at_ref_parser_spec.rb
+1
-1
spec/lib/gitlab/git/attributes_parser_spec.rb
spec/lib/gitlab/git/attributes_parser_spec.rb
+1
-1
spec/lib/gitlab/git/blame_spec.rb
spec/lib/gitlab/git/blame_spec.rb
+1
-1
spec/lib/gitlab/git/blob_snippet_spec.rb
spec/lib/gitlab/git/blob_snippet_spec.rb
+1
-1
spec/lib/gitlab/git/blob_spec.rb
spec/lib/gitlab/git/blob_spec.rb
+1
-1
spec/lib/gitlab/git/branch_spec.rb
spec/lib/gitlab/git/branch_spec.rb
+1
-1
spec/lib/gitlab/git/commit_spec.rb
spec/lib/gitlab/git/commit_spec.rb
+1
-1
spec/lib/gitlab/git/committer_with_hooks_spec.rb
spec/lib/gitlab/git/committer_with_hooks_spec.rb
+1
-1
spec/lib/gitlab/git/compare_spec.rb
spec/lib/gitlab/git/compare_spec.rb
+1
-1
spec/lib/gitlab/git/diff_collection_spec.rb
spec/lib/gitlab/git/diff_collection_spec.rb
+1
-1
spec/lib/gitlab/git/diff_spec.rb
spec/lib/gitlab/git/diff_spec.rb
+1
-1
spec/lib/gitlab/git/hooks_service_spec.rb
spec/lib/gitlab/git/hooks_service_spec.rb
+1
-1
spec/lib/gitlab/git/index_spec.rb
spec/lib/gitlab/git/index_spec.rb
+1
-1
spec/lib/gitlab/git/remote_repository_spec.rb
spec/lib/gitlab/git/remote_repository_spec.rb
+1
-1
spec/lib/gitlab/git/repository_spec.rb
spec/lib/gitlab/git/repository_spec.rb
+1
-1
spec/lib/gitlab/git/tag_spec.rb
spec/lib/gitlab/git/tag_spec.rb
+1
-1
spec/lib/gitlab/git/tree_spec.rb
spec/lib/gitlab/git/tree_spec.rb
+1
-1
spec/lib/gitlab/gitaly_client/storage_service_spec.rb
spec/lib/gitlab/gitaly_client/storage_service_spec.rb
+13
-0
spec/lib/gitlab/import_export/file_importer_object_storage_spec.rb
...gitlab/import_export/file_importer_object_storage_spec.rb
+89
-0
spec/lib/gitlab/import_export/file_importer_spec.rb
spec/lib/gitlab/import_export/file_importer_spec.rb
+2
-2
spec/lib/gitlab/import_export/importer_object_storage_spec.rb
.../lib/gitlab/import_export/importer_object_storage_spec.rb
+115
-0
spec/lib/gitlab/import_export/importer_spec.rb
spec/lib/gitlab/import_export/importer_spec.rb
+3
-2
spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
+3
-3
spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb
...d_foreign_key_from_notification_settings_to_users_spec.rb
+36
-0
spec/models/clusters/applications/ingress_spec.rb
spec/models/clusters/applications/ingress_spec.rb
+23
-1
spec/models/clusters/applications/jupyter_spec.rb
spec/models/clusters/applications/jupyter_spec.rb
+23
-1
spec/models/clusters/applications/prometheus_spec.rb
spec/models/clusters/applications/prometheus_spec.rb
+22
-0
spec/models/clusters/applications/runner_spec.rb
spec/models/clusters/applications/runner_spec.rb
+23
-1
spec/models/deploy_token_spec.rb
spec/models/deploy_token_spec.rb
+8
-0
spec/models/merge_request_diff_spec.rb
spec/models/merge_request_diff_spec.rb
+7
-0
spec/requests/api/project_import_spec.rb
spec/requests/api/project_import_spec.rb
+2
-0
spec/services/projects/gitlab_projects_import_service_spec.rb
.../services/projects/gitlab_projects_import_service_spec.rb
+1
-1
spec/services/users/activity_service_spec.rb
spec/services/users/activity_service_spec.rb
+12
-0
spec/support/helpers/seed_helper.rb
spec/support/helpers/seed_helper.rb
+0
-6
spec/support/helpers/test_env.rb
spec/support/helpers/test_env.rb
+8
-0
spec/support/shared_examples/helm_generated_script.rb
spec/support/shared_examples/helm_generated_script.rb
+1
-1
spec/support/stored_repositories.rb
spec/support/stored_repositories.rb
+0
-4
spec/tasks/gitlab/backup_rake_spec.rb
spec/tasks/gitlab/backup_rake_spec.rb
+21
-0
spec/tasks/gitlab/cleanup_rake_spec.rb
spec/tasks/gitlab/cleanup_rake_spec.rb
+45
-276
spec/workers/create_gpg_signature_worker_spec.rb
spec/workers/create_gpg_signature_worker_spec.rb
+11
-2
No files found.
GITLAB_SHELL_VERSION
View file @
1f53cf7c
8.
0
.0
8.
1
.0
Gemfile.lock
View file @
1f53cf7c
...
@@ -745,7 +745,7 @@ GEM
...
@@ -745,7 +745,7 @@ GEM
retriable (3.1.1)
retriable (3.1.1)
rinku (2.0.0)
rinku (2.0.0)
rotp (2.1.2)
rotp (2.1.2)
rouge (3.
1.1
)
rouge (3.
2.0
)
rqrcode (0.7.0)
rqrcode (0.7.0)
chunky_png
chunky_png
rqrcode-rails3 (0.1.7)
rqrcode-rails3 (0.1.7)
...
...
app/assets/javascripts/ide/components/new_dropdown/index.vue
View file @
1f53cf7c
...
@@ -35,7 +35,9 @@ export default {
...
@@ -35,7 +35,9 @@ export default {
watch
:
{
watch
:
{
dropdownOpen
()
{
dropdownOpen
()
{
this
.
$nextTick
(()
=>
{
this
.
$nextTick
(()
=>
{
this
.
$refs
.
dropdownMenu
.
scrollIntoView
();
this
.
$refs
.
dropdownMenu
.
scrollIntoView
({
block
:
'
nearest
'
,
});
});
});
},
},
mouseOver
()
{
mouseOver
()
{
...
...
app/assets/javascripts/search_autocomplete.js
View file @
1f53cf7c
...
@@ -137,7 +137,11 @@ export default class SearchAutocomplete {
...
@@ -137,7 +137,11 @@ export default class SearchAutocomplete {
if
(
!
term
)
{
if
(
!
term
)
{
const
contents
=
this
.
getCategoryContents
();
const
contents
=
this
.
getCategoryContents
();
if
(
contents
)
{
if
(
contents
)
{
this
.
searchInput
.
data
(
'
glDropdown
'
).
filter
.
options
.
callback
(
contents
);
const
glDropdownInstance
=
this
.
searchInput
.
data
(
'
glDropdown
'
);
if
(
glDropdownInstance
)
{
glDropdownInstance
.
filter
.
options
.
callback
(
contents
);
}
this
.
enableAutocomplete
();
this
.
enableAutocomplete
();
}
}
return
;
return
;
...
...
app/controllers/admin/services_controller.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Admin::ServicesController
<
Admin
::
ApplicationController
class
Admin::ServicesController
<
Admin
::
ApplicationController
include
ServiceParams
include
ServiceParams
...
@@ -30,7 +32,7 @@ class Admin::ServicesController < Admin::ApplicationController
...
@@ -30,7 +32,7 @@ class Admin::ServicesController < Admin::ApplicationController
def
services_templates
def
services_templates
Service
.
available_services_names
.
map
do
|
service_name
|
Service
.
available_services_names
.
map
do
|
service_name
|
service_template
=
service_name
.
concat
(
"_service"
)
.
camelize
.
constantize
service_template
=
"
#{
service_name
}
_service"
.
camelize
.
constantize
service_template
.
where
(
template:
true
).
first_or_create
service_template
.
where
(
template:
true
).
first_or_create
end
end
end
end
...
...
app/controllers/projects/pipelines_controller.rb
View file @
1f53cf7c
class
Projects::PipelinesController
<
Projects
::
ApplicationController
class
Projects::PipelinesController
<
Projects
::
ApplicationController
before_action
:whitelist_query_limiting
,
only:
[
:create
,
:retry
]
before_action
:whitelist_query_limiting
,
only:
[
:create
,
:retry
]
before_action
:pipeline
,
except:
[
:index
,
:new
,
:create
,
:charts
]
before_action
:pipeline
,
except:
[
:index
,
:new
,
:create
,
:charts
]
before_action
:commit
,
only:
[
:show
,
:builds
,
:failures
]
before_action
:authorize_read_pipeline!
before_action
:authorize_read_pipeline!
before_action
:authorize_create_pipeline!
,
only:
[
:new
,
:create
]
before_action
:authorize_create_pipeline!
,
only:
[
:new
,
:create
]
before_action
:authorize_update_pipeline!
,
only:
[
:retry
,
:cancel
]
before_action
:authorize_update_pipeline!
,
only:
[
:retry
,
:cancel
]
...
@@ -168,10 +167,6 @@ class Projects::PipelinesController < Projects::ApplicationController
...
@@ -168,10 +167,6 @@ class Projects::PipelinesController < Projects::ApplicationController
.
present
(
current_user:
current_user
)
.
present
(
current_user:
current_user
)
end
end
def
commit
@commit
||=
@pipeline
.
commit
end
def
whitelist_query_limiting
def
whitelist_query_limiting
# Also see https://gitlab.com/gitlab-org/gitlab-ce/issues/42343
# Also see https://gitlab.com/gitlab-org/gitlab-ce/issues/42343
Gitlab
::
QueryLimiting
.
whitelist
(
'https://gitlab.com/gitlab-org/gitlab-ce/issues/42339'
)
Gitlab
::
QueryLimiting
.
whitelist
(
'https://gitlab.com/gitlab-org/gitlab-ce/issues/42339'
)
...
...
app/models/ability.rb
View file @
1f53cf7c
# frozen_string_literal: true
require_dependency
'declarative_policy'
require_dependency
'declarative_policy'
class
Ability
class
Ability
...
...
app/models/abuse_report.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
AbuseReport
<
ActiveRecord
::
Base
class
AbuseReport
<
ActiveRecord
::
Base
include
CacheMarkdownField
include
CacheMarkdownField
...
...
app/models/active_session.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ActiveSession
class
ActiveSession
include
ActiveModel
::
Model
include
ActiveModel
::
Model
...
...
app/models/appearance.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Appearance
<
ActiveRecord
::
Base
class
Appearance
<
ActiveRecord
::
Base
include
CacheableAttributes
include
CacheableAttributes
include
CacheMarkdownField
include
CacheMarkdownField
...
...
app/models/application_setting.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ApplicationSetting
<
ActiveRecord
::
Base
class
ApplicationSetting
<
ActiveRecord
::
Base
include
CacheableAttributes
include
CacheableAttributes
include
CacheMarkdownField
include
CacheMarkdownField
...
...
app/models/audit_event.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
AuditEvent
<
ActiveRecord
::
Base
class
AuditEvent
<
ActiveRecord
::
Base
serialize
:details
,
Hash
# rubocop:disable Cop/ActiveRecordSerialize
serialize
:details
,
Hash
# rubocop:disable Cop/ActiveRecordSerialize
...
...
app/models/award_emoji.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
AwardEmoji
<
ActiveRecord
::
Base
class
AwardEmoji
<
ActiveRecord
::
Base
DOWNVOTE_NAME
=
"thumbsdown"
.
freeze
DOWNVOTE_NAME
=
"thumbsdown"
.
freeze
UPVOTE_NAME
=
"thumbsup"
.
freeze
UPVOTE_NAME
=
"thumbsup"
.
freeze
...
...
app/models/badge.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Badge
<
ActiveRecord
::
Base
class
Badge
<
ActiveRecord
::
Base
# This structure sets the placeholders that the urls
# This structure sets the placeholders that the urls
# can have. This hash also sets which action to ask when
# can have. This hash also sets which action to ask when
...
...
app/models/blob.rb
View file @
1f53cf7c
# frozen_string_literal: true
# Blob is a Rails-specific wrapper around Gitlab::Git::Blob objects
# Blob is a Rails-specific wrapper around Gitlab::Git::Blob objects
class
Blob
<
SimpleDelegator
class
Blob
<
SimpleDelegator
CACHE_TIME
=
60
# Cache raw blobs referred to by a (mutable) ref for 1 minute
CACHE_TIME
=
60
# Cache raw blobs referred to by a (mutable) ref for 1 minute
...
...
app/models/board.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Board
<
ActiveRecord
::
Base
class
Board
<
ActiveRecord
::
Base
belongs_to
:group
belongs_to
:group
belongs_to
:project
belongs_to
:project
...
...
app/models/broadcast_message.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
BroadcastMessage
<
ActiveRecord
::
Base
class
BroadcastMessage
<
ActiveRecord
::
Base
include
CacheMarkdownField
include
CacheMarkdownField
include
Sortable
include
Sortable
...
...
app/models/chat_name.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ChatName
<
ActiveRecord
::
Base
class
ChatName
<
ActiveRecord
::
Base
LAST_USED_AT_INTERVAL
=
1
.
hour
LAST_USED_AT_INTERVAL
=
1
.
hour
...
...
app/models/chat_team.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ChatTeam
<
ActiveRecord
::
Base
class
ChatTeam
<
ActiveRecord
::
Base
validates
:team_id
,
presence:
true
validates
:team_id
,
presence:
true
validates
:namespace
,
uniqueness:
true
validates
:namespace
,
uniqueness:
true
...
...
app/models/clusters/applications/ingress.rb
View file @
1f53cf7c
module
Clusters
module
Clusters
module
Applications
module
Applications
class
Ingress
<
ActiveRecord
::
Base
class
Ingress
<
ActiveRecord
::
Base
VERSION
=
'0.23.0'
.
freeze
self
.
table_name
=
'clusters_applications_ingress'
self
.
table_name
=
'clusters_applications_ingress'
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationVersion
include
::
Clusters
::
Concerns
::
ApplicationData
include
::
Clusters
::
Concerns
::
ApplicationData
include
AfterCommitQueue
include
AfterCommitQueue
default_value_for
:ingress_type
,
:nginx
default_value_for
:ingress_type
,
:nginx
default_value_for
:version
,
:nginx
default_value_for
:version
,
VERSION
enum
ingress_type:
{
enum
ingress_type:
{
nginx:
1
nginx:
1
...
@@ -33,6 +36,7 @@ module Clusters
...
@@ -33,6 +36,7 @@ module Clusters
def
install_command
def
install_command
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
name
,
name
,
version:
VERSION
,
chart:
chart
,
chart:
chart
,
values:
values
values:
values
)
)
...
...
app/models/clusters/applications/jupyter.rb
View file @
1f53cf7c
module
Clusters
module
Clusters
module
Applications
module
Applications
class
Jupyter
<
ActiveRecord
::
Base
class
Jupyter
<
ActiveRecord
::
Base
VERSION
=
'
0.0.1
'
.
freeze
VERSION
=
'
v0.6
'
.
freeze
self
.
table_name
=
'clusters_applications_jupyter'
self
.
table_name
=
'clusters_applications_jupyter'
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationVersion
include
::
Clusters
::
Concerns
::
ApplicationData
include
::
Clusters
::
Concerns
::
ApplicationData
belongs_to
:oauth_application
,
class_name:
'Doorkeeper::Application'
belongs_to
:oauth_application
,
class_name:
'Doorkeeper::Application'
...
@@ -36,6 +37,7 @@ module Clusters
...
@@ -36,6 +37,7 @@ module Clusters
def
install_command
def
install_command
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
name
,
name
,
version:
VERSION
,
chart:
chart
,
chart:
chart
,
values:
values
,
values:
values
,
repository:
repository
repository:
repository
...
...
app/models/clusters/applications/prometheus.rb
View file @
1f53cf7c
...
@@ -9,6 +9,7 @@ module Clusters
...
@@ -9,6 +9,7 @@ module Clusters
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationVersion
include
::
Clusters
::
Concerns
::
ApplicationData
include
::
Clusters
::
Concerns
::
ApplicationData
default_value_for
:version
,
VERSION
default_value_for
:version
,
VERSION
...
@@ -44,8 +45,8 @@ module Clusters
...
@@ -44,8 +45,8 @@ module Clusters
def
install_command
def
install_command
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
name
,
name
,
version:
VERSION
,
chart:
chart
,
chart:
chart
,
version:
version
,
values:
values
values:
values
)
)
end
end
...
...
app/models/clusters/applications/runner.rb
View file @
1f53cf7c
module
Clusters
module
Clusters
module
Applications
module
Applications
class
Runner
<
ActiveRecord
::
Base
class
Runner
<
ActiveRecord
::
Base
VERSION
=
'0.1.
13
'
.
freeze
VERSION
=
'0.1.
31
'
.
freeze
self
.
table_name
=
'clusters_applications_runners'
self
.
table_name
=
'clusters_applications_runners'
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationCore
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationStatus
include
::
Clusters
::
Concerns
::
ApplicationVersion
include
::
Clusters
::
Concerns
::
ApplicationData
include
::
Clusters
::
Concerns
::
ApplicationData
belongs_to
:runner
,
class_name:
'Ci::Runner'
,
foreign_key: :runner_id
belongs_to
:runner
,
class_name:
'Ci::Runner'
,
foreign_key: :runner_id
...
@@ -29,6 +30,7 @@ module Clusters
...
@@ -29,6 +30,7 @@ module Clusters
def
install_command
def
install_command
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
Gitlab
::
Kubernetes
::
Helm
::
InstallCommand
.
new
(
name
,
name
,
version:
VERSION
,
chart:
chart
,
chart:
chart
,
values:
values
,
values:
values
,
repository:
repository
repository:
repository
...
...
app/models/clusters/concerns/application_version.rb
0 → 100644
View file @
1f53cf7c
# frozen_string_literal: true
module
Clusters
module
Concerns
module
ApplicationVersion
extend
ActiveSupport
::
Concern
included
do
state_machine
:status
do
after_transition
any
=>
[
:installing
]
do
|
application
|
application
.
update
(
version:
application
.
class
.
const_get
(
:VERSION
))
end
end
end
end
end
end
app/models/commit.rb
View file @
1f53cf7c
# coding: utf-8
# coding: utf-8
# frozen_string_literal: true
class
Commit
class
Commit
extend
ActiveModel
::
Naming
extend
ActiveModel
::
Naming
extend
Gitlab
::
Cache
::
RequestCache
extend
Gitlab
::
Cache
::
RequestCache
...
@@ -339,21 +341,21 @@ class Commit
...
@@ -339,21 +341,21 @@ class Commit
end
end
def
cherry_pick_description
(
user
)
def
cherry_pick_description
(
user
)
message_body
=
"(cherry picked from commit
#{
sha
}
)"
message_body
=
[
"(cherry picked from commit
#{
sha
}
)"
]
if
merged_merge_request?
(
user
)
if
merged_merge_request?
(
user
)
commits_in_merge_request
=
merged_merge_request
(
user
).
commits
commits_in_merge_request
=
merged_merge_request
(
user
).
commits
if
commits_in_merge_request
.
present?
if
commits_in_merge_request
.
present?
message_body
<<
"
\n
"
message_body
<<
""
commits_in_merge_request
.
reverse
.
each
do
|
commit_in_merge
|
commits_in_merge_request
.
reverse
.
each
do
|
commit_in_merge
|
message_body
<<
"
\n
#{
commit_in_merge
.
short_id
}
#{
commit_in_merge
.
title
}
"
message_body
<<
"
#{
commit_in_merge
.
short_id
}
#{
commit_in_merge
.
title
}
"
end
end
end
end
end
end
message_body
message_body
.
join
(
"
\n
"
)
end
end
def
cherry_pick_message
(
user
)
def
cherry_pick_message
(
user
)
...
...
app/models/commit_range.rb
View file @
1f53cf7c
# frozen_string_literal: true
# CommitRange makes it easier to work with commit ranges
# CommitRange makes it easier to work with commit ranges
#
#
# Examples:
# Examples:
...
...
app/models/commit_status.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
CommitStatus
<
ActiveRecord
::
Base
class
CommitStatus
<
ActiveRecord
::
Base
include
HasStatus
include
HasStatus
include
Importable
include
Importable
...
...
app/models/compare.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Compare
class
Compare
include
Gitlab
::
Utils
::
StrongMemoize
include
Gitlab
::
Utils
::
StrongMemoize
...
...
app/models/container_repository.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ContainerRepository
<
ActiveRecord
::
Base
class
ContainerRepository
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
...
...
app/models/cycle_analytics.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
CycleAnalytics
class
CycleAnalytics
STAGES
=
%i[issue plan code test review staging production]
.
freeze
STAGES
=
%i[issue plan code test review staging production]
.
freeze
...
...
app/models/dashboard_milestone.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
DashboardMilestone
<
GlobalMilestone
class
DashboardMilestone
<
GlobalMilestone
def
issues_finder_params
def
issues_finder_params
{
authorized_only:
true
}
{
authorized_only:
true
}
...
...
app/models/deploy_key.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
DeployKey
<
Key
class
DeployKey
<
Key
include
IgnorableColumn
include
IgnorableColumn
...
...
app/models/deploy_keys_project.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
DeployKeysProject
<
ActiveRecord
::
Base
class
DeployKeysProject
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
belongs_to
:deploy_key
,
inverse_of: :deploy_keys_projects
belongs_to
:deploy_key
,
inverse_of: :deploy_keys_projects
...
...
app/models/deploy_token.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
DeployToken
<
ActiveRecord
::
Base
class
DeployToken
<
ActiveRecord
::
Base
include
Expirable
include
Expirable
include
TokenAuthenticatable
include
TokenAuthenticatable
...
@@ -28,7 +30,7 @@ class DeployToken < ActiveRecord::Base
...
@@ -28,7 +30,7 @@ class DeployToken < ActiveRecord::Base
end
end
def
active?
def
active?
!
revoked
&&
expires_at
>
Date
.
today
!
revoked
&&
!
expired?
end
end
def
scopes
def
scopes
...
@@ -61,6 +63,12 @@ class DeployToken < ActiveRecord::Base
...
@@ -61,6 +63,12 @@ class DeployToken < ActiveRecord::Base
private
private
def
expired?
return
false
unless
expires_at
expires_at
<
Date
.
today
end
def
ensure_at_least_one_scope
def
ensure_at_least_one_scope
errors
.
add
(
:base
,
"Scopes can't be blank"
)
unless
read_repository
||
read_registry
errors
.
add
(
:base
,
"Scopes can't be blank"
)
unless
read_repository
||
read_registry
end
end
...
...
app/models/deployment.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Deployment
<
ActiveRecord
::
Base
class
Deployment
<
ActiveRecord
::
Base
include
AtomicInternalId
include
AtomicInternalId
include
IidRoutes
include
IidRoutes
...
...
app/models/diff_discussion.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A discussion on merge request or commit diffs consisting of `DiffNote` notes.
# A discussion on merge request or commit diffs consisting of `DiffNote` notes.
#
#
# A discussion of this type can be resolvable.
# A discussion of this type can be resolvable.
...
...
app/models/diff_note.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A note on merge request or commit diffs
# A note on merge request or commit diffs
#
#
# A note of this type can be resolvable.
# A note of this type can be resolvable.
...
...
app/models/directly_addressed_user.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
DirectlyAddressedUser
class
DirectlyAddressedUser
class
<<
self
class
<<
self
def
reference_pattern
def
reference_pattern
...
...
app/models/discussion.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A non-diff discussion on an issue, merge request, commit, or snippet, consisting of `DiscussionNote` notes.
# A non-diff discussion on an issue, merge request, commit, or snippet, consisting of `DiscussionNote` notes.
#
#
# A discussion of this type can be resolvable.
# A discussion of this type can be resolvable.
...
...
app/models/discussion_note.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A note in a non-diff discussion on an issue, merge request, commit, or snippet.
# A note in a non-diff discussion on an issue, merge request, commit, or snippet.
#
#
# A note of this type can be resolvable.
# A note of this type can be resolvable.
...
...
app/models/email.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Email
<
ActiveRecord
::
Base
class
Email
<
ActiveRecord
::
Base
include
Sortable
include
Sortable
include
Gitlab
::
SQL
::
Pattern
include
Gitlab
::
SQL
::
Pattern
...
...
app/models/environment.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Environment
<
ActiveRecord
::
Base
class
Environment
<
ActiveRecord
::
Base
# Used to generate random suffixes for the slug
# Used to generate random suffixes for the slug
LETTERS
=
'a'
..
'z'
LETTERS
=
'a'
..
'z'
...
@@ -173,7 +175,7 @@ class Environment < ActiveRecord::Base
...
@@ -173,7 +175,7 @@ class Environment < ActiveRecord::Base
# * cannot end with `-`
# * cannot end with `-`
def
generate_slug
def
generate_slug
# Lowercase letters and numbers only
# Lowercase letters and numbers only
slugified
=
name
.
to_s
.
downcase
.
gsub
(
/[^a-z0-9]/
,
'-'
)
slugified
=
+
name
.
to_s
.
downcase
.
gsub
(
/[^a-z0-9]/
,
'-'
)
# Must start with a letter
# Must start with a letter
slugified
=
'env-'
+
slugified
unless
LETTERS
.
cover?
(
slugified
[
0
])
slugified
=
'env-'
+
slugified
unless
LETTERS
.
cover?
(
slugified
[
0
])
...
...
app/models/epic.rb
View file @
1f53cf7c
# frozen_string_literal: true
# Placeholder class for model that is implemented in EE
# Placeholder class for model that is implemented in EE
# It reserves '&' as a reference prefix, but the table does not exists in CE
# It reserves '&' as a reference prefix, but the table does not exists in CE
class
Epic
<
ActiveRecord
::
Base
class
Epic
<
ActiveRecord
::
Base
...
...
app/models/event.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Event
<
ActiveRecord
::
Base
class
Event
<
ActiveRecord
::
Base
include
Sortable
include
Sortable
include
IgnorableColumn
include
IgnorableColumn
...
...
app/models/event_collection.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A collection of events to display in an event list.
# A collection of events to display in an event list.
#
#
# An EventCollection is meant to be used for displaying events to a user (e.g.
# An EventCollection is meant to be used for displaying events to a user (e.g.
...
...
app/models/external_issue.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ExternalIssue
class
ExternalIssue
include
Referable
include
Referable
...
...
app/models/fork_network.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ForkNetwork
<
ActiveRecord
::
Base
class
ForkNetwork
<
ActiveRecord
::
Base
belongs_to
:root_project
,
class_name:
'Project'
belongs_to
:root_project
,
class_name:
'Project'
has_many
:fork_network_members
has_many
:fork_network_members
...
...
app/models/fork_network_member.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ForkNetworkMember
<
ActiveRecord
::
Base
class
ForkNetworkMember
<
ActiveRecord
::
Base
belongs_to
:fork_network
belongs_to
:fork_network
belongs_to
:project
belongs_to
:project
...
...
app/models/forked_project_link.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ForkedProjectLink
<
ActiveRecord
::
Base
class
ForkedProjectLink
<
ActiveRecord
::
Base
belongs_to
:forked_to_project
,
->
{
where
.
not
(
pending_delete:
true
)
},
class_name:
'Project'
belongs_to
:forked_to_project
,
->
{
where
.
not
(
pending_delete:
true
)
},
class_name:
'Project'
belongs_to
:forked_from_project
,
->
{
where
.
not
(
pending_delete:
true
)
},
class_name:
'Project'
belongs_to
:forked_from_project
,
->
{
where
.
not
(
pending_delete:
true
)
},
class_name:
'Project'
...
...
app/models/generic_commit_status.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GenericCommitStatus
<
CommitStatus
class
GenericCommitStatus
<
CommitStatus
before_validation
:set_default_values
before_validation
:set_default_values
...
...
app/models/global_label.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GlobalLabel
class
GlobalLabel
attr_accessor
:title
,
:labels
attr_accessor
:title
,
:labels
alias_attribute
:name
,
:title
alias_attribute
:name
,
:title
...
...
app/models/global_milestone.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GlobalMilestone
class
GlobalMilestone
include
Milestoneish
include
Milestoneish
...
...
app/models/gpg_key.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GpgKey
<
ActiveRecord
::
Base
class
GpgKey
<
ActiveRecord
::
Base
KEY_PREFIX
=
'-----BEGIN PGP PUBLIC KEY BLOCK-----'
.
freeze
KEY_PREFIX
=
'-----BEGIN PGP PUBLIC KEY BLOCK-----'
.
freeze
KEY_SUFFIX
=
'-----END PGP PUBLIC KEY BLOCK-----'
.
freeze
KEY_SUFFIX
=
'-----END PGP PUBLIC KEY BLOCK-----'
.
freeze
...
...
app/models/gpg_key_subkey.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GpgKeySubkey
<
ActiveRecord
::
Base
class
GpgKeySubkey
<
ActiveRecord
::
Base
include
ShaAttribute
include
ShaAttribute
...
...
app/models/gpg_signature.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GpgSignature
<
ActiveRecord
::
Base
class
GpgSignature
<
ActiveRecord
::
Base
include
ShaAttribute
include
ShaAttribute
...
...
app/models/group.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'carrierwave/orm/activerecord'
require
'carrierwave/orm/activerecord'
class
Group
<
Namespace
class
Group
<
Namespace
...
...
app/models/group_custom_attribute.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GroupCustomAttribute
<
ActiveRecord
::
Base
class
GroupCustomAttribute
<
ActiveRecord
::
Base
belongs_to
:group
belongs_to
:group
...
...
app/models/group_label.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GroupLabel
<
Label
class
GroupLabel
<
Label
belongs_to
:group
belongs_to
:group
...
...
app/models/group_milestone.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
GroupMilestone
<
GlobalMilestone
class
GroupMilestone
<
GlobalMilestone
attr_accessor
:group
attr_accessor
:group
...
...
app/models/guest.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Guest
class
Guest
class
<<
self
class
<<
self
def
can?
(
action
,
subject
=
:global
)
def
can?
(
action
,
subject
=
:global
)
...
...
app/models/identity.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Identity
<
ActiveRecord
::
Base
class
Identity
<
ActiveRecord
::
Base
def
self
.
uniqueness_scope
def
self
.
uniqueness_scope
:provider
:provider
...
...
app/models/import_export_upload.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ImportExportUpload
<
ActiveRecord
::
Base
class
ImportExportUpload
<
ActiveRecord
::
Base
include
WithUploads
include
WithUploads
include
ObjectStorage
::
BackgroundMove
include
ObjectStorage
::
BackgroundMove
belongs_to
:project
belongs_to
:project
# These hold the project Import/Export archives (.tar.gz files)
mount_uploader
:import_file
,
ImportExportUploader
mount_uploader
:import_file
,
ImportExportUploader
mount_uploader
:export_file
,
ImportExportUploader
mount_uploader
:export_file
,
ImportExportUploader
...
...
app/models/individual_note_discussion.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A discussion to wrap a single `Note` note on the root of an issue, merge request,
# A discussion to wrap a single `Note` note on the root of an issue, merge request,
# commit, or snippet, that is not displayed as a discussion.
# commit, or snippet, that is not displayed as a discussion.
#
#
...
...
app/models/instance_configuration.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'resolv'
require
'resolv'
class
InstanceConfiguration
class
InstanceConfiguration
...
...
app/models/internal_id.rb
View file @
1f53cf7c
# frozen_string_literal: true
# An InternalId is a strictly monotone sequence of integers
# An InternalId is a strictly monotone sequence of integers
# generated for a given scope and usage.
# generated for a given scope and usage.
#
#
...
...
app/models/issue.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'carrierwave/orm/activerecord'
require
'carrierwave/orm/activerecord'
class
Issue
<
ActiveRecord
::
Base
class
Issue
<
ActiveRecord
::
Base
...
...
app/models/issue_assignee.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
IssueAssignee
<
ActiveRecord
::
Base
class
IssueAssignee
<
ActiveRecord
::
Base
belongs_to
:issue
belongs_to
:issue
belongs_to
:assignee
,
class_name:
"User"
,
foreign_key: :user_id
belongs_to
:assignee
,
class_name:
"User"
,
foreign_key: :user_id
...
...
app/models/issue_collection.rb
View file @
1f53cf7c
# frozen_string_literal: true
# IssueCollection can be used to reduce a list of issues down to a subset.
# IssueCollection can be used to reduce a list of issues down to a subset.
#
#
# IssueCollection is not meant to be some sort of Enumerable, instead it's meant
# IssueCollection is not meant to be some sort of Enumerable, instead it's meant
...
...
app/models/key.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'digest/md5'
require
'digest/md5'
class
Key
<
ActiveRecord
::
Base
class
Key
<
ActiveRecord
::
Base
...
...
app/models/label.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Label
<
ActiveRecord
::
Base
class
Label
<
ActiveRecord
::
Base
include
CacheMarkdownField
include
CacheMarkdownField
include
Referable
include
Referable
...
...
app/models/label_link.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
LabelLink
<
ActiveRecord
::
Base
class
LabelLink
<
ActiveRecord
::
Base
include
Importable
include
Importable
...
...
app/models/label_priority.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
LabelPriority
<
ActiveRecord
::
Base
class
LabelPriority
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
belongs_to
:label
belongs_to
:label
...
...
app/models/legacy_diff_discussion.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A discussion on merge request or commit diffs consisting of `LegacyDiffNote` notes.
# A discussion on merge request or commit diffs consisting of `LegacyDiffNote` notes.
#
#
# All new diff discussions are of the type `DiffDiscussion`, but any diff discussions created
# All new diff discussions are of the type `DiffDiscussion`, but any diff discussions created
...
...
app/models/legacy_diff_note.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A note on merge request or commit diffs, using the legacy implementation.
# A note on merge request or commit diffs, using the legacy implementation.
#
#
# All new diff notes are of the type `DiffNote`, but any diff notes created
# All new diff notes are of the type `DiffNote`, but any diff notes created
...
...
app/models/lfs_file_lock.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
LfsFileLock
<
ActiveRecord
::
Base
class
LfsFileLock
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
belongs_to
:user
belongs_to
:user
...
...
app/models/lfs_object.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
LfsObject
<
ActiveRecord
::
Base
class
LfsObject
<
ActiveRecord
::
Base
include
AfterCommitQueue
include
AfterCommitQueue
include
ObjectStorage
::
BackgroundMove
include
ObjectStorage
::
BackgroundMove
...
...
app/models/lfs_objects_project.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
LfsObjectsProject
<
ActiveRecord
::
Base
class
LfsObjectsProject
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
belongs_to
:lfs_object
belongs_to
:lfs_object
...
...
app/models/list.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
List
<
ActiveRecord
::
Base
class
List
<
ActiveRecord
::
Base
belongs_to
:board
belongs_to
:board
belongs_to
:label
belongs_to
:label
...
...
app/models/member.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Member
<
ActiveRecord
::
Base
class
Member
<
ActiveRecord
::
Base
include
AfterCommitQueue
include
AfterCommitQueue
include
Sortable
include
Sortable
...
...
app/models/merge_request.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
MergeRequest
<
ActiveRecord
::
Base
class
MergeRequest
<
ActiveRecord
::
Base
include
AtomicInternalId
include
AtomicInternalId
include
IidRoutes
include
IidRoutes
...
...
app/models/merge_request_diff.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
MergeRequestDiff
<
ActiveRecord
::
Base
class
MergeRequestDiff
<
ActiveRecord
::
Base
include
Sortable
include
Sortable
include
Importable
include
Importable
...
@@ -249,15 +251,13 @@ class MergeRequestDiff < ActiveRecord::Base
...
@@ -249,15 +251,13 @@ class MergeRequestDiff < ActiveRecord::Base
end
end
def
load_diffs
(
options
)
def
load_diffs
(
options
)
raw
=
merge_request_diff_files
.
map
(
&
:to_hash
)
collection
=
merge_request_diff_files
if
paths
=
options
[
:paths
]
if
paths
=
options
[
:paths
]
raw
=
raw
.
select
do
|
diff
|
collection
=
collection
.
where
(
'old_path IN (?) OR new_path IN (?)'
,
paths
,
paths
)
paths
.
include?
(
diff
[
:old_path
])
||
paths
.
include?
(
diff
[
:new_path
])
end
end
end
Gitlab
::
Git
::
DiffCollection
.
new
(
raw
,
options
)
Gitlab
::
Git
::
DiffCollection
.
new
(
collection
.
map
(
&
:to_hash
)
,
options
)
end
end
def
load_commits
def
load_commits
...
...
app/models/merge_request_diff_commit.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
MergeRequestDiffCommit
<
ActiveRecord
::
Base
class
MergeRequestDiffCommit
<
ActiveRecord
::
Base
include
ShaAttribute
include
ShaAttribute
...
...
app/models/merge_request_diff_file.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
MergeRequestDiffFile
<
ActiveRecord
::
Base
class
MergeRequestDiffFile
<
ActiveRecord
::
Base
include
Gitlab
::
EncodingHelper
include
Gitlab
::
EncodingHelper
include
DiffFile
include
DiffFile
...
...
app/models/merge_requests_closing_issues.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
MergeRequestsClosingIssues
<
ActiveRecord
::
Base
class
MergeRequestsClosingIssues
<
ActiveRecord
::
Base
belongs_to
:merge_request
belongs_to
:merge_request
belongs_to
:issue
belongs_to
:issue
...
...
app/models/milestone.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Milestone
<
ActiveRecord
::
Base
class
Milestone
<
ActiveRecord
::
Base
# Represents a "No Milestone" state used for filtering Issues and Merge
# Represents a "No Milestone" state used for filtering Issues and Merge
# Requests that have no milestone assigned.
# Requests that have no milestone assigned.
...
...
app/models/namespace.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Namespace
<
ActiveRecord
::
Base
class
Namespace
<
ActiveRecord
::
Base
include
CacheMarkdownField
include
CacheMarkdownField
include
Sortable
include
Sortable
...
...
app/models/note.rb
View file @
1f53cf7c
# frozen_string_literal: true
# A note on the root of an issue, merge request, commit, or snippet.
# A note on the root of an issue, merge request, commit, or snippet.
#
#
# A note of this type is never resolvable.
# A note of this type is never resolvable.
...
...
app/models/note_diff_file.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
NoteDiffFile
<
ActiveRecord
::
Base
class
NoteDiffFile
<
ActiveRecord
::
Base
include
DiffFile
include
DiffFile
...
...
app/models/notification_reason.rb
View file @
1f53cf7c
# frozen_string_literal: true
# Holds reasons for a notification to have been sent as well as a priority list to select which reason to use
# Holds reasons for a notification to have been sent as well as a priority list to select which reason to use
# above the rest
# above the rest
class
NotificationReason
class
NotificationReason
...
...
app/models/notification_recipient.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
NotificationRecipient
class
NotificationRecipient
include
Gitlab
::
Utils
::
StrongMemoize
include
Gitlab
::
Utils
::
StrongMemoize
...
...
app/models/notification_setting.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
NotificationSetting
<
ActiveRecord
::
Base
class
NotificationSetting
<
ActiveRecord
::
Base
include
IgnorableColumn
include
IgnorableColumn
...
...
app/models/oauth_access_grant.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
OauthAccessGrant
<
Doorkeeper
::
AccessGrant
class
OauthAccessGrant
<
Doorkeeper
::
AccessGrant
belongs_to
:resource_owner
,
class_name:
'User'
belongs_to
:resource_owner
,
class_name:
'User'
belongs_to
:application
,
class_name:
'Doorkeeper::Application'
belongs_to
:application
,
class_name:
'Doorkeeper::Application'
...
...
app/models/oauth_access_token.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
OauthAccessToken
<
Doorkeeper
::
AccessToken
class
OauthAccessToken
<
Doorkeeper
::
AccessToken
belongs_to
:resource_owner
,
class_name:
'User'
belongs_to
:resource_owner
,
class_name:
'User'
belongs_to
:application
,
class_name:
'Doorkeeper::Application'
belongs_to
:application
,
class_name:
'Doorkeeper::Application'
...
...
app/models/out_of_context_discussion.rb
View file @
1f53cf7c
# frozen_string_literal: true
# When notes on a commit are displayed in the context of a merge request that
# When notes on a commit are displayed in the context of a merge request that
# contains that commit, they are displayed as if they were a discussion.
# contains that commit, they are displayed as if they were a discussion.
#
#
...
...
app/models/pages_domain.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
PagesDomain
<
ActiveRecord
::
Base
class
PagesDomain
<
ActiveRecord
::
Base
VERIFICATION_KEY
=
'gitlab-pages-verification-code'
.
freeze
VERIFICATION_KEY
=
'gitlab-pages-verification-code'
.
freeze
VERIFICATION_THRESHOLD
=
3
.
days
.
freeze
VERIFICATION_THRESHOLD
=
3
.
days
.
freeze
...
...
app/models/personal_access_token.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
PersonalAccessToken
<
ActiveRecord
::
Base
class
PersonalAccessToken
<
ActiveRecord
::
Base
include
Expirable
include
Expirable
include
TokenAuthenticatable
include
TokenAuthenticatable
...
...
app/models/personal_snippet.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
PersonalSnippet
<
Snippet
class
PersonalSnippet
<
Snippet
include
WithUploads
include
WithUploads
end
end
app/models/project.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'carrierwave/orm/activerecord'
require
'carrierwave/orm/activerecord'
class
Project
<
ActiveRecord
::
Base
class
Project
<
ActiveRecord
::
Base
...
...
app/models/project_authorization.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectAuthorization
<
ActiveRecord
::
Base
class
ProjectAuthorization
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
belongs_to
:project
belongs_to
:project
...
...
app/models/project_auto_devops.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectAutoDevops
<
ActiveRecord
::
Base
class
ProjectAutoDevops
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
...
...
app/models/project_ci_cd_setting.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectCiCdSetting
<
ActiveRecord
::
Base
class
ProjectCiCdSetting
<
ActiveRecord
::
Base
belongs_to
:project
,
inverse_of: :ci_cd_settings
belongs_to
:project
,
inverse_of: :ci_cd_settings
...
...
app/models/project_custom_attribute.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectCustomAttribute
<
ActiveRecord
::
Base
class
ProjectCustomAttribute
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
...
...
app/models/project_deploy_token.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectDeployToken
<
ActiveRecord
::
Base
class
ProjectDeployToken
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
belongs_to
:deploy_token
,
inverse_of: :project_deploy_tokens
belongs_to
:deploy_token
,
inverse_of: :project_deploy_tokens
...
...
app/models/project_feature.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectFeature
<
ActiveRecord
::
Base
class
ProjectFeature
<
ActiveRecord
::
Base
# == Project features permissions
# == Project features permissions
#
#
...
...
app/models/project_group_link.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectGroupLink
<
ActiveRecord
::
Base
class
ProjectGroupLink
<
ActiveRecord
::
Base
include
Expirable
include
Expirable
...
...
app/models/project_import_data.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'carrierwave/orm/activerecord'
require
'carrierwave/orm/activerecord'
class
ProjectImportData
<
ActiveRecord
::
Base
class
ProjectImportData
<
ActiveRecord
::
Base
...
...
app/models/project_import_state.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectImportState
<
ActiveRecord
::
Base
class
ProjectImportState
<
ActiveRecord
::
Base
include
AfterCommitQueue
include
AfterCommitQueue
...
...
app/models/project_label.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectLabel
<
Label
class
ProjectLabel
<
Label
MAX_NUMBER_OF_PRIORITIES
=
1
MAX_NUMBER_OF_PRIORITIES
=
1
...
...
app/models/project_snippet.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectSnippet
<
Snippet
class
ProjectSnippet
<
Snippet
belongs_to
:project
belongs_to
:project
belongs_to
:author
,
class_name:
"User"
belongs_to
:author
,
class_name:
"User"
...
...
app/models/project_statistics.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectStatistics
<
ActiveRecord
::
Base
class
ProjectStatistics
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
belongs_to
:namespace
belongs_to
:namespace
...
...
app/models/project_team.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProjectTeam
class
ProjectTeam
include
BulkMemberAccessLoad
include
BulkMemberAccessLoad
...
...
app/models/protectable_dropdown.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProtectableDropdown
class
ProtectableDropdown
REF_TYPES
=
%i[branches tags]
.
freeze
REF_TYPES
=
%i[branches tags]
.
freeze
...
...
app/models/protected_branch.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProtectedBranch
<
ActiveRecord
::
Base
class
ProtectedBranch
<
ActiveRecord
::
Base
include
Gitlab
::
ShellAdapter
include
Gitlab
::
ShellAdapter
include
ProtectedRef
include
ProtectedRef
...
...
app/models/protected_ref_matcher.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProtectedRefMatcher
class
ProtectedRefMatcher
def
initialize
(
protected_ref
)
def
initialize
(
protected_ref
)
@protected_ref
=
protected_ref
@protected_ref
=
protected_ref
...
...
app/models/protected_tag.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ProtectedTag
<
ActiveRecord
::
Base
class
ProtectedTag
<
ActiveRecord
::
Base
include
Gitlab
::
ShellAdapter
include
Gitlab
::
ShellAdapter
include
ProtectedRef
include
ProtectedRef
...
...
app/models/push_event.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
PushEvent
<
Event
class
PushEvent
<
Event
# This validation exists so we can't accidentally use PushEvent with a
# This validation exists so we can't accidentally use PushEvent with a
# different "action" value.
# different "action" value.
...
...
app/models/push_event_payload.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
PushEventPayload
<
ActiveRecord
::
Base
class
PushEventPayload
<
ActiveRecord
::
Base
include
ShaAttribute
include
ShaAttribute
...
...
app/models/readme_blob.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
ReadmeBlob
<
SimpleDelegator
class
ReadmeBlob
<
SimpleDelegator
attr_reader
:repository
attr_reader
:repository
...
...
app/models/redirect_route.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
RedirectRoute
<
ActiveRecord
::
Base
class
RedirectRoute
<
ActiveRecord
::
Base
belongs_to
:source
,
polymorphic:
true
# rubocop:disable Cop/PolymorphicAssociations
belongs_to
:source
,
polymorphic:
true
# rubocop:disable Cop/PolymorphicAssociations
...
...
app/models/release.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Release
<
ActiveRecord
::
Base
class
Release
<
ActiveRecord
::
Base
include
CacheMarkdownField
include
CacheMarkdownField
...
...
app/models/remote_mirror.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
RemoteMirror
<
ActiveRecord
::
Base
class
RemoteMirror
<
ActiveRecord
::
Base
include
AfterCommitQueue
include
AfterCommitQueue
...
...
app/models/repository.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'securerandom'
require
'securerandom'
class
Repository
class
Repository
...
...
app/models/route.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Route
<
ActiveRecord
::
Base
class
Route
<
ActiveRecord
::
Base
include
CaseSensitivity
include
CaseSensitivity
...
...
app/models/security_event.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
SecurityEvent
<
AuditEvent
class
SecurityEvent
<
AuditEvent
end
end
app/models/sent_notification.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
SentNotification
<
ActiveRecord
::
Base
class
SentNotification
<
ActiveRecord
::
Base
serialize
:position
,
Gitlab
::
Diff
::
Position
# rubocop:disable Cop/ActiveRecordSerialize
serialize
:position
,
Gitlab
::
Diff
::
Position
# rubocop:disable Cop/ActiveRecordSerialize
...
...
app/models/service.rb
View file @
1f53cf7c
# frozen_string_literal: true
# To add new service you should build a class inherited from Service
# To add new service you should build a class inherited from Service
# and implement a set of methods
# and implement a set of methods
class
Service
<
ActiveRecord
::
Base
class
Service
<
ActiveRecord
::
Base
...
...
app/models/snippet.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Snippet
<
ActiveRecord
::
Base
class
Snippet
<
ActiveRecord
::
Base
include
Gitlab
::
VisibilityLevel
include
Gitlab
::
VisibilityLevel
include
CacheMarkdownField
include
CacheMarkdownField
...
...
app/models/snippet_blob.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
SnippetBlob
class
SnippetBlob
include
BlobLike
include
BlobLike
...
...
app/models/spam_log.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
SpamLog
<
ActiveRecord
::
Base
class
SpamLog
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
...
...
app/models/subscription.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Subscription
<
ActiveRecord
::
Base
class
Subscription
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
belongs_to
:project
belongs_to
:project
...
...
app/models/system_note_metadata.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
SystemNoteMetadata
<
ActiveRecord
::
Base
class
SystemNoteMetadata
<
ActiveRecord
::
Base
# These notes's action text might contain a reference that is external.
# These notes's action text might contain a reference that is external.
# We should always force a deep validation upon references that are found
# We should always force a deep validation upon references that are found
...
...
app/models/term_agreement.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
TermAgreement
<
ActiveRecord
::
Base
class
TermAgreement
<
ActiveRecord
::
Base
belongs_to
:term
,
class_name:
'ApplicationSetting::Term'
belongs_to
:term
,
class_name:
'ApplicationSetting::Term'
belongs_to
:user
belongs_to
:user
...
...
app/models/timelog.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Timelog
<
ActiveRecord
::
Base
class
Timelog
<
ActiveRecord
::
Base
validates
:time_spent
,
:user
,
presence:
true
validates
:time_spent
,
:user
,
presence:
true
validate
:issuable_id_is_present
validate
:issuable_id_is_present
...
...
app/models/todo.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Todo
<
ActiveRecord
::
Base
class
Todo
<
ActiveRecord
::
Base
include
Sortable
include
Sortable
...
...
app/models/tree.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Tree
class
Tree
include
Gitlab
::
MarkupHelper
include
Gitlab
::
MarkupHelper
...
...
app/models/trending_project.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
TrendingProject
<
ActiveRecord
::
Base
class
TrendingProject
<
ActiveRecord
::
Base
belongs_to
:project
belongs_to
:project
...
...
app/models/u2f_registration.rb
View file @
1f53cf7c
# frozen_string_literal: true
# Registration information for U2F (universal 2nd factor) devices, like Yubikeys
# Registration information for U2F (universal 2nd factor) devices, like Yubikeys
class
U2fRegistration
<
ActiveRecord
::
Base
class
U2fRegistration
<
ActiveRecord
::
Base
...
...
app/models/upload.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
Upload
<
ActiveRecord
::
Base
class
Upload
<
ActiveRecord
::
Base
# Upper limit for foreground checksum processing
# Upper limit for foreground checksum processing
CHECKSUM_THRESHOLD
=
100
.
megabytes
CHECKSUM_THRESHOLD
=
100
.
megabytes
...
...
app/models/user.rb
View file @
1f53cf7c
# frozen_string_literal: true
require
'carrierwave/orm/activerecord'
require
'carrierwave/orm/activerecord'
class
User
<
ActiveRecord
::
Base
class
User
<
ActiveRecord
::
Base
...
@@ -128,7 +130,7 @@ class User < ActiveRecord::Base
...
@@ -128,7 +130,7 @@ class User < ActiveRecord::Base
has_many
:builds
,
dependent: :nullify
,
class_name:
'Ci::Build'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:builds
,
dependent: :nullify
,
class_name:
'Ci::Build'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:pipelines
,
dependent: :nullify
,
class_name:
'Ci::Pipeline'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:pipelines
,
dependent: :nullify
,
class_name:
'Ci::Pipeline'
# rubocop:disable Cop/ActiveRecordDependent
has_many
:todos
has_many
:todos
has_many
:notification_settings
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:notification_settings
has_many
:award_emoji
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:award_emoji
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_many
:triggers
,
dependent: :destroy
,
class_name:
'Ci::Trigger'
,
foreign_key: :owner_id
# rubocop:disable Cop/ActiveRecordDependent
has_many
:triggers
,
dependent: :destroy
,
class_name:
'Ci::Trigger'
,
foreign_key: :owner_id
# rubocop:disable Cop/ActiveRecordDependent
...
...
app/models/user_agent_detail.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
UserAgentDetail
<
ActiveRecord
::
Base
class
UserAgentDetail
<
ActiveRecord
::
Base
belongs_to
:subject
,
polymorphic:
true
# rubocop:disable Cop/PolymorphicAssociations
belongs_to
:subject
,
polymorphic:
true
# rubocop:disable Cop/PolymorphicAssociations
...
...
app/models/user_callout.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
UserCallout
<
ActiveRecord
::
Base
class
UserCallout
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
...
...
app/models/user_custom_attribute.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
UserCustomAttribute
<
ActiveRecord
::
Base
class
UserCustomAttribute
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
...
...
app/models/user_interacted_project.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
UserInteractedProject
<
ActiveRecord
::
Base
class
UserInteractedProject
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
belongs_to
:project
belongs_to
:project
...
...
app/models/user_synced_attributes_metadata.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
UserSyncedAttributesMetadata
<
ActiveRecord
::
Base
class
UserSyncedAttributesMetadata
<
ActiveRecord
::
Base
belongs_to
:user
belongs_to
:user
...
...
app/models/users_star_project.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
UsersStarProject
<
ActiveRecord
::
Base
class
UsersStarProject
<
ActiveRecord
::
Base
belongs_to
:project
,
counter_cache: :star_count
,
touch:
true
belongs_to
:project
,
counter_cache: :star_count
,
touch:
true
belongs_to
:user
belongs_to
:user
...
...
app/models/wiki_directory.rb
View file @
1f53cf7c
# frozen_string_literal: true
class
WikiDirectory
class
WikiDirectory
include
ActiveModel
::
Validations
include
ActiveModel
::
Validations
...
...
app/models/wiki_page.rb
View file @
1f53cf7c
# frozen_string_literal: true
# rubocop:disable Rails/ActiveRecordAliases
# rubocop:disable Rails/ActiveRecordAliases
class
WikiPage
class
WikiPage
PageChangedError
=
Class
.
new
(
StandardError
)
PageChangedError
=
Class
.
new
(
StandardError
)
...
...
app/services/projects/gitlab_projects_import_service.rb
View file @
1f53cf7c
...
@@ -15,7 +15,7 @@ module Projects
...
@@ -15,7 +15,7 @@ module Projects
end
end
def
execute
def
execute
prepare_template_environment
(
template_file
&
.
path
)
prepare_template_environment
(
template_file
)
prepare_import_params
prepare_import_params
...
@@ -61,7 +61,6 @@ module Projects
...
@@ -61,7 +61,6 @@ module Projects
if
template_file
if
template_file
params
[
:import_type
]
=
'gitlab_project'
params
[
:import_type
]
=
'gitlab_project'
params
[
:import_source
]
=
import_upload_path
end
end
params
[
:import_data
]
=
{
data:
data
}
if
data
.
present?
params
[
:import_data
]
=
{
data:
data
}
if
data
.
present?
...
...
app/services/users/activity_service.rb
View file @
1f53cf7c
...
@@ -11,6 +11,7 @@ module Users
...
@@ -11,6 +11,7 @@ module Users
author
.
user
author
.
user
end
end
@user
=
nil
unless
@user
.
is_a?
(
User
)
@activity
=
activity
@activity
=
activity
end
end
...
...
app/uploaders/import_export_uploader.rb
View file @
1f53cf7c
# frozen_string_literal: true
# frozen_string_literal: true
class
ImportExportUploader
<
AttachmentUploader
class
ImportExportUploader
<
AttachmentUploader
EXTENSION_WHITELIST
=
%w[tar.gz]
.
freeze
EXTENSION_WHITELIST
=
%w[tar.gz
gz
]
.
freeze
def
extension_whitelist
def
extension_whitelist
EXTENSION_WHITELIST
EXTENSION_WHITELIST
...
...
app/views/projects/jobs/show.html.haml
View file @
1f53cf7c
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
%br
%br
Go to
Go to
=
link_to
project_runners_path
(
@build
.
project
)
do
=
link_to
project_runners_path
(
@build
.
project
,
anchor:
'js-runners-settings'
)
do
Runners page
Runners page
-
if
@build
.
starts_environment?
-
if
@build
.
starts_environment?
...
...
app/views/projects/pipelines/_info.html.haml
View file @
1f53cf7c
#js-pipeline-header-vue
.pipeline-header-container
.commit-box
%h3
.commit-title
=
markdown
(
commit
.
title
,
pipeline: :single_line
)
-
if
commit
.
description
.
present?
.commit-description
<
=
preserve
(
markdown
(
commit
.
description
,
pipeline: :single_line
))
-
if
@commit
.
present?
.info-well
.commit-box
-
if
commit
.
status
%h3
.commit-title
.well-segment.pipeline-info
=
markdown
(
@commit
.
title
,
pipeline: :single_line
)
.icon-container
-
if
@commit
.
description
.
present?
=
icon
(
'clock-o'
)
.commit-description
<
=
pluralize
@pipeline
.
total_size
,
"job"
=
preserve
(
markdown
(
@commit
.
description
,
pipeline: :single_line
))
-
if
@pipeline
.
ref
from
=
link_to
@pipeline
.
ref
,
project_ref_path
(
@project
,
@pipeline
.
ref
),
class:
"ref-name"
-
if
@pipeline
.
duration
in
=
time_interval_in_words
(
@pipeline
.
duration
)
-
if
@pipeline
.
queued_duration
=
"(queued for
#{
time_interval_in_words
(
@pipeline
.
queued_duration
)
}
)"
.info-well
.well-segment.branch-info
-
if
@commit
.
status
.icon-container.commit-icon
.well-segment.pipeline-info
=
custom_icon
(
"icon_commit"
)
.icon-container
=
link_to
commit
.
short_id
,
project_commit_path
(
@project
,
@pipeline
.
sha
),
class:
"commit-sha js-details-short"
=
icon
(
'clock-o'
)
=
link_to
(
"#"
,
class:
"js-details-expand d-none d-sm-none d-md-inline"
)
do
=
pluralize
@pipeline
.
total_size
,
"job"
%span
.text-expander
-
if
@pipeline
.
ref
=
sprite_icon
(
'ellipsis_h'
,
size:
12
)
from
%span
.js-details-content.hide
=
link_to
@pipeline
.
ref
,
project_ref_path
(
@project
,
@pipeline
.
ref
),
class:
"ref-name"
=
link_to
@pipeline
.
sha
,
project_commit_path
(
@project
,
@pipeline
.
sha
),
class:
"commit-sha commit-hash-full"
-
if
@pipeline
.
duration
=
clipboard_button
(
text:
@pipeline
.
sha
,
title:
"Copy commit SHA to clipboard"
)
in
=
time_interval_in_words
(
@pipeline
.
duration
)
-
if
@pipeline
.
queued_duration
=
"(queued for
#{
time_interval_in_words
(
@pipeline
.
queued_duration
)
}
)"
.well-segment.branch-info
=
render_if_exists
"projects/pipelines/info_extension"
,
pipeline:
@pipeline
.icon-container.commit-icon
=
custom_icon
(
"icon_commit"
)
=
link_to
@commit
.
short_id
,
project_commit_path
(
@project
,
@pipeline
.
sha
),
class:
"commit-sha js-details-short"
=
link_to
(
"#"
,
class:
"js-details-expand d-none d-sm-none d-md-inline"
)
do
%span
.text-expander
=
sprite_icon
(
'ellipsis_h'
,
size:
12
)
%span
.js-details-content.hide
=
link_to
@pipeline
.
sha
,
project_commit_path
(
@project
,
@pipeline
.
sha
),
class:
"commit-sha commit-hash-full"
=
clipboard_button
(
text:
@pipeline
.
sha
,
title:
"Copy commit SHA to clipboard"
)
=
render_if_exists
"projects/pipelines/info_extension"
,
pipeline:
@pipeline
app/views/projects/pipelines/show.html.haml
View file @
1f53cf7c
...
@@ -4,8 +4,10 @@
...
@@ -4,8 +4,10 @@
-
page_title
"Pipeline"
-
page_title
"Pipeline"
.js-pipeline-container
{
class:
container_class
,
data:
{
controller_action:
"#{controller.action_name}"
}
}
.js-pipeline-container
{
class:
container_class
,
data:
{
controller_action:
"#{controller.action_name}"
}
}
-
if
@commit
#js-pipeline-header-vue
.pipeline-header-container
=
render
"projects/pipelines/info"
-
if
@pipeline
.
commit
.
present?
=
render
"projects/pipelines/info"
,
commit:
@pipeline
.
commit
=
render
"projects/pipelines/with_tabs"
,
pipeline:
@pipeline
=
render
"projects/pipelines/with_tabs"
,
pipeline:
@pipeline
...
...
app/views/projects/settings/ci_cd/show.html.haml
View file @
1f53cf7c
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
.settings-content
.settings-content
=
render
'autodevops_form'
=
render
'autodevops_form'
%section
.qa-runners-settings.settings.no-animate
{
class:
(
'expanded'
if
expanded
)
}
%section
.qa-runners-settings.settings.no-animate
#js-runners-settings
{
class:
(
'expanded'
if
expanded
)
}
.settings-header
.settings-header
%h4
%h4
=
_
(
"Runners"
)
=
_
(
"Runners"
)
...
...
app/workers/create_gpg_signature_worker.rb
View file @
1f53cf7c
...
@@ -4,6 +4,10 @@ class CreateGpgSignatureWorker
...
@@ -4,6 +4,10 @@ class CreateGpgSignatureWorker
include
ApplicationWorker
include
ApplicationWorker
def
perform
(
commit_shas
,
project_id
)
def
perform
(
commit_shas
,
project_id
)
# Older versions of GitPushService may push a single commit ID on the stack.
# We need this to be backwards compatible.
commit_shas
=
Array
(
commit_shas
)
return
if
commit_shas
.
empty?
return
if
commit_shas
.
empty?
project
=
Project
.
find_by
(
id:
project_id
)
project
=
Project
.
find_by
(
id:
project_id
)
...
...
changelogs/unreleased/44824-remove-ghost-notification-settings-for-group-and-project.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Adds foreign key to notification_settings.user_id
merge_request
:
20567
author
:
Jacopo Beschi @jacopo-beschi
type
:
added
changelogs/unreleased/48246-osw-load-diffs-improvement.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Improve performance when fetching collapsed diffs and commenting in merge requests
merge_request
:
20940
author
:
type
:
performance
changelogs/unreleased/48773-gitlab-project-import-should-use-object-storage.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Add object storage logic to project import
merge_request
:
20773
author
:
type
:
added
changelogs/unreleased/48834-chart-versions-for-applications-installed-by-one-click-install-buttons-should-be-version-locked.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Chart versions for applications installed by one click install buttons should
be version locked
merge_request
:
20765
author
:
type
:
fixed
changelogs/unreleased/49830-use-helm-272.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Use Helm 2.7.2 for GitLab Managed Apps
merge_request
:
20956
author
:
type
:
changed
changelogs/unreleased/49851-link-to-runners.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Automatically expand runner's settings block when linking to the runner's settings
page
merge_request
:
author
:
type
:
other
changelogs/unreleased/49861-top-nav-search-bar-produces-console-error-when-unauthenticated.yml
0 → 100644
View file @
1f53cf7c
---
title
:
fix error caused when using the search bar while unauthenticated
merge_request
:
20970
author
:
type
:
fixed
changelogs/unreleased/frozen-string-enable-app-models.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Enable frozen string in app/models/*.rb
merge_request
:
20851
author
:
gfyoung
type
:
performance
changelogs/unreleased/rouge-3-2-0.yml
0 → 100644
View file @
1f53cf7c
---
title
:
Update to Rouge 3.2.0, including Terraform and Crystal lexer and bug fixes
merge_request
:
20991
author
:
type
:
changed
db/migrate/20180710162338_add_foreign_key_from_notification_settings_to_users.rb
0 → 100644
View file @
1f53cf7c
class
AddForeignKeyFromNotificationSettingsToUsers
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
class
NotificationSetting
<
ActiveRecord
::
Base
self
.
table_name
=
'notification_settings'
include
EachBatch
end
class
User
<
ActiveRecord
::
Base
self
.
table_name
=
'users'
end
DOWNTIME
=
false
disable_ddl_transaction!
def
up
NotificationSetting
.
each_batch
(
of:
1000
)
do
|
batch
|
batch
.
where
(
'NOT EXISTS (?)'
,
User
.
select
(
1
).
where
(
'users.id = notification_settings.user_id'
))
.
delete_all
end
add_concurrent_foreign_key
(
:notification_settings
,
:users
,
column: :user_id
,
on_delete: :cascade
)
end
def
down
remove_foreign_key
(
:notification_settings
,
column: :user_id
)
end
end
db/schema.rb
View file @
1f53cf7c
...
@@ -2350,6 +2350,7 @@ ActiveRecord::Schema.define(version: 20180726172057) do
...
@@ -2350,6 +2350,7 @@ ActiveRecord::Schema.define(version: 20180726172057) do
add_foreign_key
"milestones"
,
"projects"
,
name:
"fk_9bd0a0c791"
,
on_delete: :cascade
add_foreign_key
"milestones"
,
"projects"
,
name:
"fk_9bd0a0c791"
,
on_delete: :cascade
add_foreign_key
"note_diff_files"
,
"notes"
,
column:
"diff_note_id"
,
on_delete: :cascade
add_foreign_key
"note_diff_files"
,
"notes"
,
column:
"diff_note_id"
,
on_delete: :cascade
add_foreign_key
"notes"
,
"projects"
,
name:
"fk_99e097b079"
,
on_delete: :cascade
add_foreign_key
"notes"
,
"projects"
,
name:
"fk_99e097b079"
,
on_delete: :cascade
add_foreign_key
"notification_settings"
,
"users"
,
name:
"fk_0c95e91db7"
,
on_delete: :cascade
add_foreign_key
"oauth_openid_requests"
,
"oauth_access_grants"
,
column:
"access_grant_id"
,
name:
"fk_oauth_openid_requests_oauth_access_grants_access_grant_id"
add_foreign_key
"oauth_openid_requests"
,
"oauth_access_grants"
,
column:
"access_grant_id"
,
name:
"fk_oauth_openid_requests_oauth_access_grants_access_grant_id"
add_foreign_key
"pages_domains"
,
"projects"
,
name:
"fk_ea2f6dfc6f"
,
on_delete: :cascade
add_foreign_key
"pages_domains"
,
"projects"
,
name:
"fk_ea2f6dfc6f"
,
on_delete: :cascade
add_foreign_key
"personal_access_tokens"
,
"users"
add_foreign_key
"personal_access_tokens"
,
"users"
...
...
doc/ci/yaml/README.md
View file @
1f53cf7c
...
@@ -962,8 +962,8 @@ the binaries directory:
...
@@ -962,8 +962,8 @@ the binaries directory:
```
yaml
```
yaml
job
:
job
:
artifacts
:
artifacts
:
name
:
"
$CI_COMMIT_REF_NAME"
name
:
"
$CI_COMMIT_REF_NAME"
paths
:
paths
:
-
binaries/
-
binaries/
```
```
...
...
doc/development/performance.md
View file @
1f53cf7c
...
@@ -347,13 +347,7 @@ def expire_first_branch_cache
...
@@ -347,13 +347,7 @@ def expire_first_branch_cache
end
end
```
```
## Anti-Patterns
## String Freezing
This is a collection of
[
anti-patterns
][
anti-pattern
]
that should be avoided
unless these changes have a measurable, significant and positive impact on
production environments.
### String Freezing
In recent Ruby versions calling
`freeze`
on a String leads to it being allocated
In recent Ruby versions calling
`freeze`
on a String leads to it being allocated
only once and re-used. For example, on Ruby 2.3 this will only allocate the
only once and re-used. For example, on Ruby 2.3 this will only allocate the
...
@@ -365,17 +359,38 @@ only once and re-used. For example, on Ruby 2.3 this will only allocate the
...
@@ -365,17 +359,38 @@ only once and re-used. For example, on Ruby 2.3 this will only allocate the
end
end
```
```
Blindly adding a
`.freeze`
call to every String is an anti-pattern that should
Depending on the size of the String and how frequently it would be allocated
be avoided unless one can prove (using production data) the call actually has a
(before the
`.freeze`
call was added), this _may_ make things faster, but
positive impact on performance.
there's no guarantee it will.
Strings will be frozen by default in Ruby 3.0. To prepare our code base for
this eventuality, it's a good practice to add the following header to all
Ruby files:
```
ruby
# frozen_string_literal: true
```
This may cause test failures in the code that expects to be able to manipulate
strings. Instead of using
`dup`
, use the unary plus to get an unfrozen string:
```
ruby
test
=
+
"hello"
test
+=
" world"
```
## Anti-Patterns
This feature of Ruby wasn't really meant to make things faster directly, instead
This is a collection of
[
anti-patterns
][
anti-pattern
]
that should be avoided
it was meant to reduce the number of allocations. Depending on the size of the
unless these changes have a measurable, significant and positive impact on
String and how frequently it would be allocated (before the
`.freeze`
call was
production environments.
added), this _may_ make things faster, but there's no guarantee it will.
Another common flavour of this is to not only freeze a String, but also assign
### Moving Allocations to Constants
it to a constant, for example:
Storing an object as a constant so you only allocate it once _may_ improve
performance, but there's no guarantee this will. Looking up constants has an
impact on runtime performance, and as such, using a constant instead of
referencing an object directly may even slow code down. For example:
```
ruby
```
ruby
SOME_CONSTANT
=
'foo'
.
freeze
SOME_CONSTANT
=
'foo'
.
freeze
...
@@ -393,13 +408,6 @@ there's nothing stopping somebody from doing this elsewhere in the code:
...
@@ -393,13 +408,6 @@ there's nothing stopping somebody from doing this elsewhere in the code:
SOME_CONSTANT
=
'bar'
SOME_CONSTANT
=
'bar'
```
```
### Moving Allocations to Constants
Storing an object as a constant so you only allocate it once _may_ improve
performance, but there's no guarantee this will. Looking up constants has an
impact on runtime performance, and as such, using a constant instead of
referencing an object directly may even slow code down.
[
#15607
]:
https://gitlab.com/gitlab-org/gitlab-ce/issues/15607
[
#15607
]:
https://gitlab.com/gitlab-org/gitlab-ce/issues/15607
[
yorickpeterse
]:
https://gitlab.com/yorickpeterse
[
yorickpeterse
]:
https://gitlab.com/yorickpeterse
[
anti-pattern
]:
https://en.wikipedia.org/wiki/Anti-pattern
[
anti-pattern
]:
https://en.wikipedia.org/wiki/Anti-pattern
doc/user/profile/account/two_factor_authentication.md
View file @
1f53cf7c
...
@@ -88,7 +88,7 @@ storage in a safe place. **Each code can be used only once** to log in to your
...
@@ -88,7 +88,7 @@ storage in a safe place. **Each code can be used only once** to log in to your
account.
account.
If you lose the recovery codes or just want to generate new ones, you can do so
If you lose the recovery codes or just want to generate new ones, you can do so
from the
**Profile settings ➔ Account**
page where you first enabled 2FA
.
[
using SSH
](
#generate-new-recovery-codes-using-ssh
)
.
## Logging in with 2FA Enabled
## Logging in with 2FA Enabled
...
...
lib/backup/repository.rb
View file @
1f53cf7c
require
'yaml'
require
'yaml'
require_relative
'helper'
module
Backup
module
Backup
class
Repository
class
Repository
include
Backup
::
Helper
attr_reader
:progress
attr_reader
:progress
def
initialize
(
progress
)
def
initialize
(
progress
)
...
@@ -42,131 +39,36 @@ module Backup
...
@@ -42,131 +39,36 @@ module Backup
end
end
def
prepare_directories
def
prepare_directories
Gitlab
.
config
.
repositories
.
storages
.
each
do
|
name
,
repository_storage
|
Gitlab
.
config
.
repositories
.
storages
.
each
do
|
name
,
_
repository_storage
|
delete_all_repositories
(
name
,
repository_storage
)
Gitlab
::
GitalyClient
::
StorageService
.
new
(
name
).
delete_all_repositories
end
end
end
end
def
backup_project
(
project
)
def
backup_project
(
project
)
gitaly_migrate
(
:repository_backup
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_OUT
)
do
|
is_enabled
|
if
is_enabled
backup_project_gitaly
(
project
)
else
backup_project_local
(
project
)
end
end
backup_custom_hooks
(
project
)
rescue
=>
e
progress_warn
(
project
,
e
,
'Failed to backup repo'
)
end
def
backup_project_gitaly
(
project
)
path_to_project_bundle
=
path_to_bundle
(
project
)
path_to_project_bundle
=
path_to_bundle
(
project
)
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
project
.
repository
)
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
project
.
repository
)
.
create_bundle
(
path_to_project_bundle
)
.
create_bundle
(
path_to_project_bundle
)
end
def
backup_project_local
(
project
)
path_to_project_repo
=
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
path_to_repo
(
project
)
end
path_to_project_bundle
=
path_to_bundle
(
project
)
cmd
=
%W(
#{
Gitlab
.
config
.
git
.
bin_path
}
--git-dir=
#{
path_to_project_repo
}
bundle create
#{
path_to_project_bundle
}
--all)
output
,
status
=
Gitlab
::
Popen
.
popen
(
cmd
)
progress_warn
(
project
,
cmd
.
join
(
' '
),
output
)
unless
status
.
zero?
end
def
delete_all_repositories
(
name
,
repository_storage
)
gitaly_migrate
(
:delete_all_repositories
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_OUT
)
do
|
is_enabled
|
if
is_enabled
Gitlab
::
GitalyClient
::
StorageService
.
new
(
name
).
delete_all_repositories
else
local_delete_all_repositories
(
name
,
repository_storage
)
end
end
end
def
local_delete_all_repositories
(
name
,
repository_storage
)
path
=
repository_storage
.
legacy_disk_path
return
unless
File
.
exist?
(
path
)
bk_repos_path
=
File
.
join
(
Gitlab
.
config
.
backup
.
path
,
"tmp"
,
"
#{
name
}
-repositories.old."
+
Time
.
now
.
to_i
.
to_s
)
FileUtils
.
mkdir_p
(
bk_repos_path
,
mode:
0700
)
files
=
Dir
.
glob
(
File
.
join
(
path
,
"*"
),
File
::
FNM_DOTMATCH
)
-
[
File
.
join
(
path
,
"."
),
File
.
join
(
path
,
".."
)]
begin
FileUtils
.
mv
(
files
,
bk_repos_path
)
rescue
Errno
::
EACCES
access_denied_error
(
path
)
rescue
Errno
::
EBUSY
resource_busy_error
(
path
)
end
end
def
local_restore_custom_hooks
(
project
,
dir
)
backup_custom_hooks
(
project
)
path_to_project_repo
=
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
rescue
=>
e
path_to_repo
(
project
)
progress_warn
(
project
,
e
,
'Failed to backup repo'
)
end
cmd
=
%W(tar -xf
#{
path_to_tars
(
project
,
dir
)
}
-C
#{
path_to_project_repo
}
#{
dir
}
)
output
,
status
=
Gitlab
::
Popen
.
popen
(
cmd
)
unless
status
.
zero?
progress_warn
(
project
,
cmd
.
join
(
' '
),
output
)
end
end
def
gitaly_restore_custom_hooks
(
project
,
dir
)
custom_hooks_path
=
path_to_tars
(
project
,
dir
)
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
project
.
repository
)
.
restore_custom_hooks
(
custom_hooks_path
)
end
end
def
local_backup_custom_hooks
(
project
)
def
backup_custom_hooks
(
project
)
in_path
(
path_to_tars
(
project
))
do
|
dir
|
FileUtils
.
mkdir_p
(
project_backup_path
(
project
))
path_to_project_repo
=
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
path_to_repo
(
project
)
end
break
unless
File
.
exist?
(
File
.
join
(
path_to_project_repo
,
dir
))
FileUtils
.
mkdir_p
(
path_to_tars
(
project
))
cmd
=
%W(tar -cf
#{
path_to_tars
(
project
,
dir
)
}
-c
#{
path_to_project_repo
}
#{
dir
}
)
output
,
status
=
Gitlab
::
Popen
.
popen
(
cmd
)
unless
status
.
zero?
progress_warn
(
project
,
cmd
.
join
(
' '
),
output
)
end
end
end
def
gitaly_backup_custom_hooks
(
project
)
custom_hooks_path
=
custom_hooks_tar
(
project
)
FileUtils
.
mkdir_p
(
path_to_tars
(
project
))
custom_hooks_path
=
path_to_tars
(
project
,
'custom_hooks'
)
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
project
.
repository
)
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
project
.
repository
)
.
backup_custom_hooks
(
custom_hooks_path
)
.
backup_custom_hooks
(
custom_hooks_path
)
end
end
def
backup_custom_hooks
(
project
)
gitaly_migrate
(
:backup_custom_hooks
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_OUT
)
do
|
is_enabled
|
if
is_enabled
gitaly_backup_custom_hooks
(
project
)
else
local_backup_custom_hooks
(
project
)
end
end
end
def
restore_custom_hooks
(
project
)
def
restore_custom_hooks
(
project
)
in_path
(
path_to_tars
(
project
))
do
|
dir
|
return
unless
Dir
.
exist?
(
project_backup_path
(
project
))
gitaly_migrate
(
:restore_custom_hooks
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_OUT
)
do
|
is_enabled
|
return
if
Dir
.
glob
(
"
#{
project_backup_path
(
project
)
}
/custom_hooks*"
).
none?
if
is_enabled
gitaly_restore_custom_hooks
(
project
,
dir
)
custom_hooks_path
=
custom_hooks_tar
(
project
)
else
Gitlab
::
GitalyClient
::
RepositoryService
.
new
(
project
.
repository
)
local_restore_custom_hooks
(
project
,
dir
)
.
restore_custom_hooks
(
custom_hooks_path
)
end
end
end
end
end
def
restore
def
restore
...
@@ -181,7 +83,8 @@ module Backup
...
@@ -181,7 +83,8 @@ module Backup
restore_repo_success
=
nil
restore_repo_success
=
nil
if
File
.
exist?
(
path_to_project_bundle
)
if
File
.
exist?
(
path_to_project_bundle
)
begin
begin
project
.
repository
.
create_from_bundle
path_to_project_bundle
project
.
repository
.
create_from_bundle
(
path_to_project_bundle
)
restore_custom_hooks
(
project
)
restore_repo_success
=
true
restore_repo_success
=
true
rescue
=>
e
rescue
=>
e
restore_repo_success
=
false
restore_repo_success
=
false
...
@@ -197,8 +100,6 @@ module Backup
...
@@ -197,8 +100,6 @@ module Backup
progress
.
puts
"[Failed] restoring
#{
project
.
full_path
}
repository"
.
color
(
:red
)
progress
.
puts
"[Failed] restoring
#{
project
.
full_path
}
repository"
.
color
(
:red
)
end
end
restore_custom_hooks
(
project
)
wiki
=
ProjectWiki
.
new
(
project
)
wiki
=
ProjectWiki
.
new
(
project
)
path_to_wiki_bundle
=
path_to_bundle
(
wiki
)
path_to_wiki_bundle
=
path_to_bundle
(
wiki
)
...
@@ -219,48 +120,28 @@ module Backup
...
@@ -219,48 +120,28 @@ module Backup
protected
protected
def
path_to_repo
(
project
)
project
.
repository
.
path_to_repo
end
def
path_to_bundle
(
project
)
def
path_to_bundle
(
project
)
File
.
join
(
backup_repos_path
,
project
.
disk_path
+
'.bundle'
)
File
.
join
(
backup_repos_path
,
project
.
disk_path
+
'.bundle'
)
end
end
def
path_to_tars
(
project
,
dir
=
nil
)
def
project_backup_path
(
project
)
path
=
File
.
join
(
backup_repos_path
,
project
.
disk_path
)
File
.
join
(
backup_repos_path
,
project
.
disk_path
)
end
if
dir
def
custom_hooks_tar
(
project
)
File
.
join
(
path
,
"
#{
dir
}
.tar"
)
File
.
join
(
project_backup_path
(
project
),
"custom_hooks.tar"
)
else
path
end
end
end
def
backup_repos_path
def
backup_repos_path
File
.
join
(
Gitlab
.
config
.
backup
.
path
,
'repositories'
)
File
.
join
(
Gitlab
.
config
.
backup
.
path
,
'repositories'
)
end
end
def
in_path
(
path
)
return
unless
Dir
.
exist?
(
path
)
dir_entries
=
Dir
.
entries
(
path
)
if
dir_entries
.
include?
(
'custom_hooks'
)
||
dir_entries
.
include?
(
'custom_hooks.tar'
)
yield
(
'custom_hooks'
)
end
end
def
prepare
def
prepare
FileUtils
.
rm_rf
(
backup_repos_path
)
FileUtils
.
rm_rf
(
backup_repos_path
)
FileUtils
.
mkdir_p
(
Gitlab
.
config
.
backup
.
path
)
FileUtils
.
mkdir_p
(
Gitlab
.
config
.
backup
.
path
)
FileUtils
.
mkdir
(
backup_repos_path
,
mode:
0700
)
FileUtils
.
mkdir
(
backup_repos_path
,
mode:
0700
)
end
end
def
silent
{
err:
'/dev/null'
,
out:
'/dev/null'
}
end
private
private
def
progress_warn
(
project
,
cmd
,
output
)
def
progress_warn
(
project
,
cmd
,
output
)
...
@@ -273,18 +154,8 @@ module Backup
...
@@ -273,18 +154,8 @@ module Backup
project_or_wiki
.
repository
.
empty?
project_or_wiki
.
repository
.
empty?
end
end
def
repository_storage_paths_args
Gitlab
.
config
.
repositories
.
storages
.
values
.
map
{
|
rs
|
rs
.
legacy_disk_path
}
end
def
display_repo_path
(
project
)
def
display_repo_path
(
project
)
project
.
hashed_storage?
(
:repository
)
?
"
#{
project
.
full_path
}
(
#{
project
.
disk_path
}
)"
:
project
.
full_path
project
.
hashed_storage?
(
:repository
)
?
"
#{
project
.
full_path
}
(
#{
project
.
disk_path
}
)"
:
project
.
full_path
end
end
def
gitaly_migrate
(
method
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_IN
,
&
block
)
Gitlab
::
GitalyClient
.
migrate
(
method
,
status:
status
,
&
block
)
rescue
GRPC
::
NotFound
,
GRPC
::
BadStatus
=>
e
raise
Error
,
e
end
end
end
end
end
lib/gitlab/bare_repository_import/importer.rb
View file @
1f53cf7c
...
@@ -26,6 +26,12 @@ module Gitlab
...
@@ -26,6 +26,12 @@ module Gitlab
end
end
end
end
# This is called from within a rake task only used by Admins, so allow writing
# to STDOUT
def
self
.
log
(
message
)
puts
message
# rubocop:disable Rails/Output
end
attr_reader
:user
,
:project_name
,
:bare_repo
attr_reader
:user
,
:project_name
,
:bare_repo
delegate
:log
,
to: :class
delegate
:log
,
to: :class
...
@@ -59,11 +65,10 @@ module Gitlab
...
@@ -59,11 +65,10 @@ module Gitlab
import_type:
'bare_repository'
,
import_type:
'bare_repository'
,
namespace_id:
group
&
.
id
).
execute
namespace_id:
group
&
.
id
).
execute
if
project
.
persisted?
&&
mv_repo
(
project
)
if
project
.
persisted?
&&
mv_repo
sitories
(
project
)
log
" * Created
#{
project
.
name
}
(
#{
project_full_path
}
)"
.
color
(
:green
)
log
" * Created
#{
project
.
name
}
(
#{
project_full_path
}
)"
.
color
(
:green
)
project
.
write_repository_config
project
.
write_repository_config
Gitlab
::
Git
::
Repository
.
create_hooks
(
project
.
repository
.
path_to_repo
,
Gitlab
.
config
.
gitlab_shell
.
hooks_path
)
ProjectCacheWorker
.
perform_async
(
project
.
id
)
ProjectCacheWorker
.
perform_async
(
project
.
id
)
else
else
...
@@ -74,12 +79,11 @@ module Gitlab
...
@@ -74,12 +79,11 @@ module Gitlab
project
project
end
end
def
mv_repo
(
project
)
def
mv_repositories
(
project
)
storage_path
=
storage_path_for_shard
(
project
.
repository_storage
)
mv_repo
(
bare_repo
.
repo_path
,
project
.
repository
)
FileUtils
.
mv
(
repo_path
,
project
.
repository
.
path_to_repo
)
if
bare_repo
.
wiki_exists?
if
bare_repo
.
wiki_exists?
FileUtils
.
mv
(
wiki_path
,
File
.
join
(
storage_path
,
project
.
disk_path
+
'.wiki.git'
)
)
mv_repo
(
bare_repo
.
wiki_path
,
project
.
wiki
.
repository
)
end
end
true
true
...
@@ -89,6 +93,11 @@ module Gitlab
...
@@ -89,6 +93,11 @@ module Gitlab
false
false
end
end
def
mv_repo
(
path
,
repository
)
repository
.
create_from_bundle
(
bundle
(
path
))
FileUtils
.
rm_rf
(
path
)
end
def
storage_path_for_shard
(
shard
)
def
storage_path_for_shard
(
shard
)
Gitlab
.
config
.
repositories
.
storages
[
shard
].
legacy_disk_path
Gitlab
.
config
.
repositories
.
storages
[
shard
].
legacy_disk_path
end
end
...
@@ -101,10 +110,17 @@ module Gitlab
...
@@ -101,10 +110,17 @@ module Gitlab
Groups
::
NestedCreateService
.
new
(
user
,
group_path:
group_path
).
execute
Groups
::
NestedCreateService
.
new
(
user
,
group_path:
group_path
).
execute
end
end
# This is called from within a rake task only used by Admins, so allow writing
def
bundle
(
repo_path
)
# to STDOUT
# TODO: we could save some time and disk space by using
def
self
.
log
(
message
)
# `git bundle create - --all` and streaming the bundle directly to
puts
message
# rubocop:disable Rails/Output
# Gitaly, rather than writing it on disk first
bundle_path
=
"
#{
repo_path
}
.bundle"
cmd
=
%W(
#{
Gitlab
.
config
.
git
.
bin_path
}
--git-dir=
#{
repo_path
}
bundle create
#{
bundle_path
}
--all)
output
,
status
=
Gitlab
::
Popen
.
popen
(
cmd
)
raise
output
unless
status
.
zero?
bundle_path
end
end
end
end
end
end
...
...
lib/gitlab/bare_repository_import/repository.rb
View file @
1f53cf7c
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/953
#
module
Gitlab
module
Gitlab
module
BareRepositoryImport
module
BareRepositoryImport
class
Repository
class
Repository
...
...
lib/gitlab/cleanup/project_uploads.rb
View file @
1f53cf7c
...
@@ -40,7 +40,7 @@ module Gitlab
...
@@ -40,7 +40,7 @@ module Gitlab
# Accepts a path in the form of "#{hex_secret}/#{filename}"
# Accepts a path in the form of "#{hex_secret}/#{filename}"
def
find_correct_path
(
upload_path
)
def
find_correct_path
(
upload_path
)
upload
=
Upload
.
find_by
(
uploader:
'FileUploader'
,
path:
upload_path
)
upload
=
Upload
.
find_by
(
uploader:
'FileUploader'
,
path:
upload_path
)
return
unless
upload
&&
upload
.
local?
return
unless
upload
&&
upload
.
local?
&&
upload
.
model
upload
.
absolute_path
upload
.
absolute_path
rescue
=>
e
rescue
=>
e
...
...
lib/gitlab/git/repository.rb
View file @
1f53cf7c
...
@@ -39,19 +39,6 @@ module Gitlab
...
@@ -39,19 +39,6 @@ module Gitlab
ChecksumError
=
Class
.
new
(
StandardError
)
ChecksumError
=
Class
.
new
(
StandardError
)
class
<<
self
class
<<
self
# Unlike `new`, `create` takes the repository path
def
create
(
repo_path
,
bare:
true
,
symlink_hooks_to:
nil
)
FileUtils
.
mkdir_p
(
repo_path
,
mode:
0770
)
# Equivalent to `git --git-path=#{repo_path} init [--bare]`
repo
=
Rugged
::
Repository
.
init_at
(
repo_path
,
bare
)
repo
.
close
create_hooks
(
repo_path
,
symlink_hooks_to
)
if
symlink_hooks_to
.
present?
true
end
def
create_hooks
(
repo_path
,
global_hooks_path
)
def
create_hooks
(
repo_path
,
global_hooks_path
)
local_hooks_path
=
File
.
join
(
repo_path
,
'hooks'
)
local_hooks_path
=
File
.
join
(
repo_path
,
'hooks'
)
real_local_hooks_path
=
:not_found
real_local_hooks_path
=
:not_found
...
...
lib/gitlab/import_export/command_line_util.rb
View file @
1f53cf7c
...
@@ -18,6 +18,21 @@ module Gitlab
...
@@ -18,6 +18,21 @@ module Gitlab
private
private
def
download_or_copy_upload
(
uploader
,
upload_path
)
if
uploader
.
upload
.
local?
copy_files
(
uploader
.
path
,
upload_path
)
else
download
(
uploader
.
url
,
upload_path
)
end
end
def
download
(
url
,
upload_path
)
File
.
open
(
upload_path
,
'w'
)
do
|
file
|
# Download (stream) file from the uploader's location
IO
.
copy_stream
(
URI
.
parse
(
url
).
open
,
file
)
end
end
def
tar_with_options
(
archive
:,
dir
:,
options
:)
def
tar_with_options
(
archive
:,
dir
:,
options
:)
execute
(
%W(tar -
#{
options
}
#{
archive
}
-C
#{
dir
}
.)
)
execute
(
%W(tar -
#{
options
}
#{
archive
}
-C
#{
dir
}
.)
)
end
end
...
...
lib/gitlab/import_export/file_importer.rb
View file @
1f53cf7c
...
@@ -10,15 +10,18 @@ module Gitlab
...
@@ -10,15 +10,18 @@ module Gitlab
new
(
*
args
).
import
new
(
*
args
).
import
end
end
def
initialize
(
archive_file
:,
shared
:)
def
initialize
(
project
:,
archive_file
:,
shared
:)
@project
=
project
@archive_file
=
archive_file
@archive_file
=
archive_file
@shared
=
shared
@shared
=
shared
end
end
def
import
def
import
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
archive_path
)
remove_symlinks!
remove_symlinks
copy_archive
wait_for_archived_file
do
wait_for_archived_file
do
decompress_archive
decompress_archive
...
@@ -27,7 +30,8 @@ module Gitlab
...
@@ -27,7 +30,8 @@ module Gitlab
@shared
.
error
(
e
)
@shared
.
error
(
e
)
false
false
ensure
ensure
remove_symlinks!
remove_import_file
remove_symlinks
end
end
private
private
...
@@ -51,7 +55,15 @@ module Gitlab
...
@@ -51,7 +55,15 @@ module Gitlab
result
result
end
end
def
remove_symlinks!
def
copy_archive
return
if
@archive_file
@archive_file
=
File
.
join
(
@shared
.
archive_path
,
Gitlab
::
ImportExport
.
export_filename
(
project:
@project
))
download_or_copy_upload
(
@project
.
import_export_upload
.
import_file
,
@archive_file
)
end
def
remove_symlinks
extracted_files
.
each
do
|
path
|
extracted_files
.
each
do
|
path
|
FileUtils
.
rm
(
path
)
if
File
.
lstat
(
path
).
symlink?
FileUtils
.
rm
(
path
)
if
File
.
lstat
(
path
).
symlink?
end
end
...
@@ -59,6 +71,10 @@ module Gitlab
...
@@ -59,6 +71,10 @@ module Gitlab
true
true
end
end
def
remove_import_file
FileUtils
.
rm_rf
(
@archive_file
)
end
def
extracted_files
def
extracted_files
Dir
.
glob
(
"
#{
@shared
.
export_path
}
/**/*"
,
File
::
FNM_DOTMATCH
).
reject
{
|
f
|
IGNORED_FILENAMES
.
include?
(
File
.
basename
(
f
))
}
Dir
.
glob
(
"
#{
@shared
.
export_path
}
/**/*"
,
File
::
FNM_DOTMATCH
).
reject
{
|
f
|
IGNORED_FILENAMES
.
include?
(
File
.
basename
(
f
))
}
end
end
...
...
lib/gitlab/import_export/importer.rb
View file @
1f53cf7c
...
@@ -35,7 +35,8 @@ module Gitlab
...
@@ -35,7 +35,8 @@ module Gitlab
end
end
def
import_file
def
import_file
Gitlab
::
ImportExport
::
FileImporter
.
import
(
archive_file:
@archive_file
,
Gitlab
::
ImportExport
::
FileImporter
.
import
(
project:
@project
,
archive_file:
@archive_file
,
shared:
@shared
)
shared:
@shared
)
end
end
...
@@ -91,7 +92,14 @@ module Gitlab
...
@@ -91,7 +92,14 @@ module Gitlab
end
end
def
remove_import_file
def
remove_import_file
FileUtils
.
rm_rf
(
@archive_file
)
return
unless
Gitlab
::
ImportExport
.
object_storage?
upload
=
@project
.
import_export_upload
return
unless
upload
&
.
import_file
&
.
file
upload
.
remove_import_file!
upload
.
save!
end
end
def
overwrite_project
def
overwrite_project
...
...
lib/gitlab/import_export/uploads_manager.rb
View file @
1f53cf7c
...
@@ -91,10 +91,7 @@ module Gitlab
...
@@ -91,10 +91,7 @@ module Gitlab
mkdir_p
(
File
.
join
(
uploads_export_path
,
secret
))
mkdir_p
(
File
.
join
(
uploads_export_path
,
secret
))
File
.
open
(
upload_path
,
'w'
)
do
|
file
|
download_or_copy_upload
(
upload
,
upload_path
)
# Download (stream) file from the uploader's location
IO
.
copy_stream
(
URI
.
parse
(
upload
.
file
.
url
).
open
,
file
)
end
end
end
end
end
end
end
...
...
lib/gitlab/kubernetes/helm.rb
View file @
1f53cf7c
module
Gitlab
module
Gitlab
module
Kubernetes
module
Kubernetes
module
Helm
module
Helm
HELM_VERSION
=
'2.7.
0
'
.
freeze
HELM_VERSION
=
'2.7.
2
'
.
freeze
NAMESPACE
=
'gitlab-managed-apps'
.
freeze
NAMESPACE
=
'gitlab-managed-apps'
.
freeze
end
end
end
end
...
...
lib/gitlab/template_helper.rb
View file @
1f53cf7c
...
@@ -2,11 +2,17 @@ module Gitlab
...
@@ -2,11 +2,17 @@ module Gitlab
module
TemplateHelper
module
TemplateHelper
include
Gitlab
::
Utils
::
StrongMemoize
include
Gitlab
::
Utils
::
StrongMemoize
def
prepare_template_environment
(
file
_path
)
def
prepare_template_environment
(
file
)
return
unless
file
_
path
.
present?
return
unless
file
&
.
path
.
present?
FileUtils
.
mkdir_p
(
File
.
dirname
(
import_upload_path
))
if
Gitlab
::
ImportExport
.
object_storage?
FileUtils
.
copy_entry
(
file_path
,
import_upload_path
)
params
[
:import_export_upload
]
=
ImportExportUpload
.
new
(
import_file:
file
)
else
FileUtils
.
mkdir_p
(
File
.
dirname
(
import_upload_path
))
FileUtils
.
copy_entry
(
file
.
path
,
import_upload_path
)
params
[
:import_source
]
=
import_upload_path
end
end
end
def
import_upload_path
def
import_upload_path
...
...
spec/controllers/admin/services_controller_spec.rb
View file @
1f53cf7c
...
@@ -13,7 +13,7 @@ describe Admin::ServicesController do
...
@@ -13,7 +13,7 @@ describe Admin::ServicesController do
Service
.
available_services_names
.
each
do
|
service_name
|
Service
.
available_services_names
.
each
do
|
service_name
|
context
"
#{
service_name
}
"
do
context
"
#{
service_name
}
"
do
let!
(
:service
)
do
let!
(
:service
)
do
service_template
=
service_name
.
concat
(
"_service"
)
.
camelize
.
constantize
service_template
=
"
#{
service_name
}
_service"
.
camelize
.
constantize
service_template
.
where
(
template:
true
).
first_or_create
service_template
.
where
(
template:
true
).
first_or_create
end
end
...
...
spec/features/projects/import_export/import_file_object_storage_spec.rb
0 → 100644
View file @
1f53cf7c
require
'spec_helper'
describe
'Import/Export - project import integration test'
,
:js
do
include
Select2Helper
let
(
:user
)
{
create
(
:user
)
}
let
(
:file
)
{
File
.
join
(
Rails
.
root
,
'spec'
,
'features'
,
'projects'
,
'import_export'
,
'test_project_export.tar.gz'
)
}
let
(
:export_path
)
{
"
#{
Dir
.
tmpdir
}
/import_file_spec"
}
before
do
stub_feature_flags
(
import_export_object_storage:
true
)
stub_uploads_object_storage
(
FileUploader
)
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
gitlab_sign_in
(
user
)
end
after
do
FileUtils
.
rm_rf
(
export_path
,
secure:
true
)
end
context
'when selecting the namespace'
do
let
(
:user
)
{
create
(
:admin
)
}
let!
(
:namespace
)
{
user
.
namespace
}
let
(
:project_path
)
{
'test-project-path'
+
SecureRandom
.
hex
}
context
'prefilled the path'
do
it
'user imports an exported project successfully'
do
visit
new_project_path
select2
(
namespace
.
id
,
from:
'#project_namespace_id'
)
fill_in
:project_path
,
with:
project_path
,
visible:
true
click_import_project_tab
click_link
'GitLab export'
expect
(
page
).
to
have_content
(
'Import an exported GitLab project'
)
expect
(
URI
.
parse
(
current_url
).
query
).
to
eq
(
"namespace_id=
#{
namespace
.
id
}
&path=
#{
project_path
}
"
)
attach_file
(
'file'
,
file
)
click_on
'Import project'
expect
(
Project
.
count
).
to
eq
(
1
)
project
=
Project
.
last
expect
(
project
).
not_to
be_nil
expect
(
project
.
description
).
to
eq
(
"Foo Bar"
)
expect
(
project
.
issues
).
not_to
be_empty
expect
(
project
.
merge_requests
).
not_to
be_empty
expect
(
project_hook_exists?
(
project
)).
to
be
true
expect
(
wiki_exists?
(
project
)).
to
be
true
expect
(
project
.
import_state
.
status
).
to
eq
(
'finished'
)
end
end
context
'path is not prefilled'
do
it
'user imports an exported project successfully'
do
visit
new_project_path
click_import_project_tab
click_link
'GitLab export'
fill_in
:path
,
with:
'test-project-path'
,
visible:
true
attach_file
(
'file'
,
file
)
expect
{
click_on
'Import project'
}.
to
change
{
Project
.
count
}.
by
(
1
)
project
=
Project
.
last
expect
(
project
).
not_to
be_nil
expect
(
page
).
to
have_content
(
"Project 'test-project-path' is being imported"
)
end
end
end
it
'invalid project'
do
project
=
create
(
:project
,
namespace:
user
.
namespace
)
visit
new_project_path
select2
(
user
.
namespace
.
id
,
from:
'#project_namespace_id'
)
fill_in
:project_path
,
with:
project
.
name
,
visible:
true
click_import_project_tab
click_link
'GitLab export'
attach_file
(
'file'
,
file
)
click_on
'Import project'
page
.
within
(
'.flash-container'
)
do
expect
(
page
).
to
have_content
(
'Project could not be imported'
)
end
end
def
wiki_exists?
(
project
)
wiki
=
ProjectWiki
.
new
(
project
)
wiki
.
repository
.
exists?
&&
!
wiki
.
repository
.
empty?
end
def
project_hook_exists?
(
project
)
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
Gitlab
::
Git
::
Hook
.
new
(
'post-receive'
,
project
.
repository
.
raw_repository
).
exists?
end
end
def
click_import_project_tab
find
(
'#import-project-tab'
).
click
end
end
spec/features/projects/import_export/import_file_spec.rb
View file @
1f53cf7c
...
@@ -8,6 +8,7 @@ describe 'Import/Export - project import integration test', :js do
...
@@ -8,6 +8,7 @@ describe 'Import/Export - project import integration test', :js do
let
(
:export_path
)
{
"
#{
Dir
.
tmpdir
}
/import_file_spec"
}
let
(
:export_path
)
{
"
#{
Dir
.
tmpdir
}
/import_file_spec"
}
before
do
before
do
stub_feature_flags
(
import_export_object_storage:
false
)
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
gitlab_sign_in
(
user
)
gitlab_sign_in
(
user
)
end
end
...
...
spec/javascripts/ide/components/new_dropdown/index_spec.js
View file @
1f53cf7c
...
@@ -62,7 +62,9 @@ describe('new dropdown component', () => {
...
@@ -62,7 +62,9 @@ describe('new dropdown component', () => {
vm
.
dropdownOpen
=
true
;
vm
.
dropdownOpen
=
true
;
setTimeout
(()
=>
{
setTimeout
(()
=>
{
expect
(
vm
.
$refs
.
dropdownMenu
.
scrollIntoView
).
toHaveBeenCalled
();
expect
(
vm
.
$refs
.
dropdownMenu
.
scrollIntoView
).
toHaveBeenCalledWith
({
block
:
'
nearest
'
,
});
done
();
done
();
});
});
...
...
spec/lib/backup/repository_spec.rb
View file @
1f53cf7c
...
@@ -73,37 +73,27 @@ describe Backup::Repository do
...
@@ -73,37 +73,27 @@ describe Backup::Repository do
end
end
end
end
describe
'#delete_all_repositories'
,
:seed_helper
do
describe
'#prepare_directories'
,
:seed_helper
do
shared_examples
(
'delete_all_repositories'
)
do
before
do
before
do
allow
(
FileUtils
).
to
receive
(
:mkdir_p
).
and_call_original
allow
(
FileUtils
).
to
receive
(
:mkdir_p
).
and_call_original
allow
(
FileUtils
).
to
receive
(
:mv
).
and_call_original
allow
(
FileUtils
).
to
receive
(
:mv
).
and_call_original
end
end
after
(
:all
)
do
ensure_seeds
end
it
'removes all repositories'
do
# Sanity check: there should be something for us to delete
expect
(
list_repositories
).
to
include
(
File
.
join
(
SEED_STORAGE_PATH
,
TEST_REPO_PATH
))
subject
.
delete_all_repositories
(
'default'
,
Gitlab
.
config
.
repositories
.
storages
[
'default'
])
after
(
:all
)
do
ensure_seeds
end
expect
(
list_repositories
).
to
be_empty
it
' removes all repositories'
do
end
# Sanity check: there should be something for us to delete
expect
(
list_repositories
).
to
include
(
File
.
join
(
SEED_STORAGE_PATH
,
TEST_REPO_PATH
))
def
list_repositories
subject
.
prepare_directories
Dir
[
File
.
join
(
SEED_STORAGE_PATH
,
'*.git'
)]
end
end
context
'with gitaly'
do
expect
(
list_repositories
).
to
be_empty
it_behaves_like
'delete_all_repositories'
end
end
context
'without gitaly'
,
:skip_gitaly_mock
do
def
list_repositories
it_behaves_like
'delete_all_repositories'
Dir
[
File
.
join
(
SEED_STORAGE_PATH
,
'*.git'
)]
end
end
end
end
...
...
spec/lib/gitlab/bare_repository_import/importer_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
BareRepositoryImport
::
Importer
,
repository:
true
do
describe
Gitlab
::
BareRepositoryImport
::
Importer
,
:seed_helper
do
let!
(
:admin
)
{
create
(
:admin
)
}
let!
(
:admin
)
{
create
(
:admin
)
}
let!
(
:base_dir
)
{
Dir
.
mktmpdir
+
'/'
}
let!
(
:base_dir
)
{
Dir
.
mktmpdir
+
'/'
}
let
(
:bare_repository
)
{
Gitlab
::
BareRepositoryImport
::
Repository
.
new
(
base_dir
,
File
.
join
(
base_dir
,
"
#{
project_path
}
.git"
))
}
let
(
:bare_repository
)
{
Gitlab
::
BareRepositoryImport
::
Repository
.
new
(
base_dir
,
File
.
join
(
base_dir
,
"
#{
project_path
}
.git"
))
}
let
(
:gitlab_shell
)
{
Gitlab
::
Shell
.
new
}
let
(
:gitlab_shell
)
{
Gitlab
::
Shell
.
new
}
let
(
:source_project
)
{
TEST_REPO_PATH
}
subject
(
:importer
)
{
described_class
.
new
(
admin
,
bare_repository
)
}
subject
(
:importer
)
{
described_class
.
new
(
admin
,
bare_repository
)
}
...
@@ -17,16 +18,11 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -17,16 +18,11 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
after
do
after
do
FileUtils
.
rm_rf
(
base_dir
)
FileUtils
.
rm_rf
(
base_dir
)
TestEnv
.
clean_test_path
ensure_seeds
Rainbow
.
enabled
=
@rainbow
Rainbow
.
enabled
=
@rainbow
end
end
around
do
|
example
|
# TODO migrate BareRepositoryImport https://gitlab.com/gitlab-org/gitaly/issues/953
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
example
.
run
end
end
shared_examples
'importing a repository'
do
shared_examples
'importing a repository'
do
describe
'.execute'
do
describe
'.execute'
do
it
'creates a project for a repository in storage'
do
it
'creates a project for a repository in storage'
do
...
@@ -86,8 +82,8 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -86,8 +82,8 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
importer
.
create_project_if_needed
importer
.
create_project_if_needed
end
end
it
'creates the Git repo on disk
with the proper symlink for hooks
'
do
it
'creates the Git repo on disk'
do
create_bare_repository
(
"
#{
project_path
}
.git"
)
prepare_repository
(
"
#{
project_path
}
.git"
,
source_project
)
importer
.
create_project_if_needed
importer
.
create_project_if_needed
...
@@ -97,9 +93,6 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -97,9 +93,6 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage
,
repo_path
)).
to
be
(
true
)
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage
,
repo_path
)).
to
be
(
true
)
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage
,
hook_path
)).
to
be
(
true
)
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage
,
hook_path
)).
to
be
(
true
)
full_hook_path
=
File
.
join
(
project
.
repository
.
path_to_repo
,
'hooks'
)
expect
(
File
.
readlink
(
full_hook_path
)).
to
eq
(
Gitlab
.
config
.
gitlab_shell
.
hooks_path
)
end
end
context
'hashed storage enabled'
do
context
'hashed storage enabled'
do
...
@@ -148,7 +141,7 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -148,7 +141,7 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
end
end
it
'creates the Git repo in disk'
do
it
'creates the Git repo in disk'
do
create_bare_repository
(
"
#{
project_path
}
.git"
)
prepare_repository
(
"
#{
project_path
}
.git"
,
source_project
)
importer
.
create_project_if_needed
importer
.
create_project_if_needed
...
@@ -158,23 +151,23 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -158,23 +151,23 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage
,
project
.
disk_path
+
'.wiki.git'
)).
to
be
(
true
)
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage
,
project
.
disk_path
+
'.wiki.git'
)).
to
be
(
true
)
end
end
it
'moves an existing project to the correct path'
do
context
'with a repository already on disk'
do
let!
(
:base_dir
)
{
TestEnv
.
repos_path
}
# This is a quick way to get a valid repository instead of copying an
# This is a quick way to get a valid repository instead of copying an
# existing one. Since it's not persisted, the importer will try to
# existing one. Since it's not persisted, the importer will try to
# create the project.
# create the project.
project
=
build
(
:project
,
:legacy_storage
,
:repository
)
let
(
:project
)
{
build
(
:project
,
:legacy_storage
,
:repository
)
}
original_commit_count
=
project
.
repository
.
commit_count
let
(
:project_path
)
{
project
.
full_path
}
legacy_path
=
Gitlab
.
config
.
repositories
.
storages
[
project
.
repository_storage
].
legacy_disk_path
bare_repo
=
Gitlab
::
BareRepositoryImport
::
Repository
.
new
(
legacy_path
,
project
.
repository
.
path
)
it
'moves an existing project to the correct path'
do
gitlab_importer
=
described_class
.
new
(
admin
,
bare_repo
)
original_commit_count
=
project
.
repository
.
commit_count
expect
(
gitlab_
importer
).
to
receive
(
:create_project
).
and_call_original
expect
(
importer
).
to
receive
(
:create_project
).
and_call_original
new_project
=
gitlab_
importer
.
create_project_if_needed
new_project
=
importer
.
create_project_if_needed
expect
(
new_project
.
repository
.
commit_count
).
to
eq
(
original_commit_count
)
expect
(
new_project
.
repository
.
commit_count
).
to
eq
(
original_commit_count
)
end
end
end
end
end
...
@@ -185,8 +178,8 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -185,8 +178,8 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
it_behaves_like
'importing a repository'
it_behaves_like
'importing a repository'
it
'creates the Wiki git repo in disk'
do
it
'creates the Wiki git repo in disk'
do
create_bare_repository
(
"
#{
project_path
}
.git"
)
prepare_repository
(
"
#{
project_path
}
.git"
,
source_project
)
create_bare_repository
(
"
#{
project_path
}
.wiki.git"
)
prepare_repository
(
"
#{
project_path
}
.wiki.git"
,
source_project
)
expect
(
Projects
::
CreateService
).
to
receive
(
:new
).
with
(
admin
,
hash_including
(
skip_wiki:
true
,
expect
(
Projects
::
CreateService
).
to
receive
(
:new
).
with
(
admin
,
hash_including
(
skip_wiki:
true
,
import_type:
'bare_repository'
)).
and_call_original
import_type:
'bare_repository'
)).
and_call_original
...
@@ -213,8 +206,13 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
...
@@ -213,8 +206,13 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
end
end
end
end
def
create_bare_repository
(
project_path
)
def
prepare_repository
(
project_path
,
source_project
)
repo_path
=
File
.
join
(
base_dir
,
project_path
)
repo_path
=
File
.
join
(
base_dir
,
project_path
)
Gitlab
::
Git
::
Repository
.
create
(
repo_path
,
bare:
true
)
return
create_bare_repository
(
repo_path
)
unless
source_project
cmd
=
%W(
#{
Gitlab
.
config
.
git
.
bin_path
}
clone --bare
#{
source_project
}
#{
repo_path
}
)
system
(
git_env
,
*
cmd
,
chdir:
SEED_STORAGE_PATH
,
out:
'/dev/null'
,
err:
'/dev/null'
)
end
end
end
end
spec/lib/gitlab/cleanup/project_uploads_spec.rb
0 → 100644
View file @
1f53cf7c
# frozen_string_literal: true
require
'spec_helper'
describe
Gitlab
::
Cleanup
::
ProjectUploads
do
subject
{
described_class
.
new
(
logger:
logger
)
}
let
(
:logger
)
{
double
(
:logger
)
}
before
do
allow
(
logger
).
to
receive
(
:info
).
at_least
(
1
).
times
allow
(
logger
).
to
receive
(
:debug
).
at_least
(
1
).
times
end
describe
'#run!'
do
shared_examples_for
'moves the file'
do
shared_examples_for
'a real run'
do
let
(
:args
)
{
[
dry_run:
false
]
}
it
'moves the file to its proper location'
do
subject
.
run!
(
*
args
)
expect
(
File
.
exist?
(
path
)).
to
be_falsey
expect
(
File
.
exist?
(
new_path
)).
to
be_truthy
end
it
'logs action as done'
do
expect
(
logger
).
to
receive
(
:info
).
with
(
"Looking for orphaned project uploads to clean up..."
)
expect
(
logger
).
to
receive
(
:info
).
with
(
"Did
#{
action
}
"
)
subject
.
run!
(
*
args
)
end
end
shared_examples_for
'a dry run'
do
it
'does not move the file'
do
subject
.
run!
(
*
args
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
expect
(
File
.
exist?
(
new_path
)).
to
be_falsey
end
it
'logs action as able to be done'
do
expect
(
logger
).
to
receive
(
:info
).
with
(
"Looking for orphaned project uploads to clean up. Dry run..."
)
expect
(
logger
).
to
receive
(
:info
).
with
(
"Can
#{
action
}
"
)
subject
.
run!
(
*
args
)
end
end
context
'when dry_run is false'
do
let
(
:args
)
{
[
dry_run:
false
]
}
it_behaves_like
'a real run'
end
context
'when dry_run is nil'
do
let
(
:args
)
{
[
dry_run:
nil
]
}
it_behaves_like
'a real run'
end
context
'when dry_run is true'
do
let
(
:args
)
{
[
dry_run:
true
]
}
it_behaves_like
'a dry run'
end
context
'with dry_run not specified'
do
let
(
:args
)
{
[]
}
it_behaves_like
'a dry run'
end
end
shared_examples_for
'moves the file to lost and found'
do
let
(
:action
)
{
"move to lost and found
#{
path
}
->
#{
new_path
}
"
}
it_behaves_like
'moves the file'
end
shared_examples_for
'fixes the file'
do
let
(
:action
)
{
"fix
#{
path
}
->
#{
new_path
}
"
}
it_behaves_like
'moves the file'
end
context
'orphaned project upload file'
do
context
'when an upload record matching the secret and filename is found'
do
context
'when the project is still in legacy storage'
do
let
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
create
(
:project
,
:legacy_storage
))
}
let
(
:new_path
)
{
orphaned
.
absolute_path
}
let
(
:path
)
{
File
.
join
(
FileUploader
.
root
,
'some'
,
'wrong'
,
'location'
,
orphaned
.
path
)
}
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
mv
(
new_path
,
path
)
end
it_behaves_like
'fixes the file'
end
context
'when the project was moved to hashed storage'
do
let
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
)
}
let
(
:new_path
)
{
orphaned
.
absolute_path
}
let
(
:path
)
{
File
.
join
(
FileUploader
.
root
,
'some'
,
'wrong'
,
'location'
,
orphaned
.
path
)
}
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
mv
(
new_path
,
path
)
end
it_behaves_like
'fixes the file'
end
context
'when the project is missing (the upload *record* is an orphan)'
do
let
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
}
let!
(
:path
)
{
orphaned
.
absolute_path
}
let!
(
:new_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
orphaned
.
model
.
full_path
,
orphaned
.
path
)
}
before
do
orphaned
.
model
.
delete
end
it_behaves_like
'moves the file to lost and found'
end
# We will probably want to add logic (Reschedule background upload) to
# cover Case 2 in https://gitlab.com/gitlab-org/gitlab-ce/issues/46535#note_75355104
context
'when the file should be in object storage'
do
context
'when the file otherwise has the correct local path'
do
let!
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:object_storage
,
model:
build
(
:project
,
:legacy_storage
))
}
let!
(
:path
)
{
File
.
join
(
FileUploader
.
root
,
orphaned
.
model
.
full_path
,
orphaned
.
path
)
}
before
do
stub_feature_flags
(
import_export_object_storage:
true
)
stub_uploads_object_storage
(
FileUploader
)
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
touch
(
path
)
end
it
'does not move the file'
do
expect
(
File
.
exist?
(
path
)).
to
be_truthy
subject
.
run!
(
dry_run:
false
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
end
# E.g. the upload file was orphaned, and then uploads were migrated to
# object storage
context
'when the file has the wrong local path'
do
let!
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:object_storage
,
model:
build
(
:project
,
:legacy_storage
))
}
let!
(
:path
)
{
File
.
join
(
FileUploader
.
root
,
'wrong'
,
orphaned
.
path
)
}
let!
(
:new_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
'wrong'
,
orphaned
.
path
)
}
before
do
stub_feature_flags
(
import_export_object_storage:
true
)
stub_uploads_object_storage
(
FileUploader
)
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
touch
(
path
)
end
it_behaves_like
'moves the file to lost and found'
end
end
end
context
'when a matching upload record can not be found'
do
context
'when the file path fits the known pattern'
do
let!
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
}
let!
(
:path
)
{
orphaned
.
absolute_path
}
let!
(
:new_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
orphaned
.
model
.
full_path
,
orphaned
.
path
)
}
before
do
orphaned
.
delete
end
it_behaves_like
'moves the file to lost and found'
end
context
'when the file path does not fit the known pattern'
do
let!
(
:invalid_path
)
{
File
.
join
(
'group'
,
'file.jpg'
)
}
let!
(
:path
)
{
File
.
join
(
FileUploader
.
root
,
invalid_path
)
}
let!
(
:new_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
invalid_path
)
}
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
touch
(
path
)
end
after
do
File
.
delete
(
path
)
if
File
.
exist?
(
path
)
end
it_behaves_like
'moves the file to lost and found'
end
end
end
context
'non-orphaned project upload file'
do
it
'does not move the file'
do
tracked
=
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
tracked_path
=
tracked
.
absolute_path
expect
(
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
expect
(
File
.
exist?
(
tracked_path
)).
to
be_truthy
subject
.
run!
(
dry_run:
false
)
expect
(
File
.
exist?
(
tracked_path
)).
to
be_truthy
end
end
context
'ignorable cases'
do
# Because we aren't concerned about these, and can save a lot of
# processing time by ignoring them. If we wish to cleanup hashed storage
# directories, it should simply require removing this test and modifying
# the find command.
context
'when the file is already in hashed storage'
do
let
(
:project
)
{
create
(
:project
)
}
before
do
expect
(
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
end
it
'does not move even an orphan file'
do
orphaned
=
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
project
)
path
=
orphaned
.
absolute_path
orphaned
.
delete
expect
(
File
.
exist?
(
path
)).
to
be_truthy
subject
.
run!
(
dry_run:
false
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
end
it
'does not move any non-project (FileUploader) uploads'
do
paths
=
[]
orphaned1
=
create
(
:upload
,
:personal_snippet_upload
,
:with_file
)
orphaned2
=
create
(
:upload
,
:namespace_upload
,
:with_file
)
orphaned3
=
create
(
:upload
,
:attachment_upload
,
:with_file
)
paths
<<
orphaned1
.
absolute_path
paths
<<
orphaned2
.
absolute_path
paths
<<
orphaned3
.
absolute_path
Upload
.
delete_all
expect
(
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
paths
.
each
do
|
path
|
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
subject
.
run!
(
dry_run:
false
)
paths
.
each
do
|
path
|
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
end
it
'does not move any uploads in tmp (which would interfere with ongoing upload activity)'
do
path
=
File
.
join
(
FileUploader
.
root
,
'tmp'
,
'foo.jpg'
)
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
touch
(
path
)
expect
(
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
subject
.
run!
(
dry_run:
false
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
end
end
end
spec/lib/gitlab/git/attributes_at_ref_parser_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
AttributesAtRefParser
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
AttributesAtRefParser
,
:seed_helper
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:repository
)
{
project
.
repository
}
let
(
:repository
)
{
project
.
repository
}
...
...
spec/lib/gitlab/git/attributes_parser_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
AttributesParser
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
AttributesParser
,
:seed_helper
do
let
(
:attributes_path
)
{
File
.
join
(
SEED_STORAGE_PATH
,
'with-git-attributes.git'
,
'info'
,
'attributes'
)
}
let
(
:attributes_path
)
{
File
.
join
(
SEED_STORAGE_PATH
,
'with-git-attributes.git'
,
'info'
,
'attributes'
)
}
let
(
:data
)
{
File
.
read
(
attributes_path
)
}
let
(
:data
)
{
File
.
read
(
attributes_path
)
}
...
...
spec/lib/gitlab/git/blame_spec.rb
View file @
1f53cf7c
# coding: utf-8
# coding: utf-8
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Blame
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Blame
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:blame
)
do
let
(
:blame
)
do
Gitlab
::
Git
::
Blame
.
new
(
repository
,
SeedRepo
::
Commit
::
ID
,
"CONTRIBUTING.md"
)
Gitlab
::
Git
::
Blame
.
new
(
repository
,
SeedRepo
::
Commit
::
ID
,
"CONTRIBUTING.md"
)
...
...
spec/lib/gitlab/git/blob_snippet_spec.rb
View file @
1f53cf7c
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
BlobSnippet
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
BlobSnippet
,
:seed_helper
do
describe
'#data'
do
describe
'#data'
do
context
'empty lines'
do
context
'empty lines'
do
let
(
:snippet
)
{
Gitlab
::
Git
::
BlobSnippet
.
new
(
'master'
,
nil
,
nil
,
nil
)
}
let
(
:snippet
)
{
Gitlab
::
Git
::
BlobSnippet
.
new
(
'master'
,
nil
,
nil
,
nil
)
}
...
...
spec/lib/gitlab/git/blob_spec.rb
View file @
1f53cf7c
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Blob
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Blob
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
describe
'initialize'
do
describe
'initialize'
do
...
...
spec/lib/gitlab/git/branch_spec.rb
View file @
1f53cf7c
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Branch
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Branch
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:rugged
)
do
let
(
:rugged
)
do
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
Gitlab
::
GitalyClient
::
StorageSettings
.
allow_disk_access
do
...
...
spec/lib/gitlab/git/commit_spec.rb
View file @
1f53cf7c
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Commit
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Commit
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:commit
)
{
described_class
.
find
(
repository
,
SeedRepo
::
Commit
::
ID
)
}
let
(
:commit
)
{
described_class
.
find
(
repository
,
SeedRepo
::
Commit
::
ID
)
}
let
(
:rugged_commit
)
do
let
(
:rugged_commit
)
do
...
...
spec/lib/gitlab/git/committer_with_hooks_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
CommitterWithHooks
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
CommitterWithHooks
,
:seed_helper
do
# TODO https://gitlab.com/gitlab-org/gitaly/issues/1234
# TODO https://gitlab.com/gitlab-org/gitaly/issues/1234
skip
'needs to be moved to gitaly-ruby test suite'
do
skip
'needs to be moved to gitaly-ruby test suite'
do
shared_examples
'calling wiki hooks'
do
shared_examples
'calling wiki hooks'
do
...
...
spec/lib/gitlab/git/compare_spec.rb
View file @
1f53cf7c
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Compare
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Compare
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:compare
)
{
Gitlab
::
Git
::
Compare
.
new
(
repository
,
SeedRepo
::
BigCommit
::
ID
,
SeedRepo
::
Commit
::
ID
,
straight:
false
)
}
let
(
:compare
)
{
Gitlab
::
Git
::
Compare
.
new
(
repository
,
SeedRepo
::
BigCommit
::
ID
,
SeedRepo
::
Commit
::
ID
,
straight:
false
)
}
let
(
:compare_straight
)
{
Gitlab
::
Git
::
Compare
.
new
(
repository
,
SeedRepo
::
BigCommit
::
ID
,
SeedRepo
::
Commit
::
ID
,
straight:
true
)
}
let
(
:compare_straight
)
{
Gitlab
::
Git
::
Compare
.
new
(
repository
,
SeedRepo
::
BigCommit
::
ID
,
SeedRepo
::
Commit
::
ID
,
straight:
true
)
}
...
...
spec/lib/gitlab/git/diff_collection_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
DiffCollection
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
DiffCollection
,
:seed_helper
do
subject
do
subject
do
Gitlab
::
Git
::
DiffCollection
.
new
(
Gitlab
::
Git
::
DiffCollection
.
new
(
iterator
,
iterator
,
...
...
spec/lib/gitlab/git/diff_spec.rb
View file @
1f53cf7c
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Diff
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Diff
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
before
do
before
do
...
...
spec/lib/gitlab/git/hooks_service_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
HooksService
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
HooksService
,
:seed_helper
do
let
(
:gl_id
)
{
'user-456'
}
let
(
:gl_id
)
{
'user-456'
}
let
(
:gl_username
)
{
'janedoe'
}
let
(
:gl_username
)
{
'janedoe'
}
let
(
:user
)
{
Gitlab
::
Git
::
User
.
new
(
gl_username
,
'Jane Doe'
,
'janedoe@example.com'
,
gl_id
)
}
let
(
:user
)
{
Gitlab
::
Git
::
User
.
new
(
gl_username
,
'Jane Doe'
,
'janedoe@example.com'
,
gl_id
)
}
...
...
spec/lib/gitlab/git/index_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
Index
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Index
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:index
)
{
described_class
.
new
(
repository
)
}
let
(
:index
)
{
described_class
.
new
(
repository
)
}
...
...
spec/lib/gitlab/git/remote_repository_spec.rb
View file @
1f53cf7c
require
'spec_helper'
require
'spec_helper'
describe
Gitlab
::
Git
::
RemoteRepository
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
RemoteRepository
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
subject
{
described_class
.
new
(
repository
)
}
subject
{
described_class
.
new
(
repository
)
}
...
...
spec/lib/gitlab/git/repository_spec.rb
View file @
1f53cf7c
# coding: utf-8
# coding: utf-8
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Repository
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Repository
,
:seed_helper
do
include
Gitlab
::
EncodingHelper
include
Gitlab
::
EncodingHelper
using
RSpec
::
Parameterized
::
TableSyntax
using
RSpec
::
Parameterized
::
TableSyntax
...
...
spec/lib/gitlab/git/tag_spec.rb
View file @
1f53cf7c
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Tag
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Tag
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
shared_examples
'Gitlab::Git::Repository#tags'
do
shared_examples
'Gitlab::Git::Repository#tags'
do
...
...
spec/lib/gitlab/git/tree_spec.rb
View file @
1f53cf7c
require
"spec_helper"
require
"spec_helper"
describe
Gitlab
::
Git
::
Tree
,
seed_helper:
true
do
describe
Gitlab
::
Git
::
Tree
,
:seed_helper
do
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
let
(
:repository
)
{
Gitlab
::
Git
::
Repository
.
new
(
'default'
,
TEST_REPO_PATH
,
''
)
}
context
:repo
do
context
:repo
do
...
...
spec/lib/gitlab/gitaly_client/storage_service_spec.rb
0 → 100644
View file @
1f53cf7c
require
'spec_helper'
describe
Gitlab
::
GitalyClient
::
StorageService
do
describe
'#delete_all_repositories'
do
let!
(
:project
)
{
create
(
:project
,
:repository
)
}
it
'removes all repositories'
do
described_class
.
new
(
project
.
repository_storage
).
delete_all_repositories
expect
(
project
.
repository
.
exists?
).
to
be
(
false
)
end
end
end
spec/lib/gitlab/import_export/file_importer_object_storage_spec.rb
0 → 100644
View file @
1f53cf7c
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
FileImporter
do
let
(
:shared
)
{
Gitlab
::
ImportExport
::
Shared
.
new
(
nil
)
}
let
(
:storage_path
)
{
"
#{
Dir
.
tmpdir
}
/file_importer_spec"
}
let
(
:valid_file
)
{
"
#{
shared
.
export_path
}
/valid.json"
}
let
(
:symlink_file
)
{
"
#{
shared
.
export_path
}
/invalid.json"
}
let
(
:hidden_symlink_file
)
{
"
#{
shared
.
export_path
}
/.hidden"
}
let
(
:subfolder_symlink_file
)
{
"
#{
shared
.
export_path
}
/subfolder/invalid.json"
}
let
(
:evil_symlink_file
)
{
"
#{
shared
.
export_path
}
/.
\n
evil"
}
before
do
stub_const
(
'Gitlab::ImportExport::FileImporter::MAX_RETRIES'
,
0
)
stub_feature_flags
(
import_export_object_storage:
true
)
stub_uploads_object_storage
(
FileUploader
)
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
storage_path
)
allow_any_instance_of
(
Gitlab
::
ImportExport
::
CommandLineUtil
).
to
receive
(
:untar_zxf
).
and_return
(
true
)
allow_any_instance_of
(
Gitlab
::
ImportExport
::
Shared
).
to
receive
(
:relative_archive_path
).
and_return
(
'test'
)
allow
(
SecureRandom
).
to
receive
(
:hex
).
and_return
(
'abcd'
)
setup_files
end
after
do
FileUtils
.
rm_rf
(
storage_path
)
end
context
'normal run'
do
before
do
described_class
.
import
(
project:
build
(
:project
),
archive_file:
''
,
shared:
shared
)
end
it
'removes symlinks in root folder'
do
expect
(
File
.
exist?
(
symlink_file
)).
to
be
false
end
it
'removes hidden symlinks in root folder'
do
expect
(
File
.
exist?
(
hidden_symlink_file
)).
to
be
false
end
it
'removes evil symlinks in root folder'
do
expect
(
File
.
exist?
(
evil_symlink_file
)).
to
be
false
end
it
'removes symlinks in subfolders'
do
expect
(
File
.
exist?
(
subfolder_symlink_file
)).
to
be
false
end
it
'does not remove a valid file'
do
expect
(
File
.
exist?
(
valid_file
)).
to
be
true
end
it
'creates the file in the right subfolder'
do
expect
(
shared
.
export_path
).
to
include
(
'test/abcd'
)
end
end
context
'error'
do
before
do
allow_any_instance_of
(
described_class
).
to
receive
(
:wait_for_archived_file
).
and_raise
(
StandardError
)
described_class
.
import
(
project:
build
(
:project
),
archive_file:
''
,
shared:
shared
)
end
it
'removes symlinks in root folder'
do
expect
(
File
.
exist?
(
symlink_file
)).
to
be
false
end
it
'removes hidden symlinks in root folder'
do
expect
(
File
.
exist?
(
hidden_symlink_file
)).
to
be
false
end
it
'removes symlinks in subfolders'
do
expect
(
File
.
exist?
(
subfolder_symlink_file
)).
to
be
false
end
it
'does not remove a valid file'
do
expect
(
File
.
exist?
(
valid_file
)).
to
be
true
end
end
def
setup_files
FileUtils
.
mkdir_p
(
"
#{
shared
.
export_path
}
/subfolder/"
)
FileUtils
.
touch
(
valid_file
)
FileUtils
.
ln_s
(
valid_file
,
symlink_file
)
FileUtils
.
ln_s
(
valid_file
,
subfolder_symlink_file
)
FileUtils
.
ln_s
(
valid_file
,
hidden_symlink_file
)
FileUtils
.
ln_s
(
valid_file
,
evil_symlink_file
)
end
end
spec/lib/gitlab/import_export/file_importer_spec.rb
View file @
1f53cf7c
...
@@ -24,7 +24,7 @@ describe Gitlab::ImportExport::FileImporter do
...
@@ -24,7 +24,7 @@ describe Gitlab::ImportExport::FileImporter do
context
'normal run'
do
context
'normal run'
do
before
do
before
do
described_class
.
import
(
archive_file:
''
,
shared:
shared
)
described_class
.
import
(
project:
nil
,
archive_file:
''
,
shared:
shared
)
end
end
it
'removes symlinks in root folder'
do
it
'removes symlinks in root folder'
do
...
@@ -55,7 +55,7 @@ describe Gitlab::ImportExport::FileImporter do
...
@@ -55,7 +55,7 @@ describe Gitlab::ImportExport::FileImporter do
context
'error'
do
context
'error'
do
before
do
before
do
allow_any_instance_of
(
described_class
).
to
receive
(
:wait_for_archived_file
).
and_raise
(
StandardError
)
allow_any_instance_of
(
described_class
).
to
receive
(
:wait_for_archived_file
).
and_raise
(
StandardError
)
described_class
.
import
(
archive_file:
''
,
shared:
shared
)
described_class
.
import
(
project:
nil
,
archive_file:
''
,
shared:
shared
)
end
end
it
'removes symlinks in root folder'
do
it
'removes symlinks in root folder'
do
...
...
spec/lib/gitlab/import_export/importer_object_storage_spec.rb
0 → 100644
View file @
1f53cf7c
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
Importer
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:test_path
)
{
"
#{
Dir
.
tmpdir
}
/importer_spec"
}
let
(
:shared
)
{
project
.
import_export_shared
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:import_file
)
{
fixture_file_upload
(
'spec/features/projects/import_export/test_project_export.tar.gz'
)
}
subject
(
:importer
)
{
described_class
.
new
(
project
)
}
before
do
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
test_path
)
allow_any_instance_of
(
Gitlab
::
ImportExport
::
FileImporter
).
to
receive
(
:remove_import_file
)
stub_feature_flags
(
import_export_object_storage:
true
)
stub_uploads_object_storage
(
FileUploader
)
FileUtils
.
mkdir_p
(
shared
.
export_path
)
ImportExportUpload
.
create
(
project:
project
,
import_file:
import_file
)
end
after
do
FileUtils
.
rm_rf
(
test_path
)
end
describe
'#execute'
do
it
'succeeds'
do
importer
.
execute
expect
(
shared
.
errors
).
to
be_empty
end
it
'extracts the archive'
do
expect
(
Gitlab
::
ImportExport
::
FileImporter
).
to
receive
(
:import
).
and_call_original
importer
.
execute
end
it
'checks the version'
do
expect
(
Gitlab
::
ImportExport
::
VersionChecker
).
to
receive
(
:check!
).
and_call_original
importer
.
execute
end
context
'all restores are executed'
do
[
Gitlab
::
ImportExport
::
AvatarRestorer
,
Gitlab
::
ImportExport
::
RepoRestorer
,
Gitlab
::
ImportExport
::
WikiRestorer
,
Gitlab
::
ImportExport
::
UploadsRestorer
,
Gitlab
::
ImportExport
::
LfsRestorer
,
Gitlab
::
ImportExport
::
StatisticsRestorer
].
each
do
|
restorer
|
it
"calls the
#{
restorer
}
"
do
fake_restorer
=
double
(
restorer
.
to_s
)
expect
(
fake_restorer
).
to
receive
(
:restore
).
and_return
(
true
).
at_least
(
1
)
expect
(
restorer
).
to
receive
(
:new
).
and_return
(
fake_restorer
).
at_least
(
1
)
importer
.
execute
end
end
it
'restores the ProjectTree'
do
expect
(
Gitlab
::
ImportExport
::
ProjectTreeRestorer
).
to
receive
(
:new
).
and_call_original
importer
.
execute
end
it
'removes the import file'
do
expect
(
importer
).
to
receive
(
:remove_import_file
).
and_call_original
importer
.
execute
expect
(
project
.
import_export_upload
.
import_file
&
.
file
).
to
be_nil
end
end
context
'when project successfully restored'
do
let!
(
:existing_project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
,
name:
'whatever'
,
path:
'whatever'
)
}
before
do
restorers
=
double
(
:restorers
,
all?:
true
)
allow
(
subject
).
to
receive
(
:import_file
).
and_return
(
true
)
allow
(
subject
).
to
receive
(
:check_version!
).
and_return
(
true
)
allow
(
subject
).
to
receive
(
:restorers
).
and_return
(
restorers
)
allow
(
project
).
to
receive
(
:import_data
).
and_return
(
double
(
data:
{
'original_path'
=>
existing_project
.
path
}))
end
context
'when import_data'
do
context
'has original_path'
do
it
'overwrites existing project'
do
expect_any_instance_of
(
::
Projects
::
OverwriteProjectService
).
to
receive
(
:execute
).
with
(
existing_project
)
subject
.
execute
end
end
context
'has not original_path'
do
before
do
allow
(
project
).
to
receive
(
:import_data
).
and_return
(
double
(
data:
{}))
end
it
'does not call the overwrite service'
do
expect_any_instance_of
(
::
Projects
::
OverwriteProjectService
).
not_to
receive
(
:execute
).
with
(
existing_project
)
subject
.
execute
end
end
end
end
end
end
spec/lib/gitlab/import_export/importer_spec.rb
View file @
1f53cf7c
...
@@ -10,9 +10,10 @@ describe Gitlab::ImportExport::Importer do
...
@@ -10,9 +10,10 @@ describe Gitlab::ImportExport::Importer do
before
do
before
do
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
test_path
)
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
test_path
)
allow_any_instance_of
(
Gitlab
::
ImportExport
::
FileImporter
).
to
receive
(
:remove_import_file
)
FileUtils
.
mkdir_p
(
shared
.
export_path
)
FileUtils
.
mkdir_p
(
shared
.
export_path
)
FileUtils
.
cp
(
Rails
.
root
.
join
(
'spec/features/projects/import_export/test_project_export.tar.gz'
),
test_path
)
FileUtils
.
cp
(
Rails
.
root
.
join
(
'spec/features/projects/import_export/test_project_export.tar.gz'
),
test_path
)
allow
(
subject
).
to
receive
(
:remove_import_file
)
end
end
after
do
after
do
...
@@ -69,7 +70,7 @@ describe Gitlab::ImportExport::Importer do
...
@@ -69,7 +70,7 @@ describe Gitlab::ImportExport::Importer do
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
,
name:
'whatever'
,
path:
'whatever'
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
,
name:
'whatever'
,
path:
'whatever'
)
}
before
do
before
do
restorers
=
double
restorers
=
double
(
:restorers
,
all?:
true
)
allow
(
subject
).
to
receive
(
:import_file
).
and_return
(
true
)
allow
(
subject
).
to
receive
(
:import_file
).
and_return
(
true
)
allow
(
subject
).
to
receive
(
:check_version!
).
and_return
(
true
)
allow
(
subject
).
to
receive
(
:check_version!
).
and_return
(
true
)
...
...
spec/lib/gitlab/kubernetes/helm/install_command_spec.rb
View file @
1f53cf7c
...
@@ -14,7 +14,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
...
@@ -14,7 +14,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
let
(
:commands
)
do
let
(
:commands
)
do
<<~
EOS
<<~
EOS
helm init --client-only >/dev/null
helm init --client-only >/dev/null
helm install
#{
application
.
chart
}
--name
#{
application
.
name
}
--namespace
#{
namespace
}
-f /data/helm/
#{
application
.
name
}
/config/values.yaml >/dev/null
helm install
#{
application
.
chart
}
--name
#{
application
.
name
}
--
version
#{
application
.
version
}
--
namespace
#{
namespace
}
-f /data/helm/
#{
application
.
name
}
/config/values.yaml >/dev/null
EOS
EOS
end
end
end
end
...
@@ -42,7 +42,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
...
@@ -42,7 +42,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
<<~
EOS
<<~
EOS
helm init --client-only >/dev/null
helm init --client-only >/dev/null
helm repo add
#{
application
.
name
}
#{
application
.
repository
}
helm repo add
#{
application
.
name
}
#{
application
.
repository
}
helm install
#{
application
.
chart
}
--name
#{
application
.
name
}
--namespace
#{
namespace
}
-f /data/helm/
#{
application
.
name
}
/config/values.yaml >/dev/null
helm install
#{
application
.
chart
}
--name
#{
application
.
name
}
--
version
#{
application
.
version
}
--
namespace
#{
namespace
}
-f /data/helm/
#{
application
.
name
}
/config/values.yaml >/dev/null
EOS
EOS
end
end
end
end
...
@@ -56,7 +56,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
...
@@ -56,7 +56,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do
<<~
EOS
<<~
EOS
helm init --client-only >/dev/null
helm init --client-only >/dev/null
helm repo add
#{
application
.
name
}
#{
application
.
repository
}
helm repo add
#{
application
.
name
}
#{
application
.
repository
}
helm install
#{
application
.
chart
}
--name
#{
application
.
name
}
--namespace
#{
namespace
}
-f /data/helm/
#{
application
.
name
}
/config/values.yaml >/dev/null
helm install
#{
application
.
chart
}
--name
#{
application
.
name
}
--
version
#{
application
.
version
}
--
namespace
#{
namespace
}
-f /data/helm/
#{
application
.
name
}
/config/values.yaml >/dev/null
EOS
EOS
end
end
end
end
...
...
spec/migrations/add_foreign_key_from_notification_settings_to_users_spec.rb
0 → 100644
View file @
1f53cf7c
# frozen_string_literal: true
require
'spec_helper'
require
Rails
.
root
.
join
(
'db'
,
'migrate'
,
'20180710162338_add_foreign_key_from_notification_settings_to_users.rb'
)
describe
AddForeignKeyFromNotificationSettingsToUsers
,
:migration
do
let
(
:notification_settings
)
{
table
(
:notification_settings
)
}
let
(
:users
)
{
table
(
:users
)
}
let
(
:projects
)
{
table
(
:projects
)
}
before
do
users
.
create!
(
email:
'email@email.com'
,
name:
'foo'
,
username:
'foo'
,
projects_limit:
0
)
projects
.
create!
(
name:
'gitlab'
,
path:
'gitlab-org/gitlab-ce'
,
namespace_id:
1
)
end
describe
'removal of orphans without user'
do
let!
(
:notification_setting_without_user
)
{
create_notification_settings!
(
user_id:
123
)
}
let!
(
:notification_setting_with_user
)
{
create_notification_settings!
(
user_id:
users
.
last
.
id
)
}
it
'removes orphaned notification_settings without user'
do
expect
{
migrate!
}.
to
change
{
notification_settings
.
count
}.
by
(
-
1
)
end
it
"doesn't remove notification_settings with valid user"
do
expect
{
migrate!
}.
not_to
change
{
notification_setting_with_user
.
reload
}
end
end
def
create_notification_settings!
(
**
opts
)
notification_settings
.
create!
(
source_id:
projects
.
last
.
id
,
source_type:
'Project'
,
user_id:
users
.
last
.
id
,
**
opts
)
end
end
spec/models/clusters/applications/ingress_spec.rb
View file @
1f53cf7c
...
@@ -23,6 +23,20 @@ describe Clusters::Applications::Ingress do
...
@@ -23,6 +23,20 @@ describe Clusters::Applications::Ingress do
it
{
is_expected
.
to
contain_exactly
(
cluster
)
}
it
{
is_expected
.
to
contain_exactly
(
cluster
)
}
end
end
describe
'#make_installing!'
do
before
do
application
.
make_installing!
end
context
'application install previously errored with older version'
do
let
(
:application
)
{
create
(
:clusters_applications_ingress
,
:scheduled
,
version:
'0.22.0'
)
}
it
'updates the application version'
do
expect
(
application
.
reload
.
version
).
to
eq
(
'0.23.0'
)
end
end
end
describe
'#make_installed!'
do
describe
'#make_installed!'
do
before
do
before
do
application
.
make_installed!
application
.
make_installed!
...
@@ -73,9 +87,17 @@ describe Clusters::Applications::Ingress do
...
@@ -73,9 +87,17 @@ describe Clusters::Applications::Ingress do
it
'should be initialized with ingress arguments'
do
it
'should be initialized with ingress arguments'
do
expect
(
subject
.
name
).
to
eq
(
'ingress'
)
expect
(
subject
.
name
).
to
eq
(
'ingress'
)
expect
(
subject
.
chart
).
to
eq
(
'stable/nginx-ingress'
)
expect
(
subject
.
chart
).
to
eq
(
'stable/nginx-ingress'
)
expect
(
subject
.
version
).
to
be_nil
expect
(
subject
.
version
).
to
eq
(
'0.23.0'
)
expect
(
subject
.
values
).
to
eq
(
ingress
.
values
)
expect
(
subject
.
values
).
to
eq
(
ingress
.
values
)
end
end
context
'application failed to install previously'
do
let
(
:ingress
)
{
create
(
:clusters_applications_ingress
,
:errored
,
version:
'nginx'
)
}
it
'should be initialized with the locked version'
do
expect
(
subject
.
version
).
to
eq
(
'0.23.0'
)
end
end
end
end
describe
'#values'
do
describe
'#values'
do
...
...
spec/models/clusters/applications/jupyter_spec.rb
View file @
1f53cf7c
...
@@ -25,6 +25,20 @@ describe Clusters::Applications::Jupyter do
...
@@ -25,6 +25,20 @@ describe Clusters::Applications::Jupyter do
end
end
end
end
describe
'#make_installing!'
do
before
do
application
.
make_installing!
end
context
'application install previously errored with older version'
do
let
(
:application
)
{
create
(
:clusters_applications_jupyter
,
:scheduled
,
version:
'v0.5'
)
}
it
'updates the application version'
do
expect
(
application
.
reload
.
version
).
to
eq
(
'v0.6'
)
end
end
end
describe
'#install_command'
do
describe
'#install_command'
do
let!
(
:ingress
)
{
create
(
:clusters_applications_ingress
,
:installed
,
external_ip:
'127.0.0.1'
)
}
let!
(
:ingress
)
{
create
(
:clusters_applications_ingress
,
:installed
,
external_ip:
'127.0.0.1'
)
}
let!
(
:jupyter
)
{
create
(
:clusters_applications_jupyter
,
cluster:
ingress
.
cluster
)
}
let!
(
:jupyter
)
{
create
(
:clusters_applications_jupyter
,
cluster:
ingress
.
cluster
)
}
...
@@ -36,10 +50,18 @@ describe Clusters::Applications::Jupyter do
...
@@ -36,10 +50,18 @@ describe Clusters::Applications::Jupyter do
it
'should be initialized with 4 arguments'
do
it
'should be initialized with 4 arguments'
do
expect
(
subject
.
name
).
to
eq
(
'jupyter'
)
expect
(
subject
.
name
).
to
eq
(
'jupyter'
)
expect
(
subject
.
chart
).
to
eq
(
'jupyter/jupyterhub'
)
expect
(
subject
.
chart
).
to
eq
(
'jupyter/jupyterhub'
)
expect
(
subject
.
version
).
to
be_nil
expect
(
subject
.
version
).
to
eq
(
'v0.6'
)
expect
(
subject
.
repository
).
to
eq
(
'https://jupyterhub.github.io/helm-chart/'
)
expect
(
subject
.
repository
).
to
eq
(
'https://jupyterhub.github.io/helm-chart/'
)
expect
(
subject
.
values
).
to
eq
(
jupyter
.
values
)
expect
(
subject
.
values
).
to
eq
(
jupyter
.
values
)
end
end
context
'application failed to install previously'
do
let
(
:jupyter
)
{
create
(
:clusters_applications_jupyter
,
:errored
,
version:
'0.0.1'
)
}
it
'should be initialized with the locked version'
do
expect
(
subject
.
version
).
to
eq
(
'v0.6'
)
end
end
end
end
describe
'#values'
do
describe
'#values'
do
...
...
spec/models/clusters/applications/prometheus_spec.rb
View file @
1f53cf7c
...
@@ -16,6 +16,20 @@ describe Clusters::Applications::Prometheus do
...
@@ -16,6 +16,20 @@ describe Clusters::Applications::Prometheus do
it
{
is_expected
.
to
contain_exactly
(
cluster
)
}
it
{
is_expected
.
to
contain_exactly
(
cluster
)
}
end
end
describe
'#make_installing!'
do
before
do
application
.
make_installing!
end
context
'application install previously errored with older version'
do
let
(
:application
)
{
create
(
:clusters_applications_prometheus
,
:scheduled
,
version:
'6.7.2'
)
}
it
'updates the application version'
do
expect
(
application
.
reload
.
version
).
to
eq
(
'6.7.3'
)
end
end
end
describe
'transition to installed'
do
describe
'transition to installed'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:cluster
)
{
create
(
:cluster
,
projects:
[
project
])
}
let
(
:cluster
)
{
create
(
:cluster
,
projects:
[
project
])
}
...
@@ -155,6 +169,14 @@ describe Clusters::Applications::Prometheus do
...
@@ -155,6 +169,14 @@ describe Clusters::Applications::Prometheus do
expect
(
command
.
version
).
to
eq
(
'6.7.3'
)
expect
(
command
.
version
).
to
eq
(
'6.7.3'
)
expect
(
command
.
values
).
to
eq
(
prometheus
.
values
)
expect
(
command
.
values
).
to
eq
(
prometheus
.
values
)
end
end
context
'application failed to install previously'
do
let
(
:prometheus
)
{
create
(
:clusters_applications_prometheus
,
:errored
,
version:
'2.0.0'
)
}
it
'should be initialized with the locked version'
do
expect
(
subject
.
version
).
to
eq
(
'6.7.3'
)
end
end
end
end
describe
'#values'
do
describe
'#values'
do
...
...
spec/models/clusters/applications/runner_spec.rb
View file @
1f53cf7c
...
@@ -8,6 +8,20 @@ describe Clusters::Applications::Runner do
...
@@ -8,6 +8,20 @@ describe Clusters::Applications::Runner do
it
{
is_expected
.
to
belong_to
(
:runner
)
}
it
{
is_expected
.
to
belong_to
(
:runner
)
}
describe
'#make_installing!'
do
before
do
application
.
make_installing!
end
context
'application install previously errored with older version'
do
let
(
:application
)
{
create
(
:clusters_applications_runner
,
:scheduled
,
version:
'0.1.30'
)
}
it
'updates the application version'
do
expect
(
application
.
reload
.
version
).
to
eq
(
'0.1.31'
)
end
end
end
describe
'.installed'
do
describe
'.installed'
do
subject
{
described_class
.
installed
}
subject
{
described_class
.
installed
}
...
@@ -31,10 +45,18 @@ describe Clusters::Applications::Runner do
...
@@ -31,10 +45,18 @@ describe Clusters::Applications::Runner do
it
'should be initialized with 4 arguments'
do
it
'should be initialized with 4 arguments'
do
expect
(
subject
.
name
).
to
eq
(
'runner'
)
expect
(
subject
.
name
).
to
eq
(
'runner'
)
expect
(
subject
.
chart
).
to
eq
(
'runner/gitlab-runner'
)
expect
(
subject
.
chart
).
to
eq
(
'runner/gitlab-runner'
)
expect
(
subject
.
version
).
to
be_nil
expect
(
subject
.
version
).
to
eq
(
'0.1.31'
)
expect
(
subject
.
repository
).
to
eq
(
'https://charts.gitlab.io'
)
expect
(
subject
.
repository
).
to
eq
(
'https://charts.gitlab.io'
)
expect
(
subject
.
values
).
to
eq
(
gitlab_runner
.
values
)
expect
(
subject
.
values
).
to
eq
(
gitlab_runner
.
values
)
end
end
context
'application failed to install previously'
do
let
(
:gitlab_runner
)
{
create
(
:clusters_applications_runner
,
:errored
,
runner:
ci_runner
,
version:
'0.1.13'
)
}
it
'should be initialized with the locked version'
do
expect
(
subject
.
version
).
to
eq
(
'0.1.31'
)
end
end
end
end
describe
'#values'
do
describe
'#values'
do
...
...
spec/models/deploy_token_spec.rb
View file @
1f53cf7c
...
@@ -74,6 +74,14 @@ describe DeployToken do
...
@@ -74,6 +74,14 @@ describe DeployToken do
expect
(
deploy_token
.
active?
).
to
be_falsy
expect
(
deploy_token
.
active?
).
to
be_falsy
end
end
end
end
context
"when it hasn't been revoked and has no expiry"
do
let
(
:deploy_token
)
{
create
(
:deploy_token
,
expires_at:
nil
)
}
it
'should return true'
do
expect
(
deploy_token
.
active?
).
to
be_truthy
end
end
end
end
describe
'#username'
do
describe
'#username'
do
...
...
spec/models/merge_request_diff_spec.rb
View file @
1f53cf7c
...
@@ -127,6 +127,13 @@ describe MergeRequestDiff do
...
@@ -127,6 +127,13 @@ describe MergeRequestDiff do
expect
(
diffs
.
map
(
&
:new_path
)).
to
contain_exactly
(
'files/ruby/popen.rb'
)
expect
(
diffs
.
map
(
&
:new_path
)).
to
contain_exactly
(
'files/ruby/popen.rb'
)
end
end
it
'only serializes diff files found by query'
do
expect
(
diff_with_commits
.
merge_request_diff_files
.
count
).
to
be
>
10
expect_any_instance_of
(
MergeRequestDiffFile
).
to
receive
(
:to_hash
).
once
diffs
end
it
'uses the diffs from the DB'
do
it
'uses the diffs from the DB'
do
expect
(
diff_with_commits
).
to
receive
(
:load_diffs
)
expect
(
diff_with_commits
).
to
receive
(
:load_diffs
)
...
...
spec/requests/api/project_import_spec.rb
View file @
1f53cf7c
...
@@ -7,6 +7,8 @@ describe API::ProjectImport do
...
@@ -7,6 +7,8 @@ describe API::ProjectImport do
let
(
:namespace
)
{
create
(
:group
)
}
let
(
:namespace
)
{
create
(
:group
)
}
before
do
before
do
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
allow_any_instance_of
(
Gitlab
::
ImportExport
).
to
receive
(
:storage_path
).
and_return
(
export_path
)
stub_feature_flags
(
import_export_object_storage:
true
)
stub_uploads_object_storage
(
FileUploader
)
namespace
.
add_owner
(
user
)
namespace
.
add_owner
(
user
)
end
end
...
...
spec/services/projects/gitlab_projects_import_service_spec.rb
View file @
1f53cf7c
...
@@ -3,7 +3,7 @@ require 'spec_helper'
...
@@ -3,7 +3,7 @@ require 'spec_helper'
describe
Projects
::
GitlabProjectsImportService
do
describe
Projects
::
GitlabProjectsImportService
do
set
(
:namespace
)
{
create
(
:namespace
)
}
set
(
:namespace
)
{
create
(
:namespace
)
}
let
(
:path
)
{
'test-path'
}
let
(
:path
)
{
'test-path'
}
let
(
:file
)
{
fixture_file_upload
(
'spec/fixtures/
doc_sample.txt'
,
'text/plain
'
)
}
let
(
:file
)
{
fixture_file_upload
(
'spec/fixtures/
project_export.tar.gz
'
)
}
let
(
:overwrite
)
{
false
}
let
(
:overwrite
)
{
false
}
let
(
:import_params
)
{
{
namespace_id:
namespace
.
id
,
path:
path
,
file:
file
,
overwrite:
overwrite
}
}
let
(
:import_params
)
{
{
namespace_id:
namespace
.
id
,
path:
path
,
file:
file
,
overwrite:
overwrite
}
}
...
...
spec/services/users/activity_service_spec.rb
View file @
1f53cf7c
...
@@ -28,6 +28,18 @@ describe Users::ActivityService do
...
@@ -28,6 +28,18 @@ describe Users::ActivityService do
end
end
end
end
context
'when a bad object is passed'
do
let
(
:fake_object
)
{
double
(
username:
'hello'
)
}
it
'does not record activity'
do
service
=
described_class
.
new
(
fake_object
,
'pull'
)
expect
(
service
).
not_to
receive
(
:record_activity
)
service
.
execute
end
end
context
'when last activity is today'
do
context
'when last activity is today'
do
let
(
:last_activity_on
)
{
Date
.
today
}
let
(
:last_activity_on
)
{
Date
.
today
}
...
...
spec/support/helpers/seed_helper.rb
View file @
1f53cf7c
...
@@ -101,10 +101,4 @@ bla/bla.txt
...
@@ -101,10 +101,4 @@ bla/bla.txt
handle
.
write
(
'# hello'
.
encode
(
enc
))
handle
.
write
(
'# hello'
.
encode
(
enc
))
end
end
end
end
# Prevent developer git configurations from being persisted to test
# repositories
def
git_env
{
'GIT_TEMPLATE_DIR'
=>
''
}
end
end
end
spec/support/helpers/test_env.rb
View file @
1f53cf7c
...
@@ -243,6 +243,14 @@ module TestEnv
...
@@ -243,6 +243,14 @@ module TestEnv
set_repo_refs
(
target_repo_path
,
refs
)
set_repo_refs
(
target_repo_path
,
refs
)
end
end
def
create_bare_repository
(
path
)
FileUtils
.
mkdir_p
(
path
)
system
(
git_env
,
*
%W(
#{
Gitlab
.
config
.
git
.
bin_path
}
-C
#{
path
}
init --bare)
,
out:
'/dev/null'
,
err:
'/dev/null'
)
end
def
repos_path
def
repos_path
@repos_path
||=
Gitlab
.
config
.
repositories
.
storages
[
REPOS_STORAGE
].
legacy_disk_path
@repos_path
||=
Gitlab
.
config
.
repositories
.
storages
[
REPOS_STORAGE
].
legacy_disk_path
end
end
...
...
spec/support/shared_examples/helm_generated_script.rb
View file @
1f53cf7c
...
@@ -7,7 +7,7 @@ shared_examples 'helm commands' do
...
@@ -7,7 +7,7 @@ shared_examples 'helm commands' do
echo http://mirror.clarkson.edu/alpine/v$ALPINE_VERSION/main >> /etc/apk/repositories
echo http://mirror.clarkson.edu/alpine/v$ALPINE_VERSION/main >> /etc/apk/repositories
echo http://mirror1.hs-esslingen.de/pub/Mirrors/alpine/v$ALPINE_VERSION/main >> /etc/apk/repositories
echo http://mirror1.hs-esslingen.de/pub/Mirrors/alpine/v$ALPINE_VERSION/main >> /etc/apk/repositories
apk add -U wget ca-certificates openssl >/dev/null
apk add -U wget ca-certificates openssl >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.
0
-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
wget -q -O - https://kubernetes-helm.storage.googleapis.com/helm-v2.7.
2
-linux-amd64.tar.gz | tar zxC /tmp >/dev/null
mv /tmp/linux-amd64/helm /usr/bin/
mv /tmp/linux-amd64/helm /usr/bin/
EOS
EOS
end
end
...
...
spec/support/stored_repositories.rb
View file @
1f53cf7c
RSpec
.
configure
do
|
config
|
RSpec
.
configure
do
|
config
|
config
.
before
(
:each
,
:repository
)
do
TestEnv
.
clean_test_path
end
config
.
before
(
:all
,
:broken_storage
)
do
config
.
before
(
:all
,
:broken_storage
)
do
FileUtils
.
rm_rf
Gitlab
.
config
.
repositories
.
storages
.
broken
.
legacy_disk_path
FileUtils
.
rm_rf
Gitlab
.
config
.
repositories
.
storages
.
broken
.
legacy_disk_path
end
end
...
...
spec/tasks/gitlab/backup_rake_spec.rb
View file @
1f53cf7c
...
@@ -87,6 +87,27 @@ describe 'gitlab:app namespace rake task' do
...
@@ -87,6 +87,27 @@ describe 'gitlab:app namespace rake task' do
expect
{
run_rake_task
(
'gitlab:backup:restore'
)
}.
to
output
.
to_stdout
expect
{
run_rake_task
(
'gitlab:backup:restore'
)
}.
to
output
.
to_stdout
end
end
end
end
context
'when the restore directory is not empty'
do
before
do
# We only need a backup of the repositories for this test
stub_env
(
'SKIP'
,
'db,uploads,builds,artifacts,lfs,registry'
)
end
it
'removes stale data'
do
expect
{
run_rake_task
(
'gitlab:backup:create'
)
}.
to
output
.
to_stdout
excluded_project
=
create
(
:project
,
:repository
,
name:
'mepmep'
)
expect
{
run_rake_task
(
'gitlab:backup:restore'
)
}.
to
output
.
to_stdout
raw_repo
=
excluded_project
.
repository
.
raw
# The restore will not find the repository in the backup, but will create
# an empty one in its place
expect
(
raw_repo
.
empty?
).
to
be
(
true
)
end
end
end
# backup_restore task
end
# backup_restore task
describe
'backup'
do
describe
'backup'
do
...
...
spec/tasks/gitlab/cleanup_rake_spec.rb
View file @
1f53cf7c
...
@@ -68,317 +68,86 @@ describe 'gitlab:cleanup rake tasks' do
...
@@ -68,317 +68,86 @@ describe 'gitlab:cleanup rake tasks' do
end
end
end
end
# A single integration test that is redundant with one part of the
# Gitlab::Cleanup::ProjectUploads spec.
#
# Additionally, this tests DRY_RUN env var values, and the extra line of
# output that says you can disable DRY_RUN if it's enabled.
describe
'cleanup:project_uploads'
do
describe
'cleanup:project_uploads'
do
context
'orphaned project upload file'
do
let!
(
:logger
)
{
double
(
:logger
)
}
context
'when an upload record matching the secret and filename is found'
do
context
'when the project is still in legacy storage'
do
let!
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
}
let!
(
:correct_path
)
{
orphaned
.
absolute_path
}
let!
(
:other_project
)
{
create
(
:project
,
:legacy_storage
)
}
let!
(
:orphaned_path
)
{
correct_path
.
sub
(
/
#{
orphaned
.
model
.
full_path
}
/
,
other_project
.
full_path
)
}
before
do
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
orphaned_path
))
expect
(
main_object
).
to
receive
(
:logger
).
and_return
(
logger
).
at_least
(
1
).
times
FileUtils
.
mv
(
correct_path
,
orphaned_path
)
end
it
'moves the file to its proper location'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Did fix
#{
orphaned_path
}
->
#{
correct_path
}
"
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
correct_path
)).
to
be_falsey
stub_env
(
'DRY_RUN'
,
'false'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_falsey
expect
(
File
.
exist?
(
correct_path
)).
to
be_truthy
end
it
'a dry run does not move the file'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Can fix
#{
orphaned_path
}
->
#{
correct_path
}
"
)
expect
(
Rails
.
logger
).
to
receive
(
:info
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
correct_path
)).
to
be_falsey
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
correct_path
)).
to
be_falsey
end
context
'when the project record is missing (Upload#absolute_path raises error)'
do
let!
(
:lost_and_found_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
other_project
.
full_path
,
orphaned
.
path
)
}
before
do
orphaned
.
model
.
delete
end
it
'moves the file to lost and found'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Did move to lost and found
#{
orphaned_path
}
->
#{
lost_and_found_path
}
"
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
stub_env
(
'DRY_RUN'
,
'false'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_falsey
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_truthy
end
it
'a dry run does not move the file'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Can move to lost and found
#{
orphaned_path
}
->
#{
lost_and_found_path
}
"
)
expect
(
Rails
.
logger
).
to
receive
(
:info
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
end
end
end
context
'when the project was moved to hashed storage'
do
let!
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
)
}
let!
(
:correct_path
)
{
orphaned
.
absolute_path
}
let!
(
:orphaned_path
)
{
File
.
join
(
FileUploader
.
root
,
'foo'
,
'bar'
,
orphaned
.
path
)
}
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
orphaned_path
))
FileUtils
.
mv
(
correct_path
,
orphaned_path
)
end
it
'moves the file to its proper location'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Did fix
#{
orphaned_path
}
->
#{
correct_path
}
"
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
correct_path
)).
to
be_falsey
stub_env
(
'DRY_RUN'
,
'false'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_falsey
expect
(
File
.
exist?
(
correct_path
)).
to
be_truthy
end
it
'a dry run does not move the file'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Can fix
#{
orphaned_path
}
->
#{
correct_path
}
"
)
expect
(
Rails
.
logger
).
to
receive
(
:info
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
allow
(
logger
).
to
receive
(
:info
).
at_least
(
1
).
times
expect
(
File
.
exist?
(
correct_path
)).
to
be_falsey
allow
(
logger
).
to
receive
(
:debug
).
at_least
(
1
).
times
end
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
context
'with a fixable orphaned project upload file'
do
let
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
}
let
(
:new_path
)
{
orphaned
.
absolute_path
}
let
(
:path
)
{
File
.
join
(
FileUploader
.
root
,
'some'
,
'wrong'
,
'location'
,
orphaned
.
path
)
}
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
before
do
expect
(
File
.
exist?
(
correct_path
)).
to
be_falsey
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
end
FileUtils
.
mv
(
new_path
,
path
)
end
end
end
context
'when a matching upload record can not be found'
do
context
'with DRY_RUN disabled'
do
context
'when the file path fits the known pattern'
do
before
do
let!
(
:orphaned
)
{
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
}
stub_env
(
'DRY_RUN'
,
'false'
)
let!
(
:orphaned_path
)
{
orphaned
.
absolute_path
}
let!
(
:lost_and_found_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
orphaned
.
model
.
full_path
,
orphaned
.
path
)
}
before
do
orphaned
.
delete
end
it
'moves the file to lost and found'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Did move to lost and found
#{
orphaned_path
}
->
#{
lost_and_found_path
}
"
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
stub_env
(
'DRY_RUN'
,
'false'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_falsey
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_truthy
end
it
'a dry run does not move the file'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Can move to lost and found
#{
orphaned_path
}
->
#{
lost_and_found_path
}
"
)
expect
(
Rails
.
logger
).
to
receive
(
:info
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
end
end
end
context
'when the file path does not fit the known pattern'
do
it
'moves the file to its proper location'
do
let!
(
:invalid_path
)
{
File
.
join
(
'group'
,
'file.jpg'
)
}
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
let!
(
:orphaned_path
)
{
File
.
join
(
FileUploader
.
root
,
invalid_path
)
}
let!
(
:lost_and_found_path
)
{
File
.
join
(
FileUploader
.
root
,
'-'
,
'project-lost-found'
,
invalid_path
)
}
before
do
FileUtils
.
mkdir_p
(
File
.
dirname
(
orphaned_path
))
FileUtils
.
touch
(
orphaned_path
)
end
after
do
File
.
delete
(
orphaned_path
)
if
File
.
exist?
(
orphaned_path
)
end
it
'moves the file to lost and found'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Did move to lost and found
#{
orphaned_path
}
->
#{
lost_and_found_path
}
"
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
stub_env
(
'DRY_RUN'
,
'false'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_falsey
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_truthy
end
it
'a dry run does not move the file'
do
expect
(
Rails
.
logger
).
to
receive
(
:info
).
twice
expect
(
Rails
.
logger
).
to
receive
(
:info
).
with
(
"Can move to lost and found
#{
orphaned_path
}
->
#{
lost_and_found_path
}
"
)
expect
(
Rails
.
logger
).
to
receive
(
:info
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
expect
(
File
.
exist?
(
path
)).
to
be_falsey
expect
(
File
.
exist?
(
lost_and_found_path
)).
to
be_falsey
expect
(
File
.
exist?
(
new_path
)).
to
be_truthy
end
end
end
end
end
context
'non-orphaned project upload file'
do
it
'does not move the file'
do
tracked
=
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
build
(
:project
,
:legacy_storage
))
tracked_path
=
tracked
.
absolute_path
expect
(
Rails
.
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
it
'logs action as done'
do
expect
(
File
.
exist?
(
tracked_path
)).
to
be_truthy
expect
(
logger
).
to
receive
(
:info
).
with
(
"Looking for orphaned project uploads to clean up..."
)
expect
(
logger
).
to
receive
(
:info
).
with
(
"Did fix
#{
path
}
->
#{
new_path
}
"
)
stub_env
(
'DRY_RUN'
,
'false'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
tracked_path
)).
to
be_truthy
end
end
context
'ignorable cases'
do
shared_examples_for
'does not move anything'
do
it
'does not move even an orphan file'
do
orphaned
=
create
(
:upload
,
:issuable_upload
,
:with_file
,
model:
project
)
orphaned_path
=
orphaned
.
absolute_path
orphaned
.
delete
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
orphaned_path
)).
to
be_truthy
end
end
end
end
# Because we aren't concerned about these, and can save a lot of
shared_examples_for
'does not move the file'
do
# processing time by ignoring them. If we wish to cleanup hashed storage
it
'does not move the file'
do
# directories, it should simply require removing this test and modifying
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
# the find command.
context
'when the file is already in hashed storage'
do
let
(
:project
)
{
create
(
:project
)
}
before
do
expect
(
File
.
exist?
(
path
)).
to
be_truthy
stub_env
(
'DRY_RUN'
,
'false'
)
expect
(
File
.
exist?
(
new_path
)).
to
be_falsey
expect
(
Rails
.
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
end
end
it_behaves_like
'does not move anything'
it
'logs action as able to be done'
do
end
expect
(
logger
).
to
receive
(
:info
).
with
(
"Looking for orphaned project uploads to clean up. Dry run..."
)
expect
(
logger
).
to
receive
(
:info
).
with
(
"Can fix
#{
path
}
->
#{
new_path
}
"
)
context
'when DRY_RUN env var is unset'
do
expect
(
logger
).
to
receive
(
:info
).
with
(
/To clean up these files run this command with DRY_RUN=false/
)
let
(
:project
)
{
create
(
:project
,
:legacy_storage
)
}
it_behaves_like
'does not move anything'
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
end
end
end
context
'when DRY_RUN env var is true'
do
context
'with DRY_RUN explicitly enabled'
do
let
(
:project
)
{
create
(
:project
,
:legacy_storage
)
}
before
do
before
do
stub_env
(
'DRY_RUN'
,
'true'
)
stub_env
(
'DRY_RUN'
,
'true'
)
end
end
it_behaves_like
'does not move
anything
'
it_behaves_like
'does not move
the file
'
end
end
context
'when DRY_RUN env var is foo'
do
context
'with DRY_RUN set to an unknown value'
do
let
(
:project
)
{
create
(
:project
,
:legacy_storage
)
}
before
do
before
do
stub_env
(
'DRY_RUN'
,
'foo'
)
stub_env
(
'DRY_RUN'
,
'foo'
)
end
end
it_behaves_like
'does not move
anything
'
it_behaves_like
'does not move
the file
'
end
end
it
'does not move any non-project (FileUploader) uploads'
do
context
'with DRY_RUN unset'
do
stub_env
(
'DRY_RUN'
,
'false'
)
it_behaves_like
'does not move the file'
paths
=
[]
orphaned1
=
create
(
:upload
,
:personal_snippet_upload
,
:with_file
)
orphaned2
=
create
(
:upload
,
:namespace_upload
,
:with_file
)
orphaned3
=
create
(
:upload
,
:attachment_upload
,
:with_file
)
paths
<<
orphaned1
.
absolute_path
paths
<<
orphaned2
.
absolute_path
paths
<<
orphaned3
.
absolute_path
Upload
.
delete_all
expect
(
Rails
.
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
paths
.
each
do
|
path
|
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
paths
.
each
do
|
path
|
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
end
it
'does not move any uploads in tmp (which would interfere with ongoing upload activity)'
do
stub_env
(
'DRY_RUN'
,
'false'
)
path
=
File
.
join
(
FileUploader
.
root
,
'tmp'
,
'foo.jpg'
)
FileUtils
.
mkdir_p
(
File
.
dirname
(
path
))
FileUtils
.
touch
(
path
)
expect
(
Rails
.
logger
).
not_to
receive
(
:info
).
with
(
/move|fix/i
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
run_rake_task
(
'gitlab:cleanup:project_uploads'
)
expect
(
File
.
exist?
(
path
)).
to
be_truthy
end
end
end
end
end
end
...
...
spec/workers/create_gpg_signature_worker_spec.rb
View file @
1f53cf7c
...
@@ -4,10 +4,9 @@ describe CreateGpgSignatureWorker do
...
@@ -4,10 +4,9 @@ describe CreateGpgSignatureWorker do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:commits
)
{
project
.
repository
.
commits
(
'HEAD'
,
limit:
3
).
commits
}
let
(
:commits
)
{
project
.
repository
.
commits
(
'HEAD'
,
limit:
3
).
commits
}
let
(
:commit_shas
)
{
commits
.
map
(
&
:id
)
}
let
(
:commit_shas
)
{
commits
.
map
(
&
:id
)
}
let
(
:gpg_commit
)
{
instance_double
(
Gitlab
::
Gpg
::
Commit
)
}
context
'when GpgKey is found'
do
context
'when GpgKey is found'
do
let
(
:gpg_commit
)
{
instance_double
(
Gitlab
::
Gpg
::
Commit
)
}
before
do
before
do
allow
(
Project
).
to
receive
(
:find_by
).
with
(
id:
project
.
id
).
and_return
(
project
)
allow
(
Project
).
to
receive
(
:find_by
).
with
(
id:
project
.
id
).
and_return
(
project
)
allow
(
project
).
to
receive
(
:commits_by
).
with
(
oids:
commit_shas
).
and_return
(
commits
)
allow
(
project
).
to
receive
(
:commits_by
).
with
(
oids:
commit_shas
).
and_return
(
commits
)
...
@@ -36,6 +35,16 @@ describe CreateGpgSignatureWorker do
...
@@ -36,6 +35,16 @@ describe CreateGpgSignatureWorker do
end
end
end
end
context
'handles when a string is passed in for the commit SHA'
do
it
'creates a signature once'
do
allow
(
Gitlab
::
Gpg
::
Commit
).
to
receive
(
:new
).
with
(
commits
.
first
).
and_return
(
gpg_commit
)
expect
(
gpg_commit
).
to
receive
(
:signature
).
once
described_class
.
new
.
perform
(
commit_shas
.
first
,
project
.
id
)
end
end
context
'when Commit is not found'
do
context
'when Commit is not found'
do
let
(
:nonexisting_commit_sha
)
{
'0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a34'
}
let
(
:nonexisting_commit_sha
)
{
'0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a34'
}
...
...
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