debian-mirror-gitlab/lib/gitlab/shell.rb

201 lines
6.7 KiB
Ruby
Raw Normal View History

2018-12-13 13:39:08 +05:30
# frozen_string_literal: true
2016-08-24 12:49:21 +05:30
require 'securerandom'
2014-09-02 18:07:02 +05:30
module Gitlab
2020-04-08 14:13:33 +05:30
# This class is an artifact of a time when common repository operations were
# performed by calling out to scripts in the gitlab-shell project. Now, these
# operations are all performed by Gitaly, and are mostly accessible through
# the Repository class. Prefer using a Repository to functionality here.
#
# Legacy code relating to namespaces still relies on Gitlab::Shell; it can be
# converted to a module once https://gitlab.com/groups/gitlab-org/-/epics/2320
# is completed. https://gitlab.com/gitlab-org/gitlab/-/issues/25095 tracks it.
2014-09-02 18:07:02 +05:30
class Shell
2017-08-17 22:00:37 +05:30
Error = Class.new(StandardError)
2014-09-02 18:07:02 +05:30
2023-01-13 00:05:48 +05:30
PERMITTED_ACTIONS = %w[
mv_repository remove_repository add_namespace rm_namespace mv_namespace
repository_exists?
].freeze
2015-04-26 12:48:37 +05:30
class << self
2020-03-13 15:44:24 +05:30
# Retrieve GitLab Shell secret token
#
# @return [String] secret token
2016-11-03 12:29:30 +05:30
def secret_token
@secret_token ||= begin
File.read(Gitlab.config.gitlab_shell.secret_file).chomp
end
end
2020-03-13 15:44:24 +05:30
# Ensure gitlab shell has a secret token stored in the secret_file
# if that was never generated, generate a new one
2016-11-03 12:29:30 +05:30
def ensure_secret_token!
return if File.exist?(File.join(Gitlab.config.gitlab_shell.path, '.gitlab_shell_secret'))
generate_and_link_secret_token
end
2020-03-13 15:44:24 +05:30
# Returns required GitLab shell version
#
# @return [String] version from the manifest file
2015-04-26 12:48:37 +05:30
def version_required
2017-09-10 17:25:29 +05:30
@version_required ||= File.read(Rails.root
.join('GITLAB_SHELL_VERSION')).strip
2015-04-26 12:48:37 +05:30
end
2016-09-29 09:46:39 +05:30
2020-04-08 14:13:33 +05:30
# Return GitLab shell version
#
# @return [String] version
def version
@version ||= File.read(gitlab_shell_version_file).chomp if File.readable?(gitlab_shell_version_file)
end
2016-11-03 12:29:30 +05:30
private
2020-04-08 14:13:33 +05:30
def gitlab_shell_path
File.expand_path(Gitlab.config.gitlab_shell.path)
end
def gitlab_shell_version_file
File.join(gitlab_shell_path, 'VERSION')
end
2016-11-03 12:29:30 +05:30
# Create (if necessary) and link the secret token file
def generate_and_link_secret_token
secret_file = Gitlab.config.gitlab_shell.secret_file
shell_path = Gitlab.config.gitlab_shell.path
unless File.size?(secret_file)
# Generate a new token of 16 random hexadecimal characters and store it in secret_file.
@secret_token = SecureRandom.hex(16)
File.write(secret_file, @secret_token)
end
link_path = File.join(shell_path, '.gitlab_shell_secret')
if File.exist?(shell_path) && !File.exist?(link_path)
2022-10-11 01:57:18 +05:30
# It could happen that link_path is a broken symbolic link.
# In that case !File.exist?(link_path) is true, but we still want to overwrite the (broken) symbolic link.
FileUtils.ln_sf(secret_file, link_path)
2016-11-03 12:29:30 +05:30
end
end
2015-04-26 12:48:37 +05:30
end
2020-03-13 15:44:24 +05:30
# Move or rename a repository
2014-09-02 18:07:02 +05:30
#
2020-03-13 15:44:24 +05:30
# @example Move/rename a repository
2016-08-24 12:49:21 +05:30
# mv_repository("/path/to/storage", "gitlab/gitlab-ci", "randx/gitlab-ci-new")
2020-03-13 15:44:24 +05:30
#
# @param [String] storage project's storage path
# @param [String] disk_path current project path on disk
# @param [String] new_disk_path new project path on disk
# @return [Boolean] whether repository could be moved/renamed on disk
2020-04-08 14:13:33 +05:30
#
# @deprecated
2020-03-13 15:44:24 +05:30
def mv_repository(storage, disk_path, new_disk_path)
return false if disk_path.empty? || new_disk_path.empty?
2018-03-17 18:26:18 +05:30
2020-03-13 15:44:24 +05:30
Gitlab::Git::Repository.new(storage, "#{disk_path}.git", nil, nil).rename("#{new_disk_path}.git")
2019-12-21 20:55:43 +05:30
true
2021-06-08 01:23:25 +05:30
rescue StandardError => e
2020-03-13 15:44:24 +05:30
Gitlab::ErrorTracking.track_exception(e, path: disk_path, new_path: new_disk_path, storage: storage)
2019-12-21 20:55:43 +05:30
false
2014-09-02 18:07:02 +05:30
end
2018-03-17 18:26:18 +05:30
# Removes a repository from file system, using rm_diretory which is an alias
# for rm_namespace. Given the underlying implementation removes the name
# passed as second argument on the passed storage.
2014-09-02 18:07:02 +05:30
#
2020-03-13 15:44:24 +05:30
# @example Remove a repository
2016-08-24 12:49:21 +05:30
# remove_repository("/path/to/storage", "gitlab/gitlab-ci")
2020-03-13 15:44:24 +05:30
#
# @param [String] storage project's storage path
# @param [String] disk_path current project path on disk
2020-04-08 14:13:33 +05:30
#
# @deprecated
2020-03-13 15:44:24 +05:30
def remove_repository(storage, disk_path)
return false if disk_path.empty?
2018-03-17 18:26:18 +05:30
2020-03-13 15:44:24 +05:30
Gitlab::Git::Repository.new(storage, "#{disk_path}.git", nil, nil).remove
2019-12-21 20:55:43 +05:30
true
2021-06-08 01:23:25 +05:30
rescue StandardError => e
2020-11-24 15:15:51 +05:30
Gitlab::AppLogger.warn("Repository does not exist: #{e} at: #{disk_path}.git")
2020-03-13 15:44:24 +05:30
Gitlab::ErrorTracking.track_exception(e, path: disk_path, storage: storage)
2019-12-21 20:55:43 +05:30
2018-03-17 18:26:18 +05:30
false
2014-09-02 18:07:02 +05:30
end
# Add empty directory for storing repositories
#
2020-03-13 15:44:24 +05:30
# @example Add new namespace directory
2018-10-15 14:42:47 +05:30
# add_namespace("default", "gitlab")
2014-09-02 18:07:02 +05:30
#
2020-03-13 15:44:24 +05:30
# @param [String] storage project's storage path
# @param [String] name namespace name
2020-04-08 14:13:33 +05:30
#
# @deprecated
2016-08-24 12:49:21 +05:30
def add_namespace(storage, name)
2019-07-07 11:18:12 +05:30
Gitlab::GitalyClient.allow_n_plus_1_calls do
Gitlab::GitalyClient::NamespaceService.new(storage).add(name)
end
2018-03-17 18:26:18 +05:30
rescue GRPC::InvalidArgument => e
raise ArgumentError, e.message
2014-09-02 18:07:02 +05:30
end
# Remove directory from repositories storage
# Every repository inside this directory will be removed too
#
2020-03-13 15:44:24 +05:30
# @example Remove namespace directory
2018-10-15 14:42:47 +05:30
# rm_namespace("default", "gitlab")
2014-09-02 18:07:02 +05:30
#
2020-03-13 15:44:24 +05:30
# @param [String] storage project's storage path
# @param [String] name namespace name
2020-04-08 14:13:33 +05:30
#
# @deprecated
2016-08-24 12:49:21 +05:30
def rm_namespace(storage, name)
2018-10-15 14:42:47 +05:30
Gitlab::GitalyClient::NamespaceService.new(storage).remove(name)
2018-03-17 18:26:18 +05:30
rescue GRPC::InvalidArgument => e
raise ArgumentError, e.message
2014-09-02 18:07:02 +05:30
end
2018-03-17 18:26:18 +05:30
alias_method :rm_directory, :rm_namespace
2014-09-02 18:07:02 +05:30
# Move namespace directory inside repositories storage
#
2020-03-13 15:44:24 +05:30
# @example Move/rename a namespace directory
2016-08-24 12:49:21 +05:30
# mv_namespace("/path/to/storage", "gitlab", "gitlabhq")
2014-09-02 18:07:02 +05:30
#
2020-03-13 15:44:24 +05:30
# @param [String] storage project's storage path
# @param [String] old_name current namespace name
# @param [String] new_name new namespace name
2020-04-08 14:13:33 +05:30
#
# @deprecated
2016-08-24 12:49:21 +05:30
def mv_namespace(storage, old_name, new_name)
2018-10-15 14:42:47 +05:30
Gitlab::GitalyClient::NamespaceService.new(storage).rename(old_name, new_name)
2019-02-15 15:39:39 +05:30
rescue GRPC::InvalidArgument => e
2020-01-01 13:55:28 +05:30
Gitlab::ErrorTracking.track_exception(e, old_name: old_name, new_name: new_name, storage: storage)
2019-02-15 15:39:39 +05:30
2018-03-17 18:26:18 +05:30
false
2014-09-02 18:07:02 +05:30
end
2020-03-13 15:44:24 +05:30
# Check if repository exists on disk
#
# @example Check if repository exists
# repository_exists?('default', 'gitlab-org/gitlab.git')
#
# @return [Boolean] whether repository exists or not
# @param [String] storage project's storage path
# @param [Object] dir_name repository dir name
2020-04-08 14:13:33 +05:30
#
# @deprecated
2019-12-21 20:55:43 +05:30
def repository_exists?(storage, dir_name)
Gitlab::Git::Repository.new(storage, dir_name, nil, nil).exists?
rescue GRPC::Internal
false
end
2014-09-02 18:07:02 +05:30
end
end