Rails 콘솔
GitLab v19.5Offering: GitLab Self-Managed
요약
GitLab의 핵심은 Ruby on Rails 프레임워크로 구축된 웹 애플리케이션입니다. Rails 콘솔은 GitLab과 직접 상호 작용합니다. Rails 콘솔은 문제를 해결하고 있거나, GitLab 애플리케이션에 직접 접근해야만 가져올 수 있는 데이터가 필요한 GitLab 시스템 관리자를 위한 것입니다.
GitLab의 핵심은 Ruby on Rails 프레임워크로 구축된 웹 애플리케이션입니다. Rails 콘솔은 명령줄에서 GitLab 인스턴스와 상호 작용하는 방법을 제공하며, Rails에 그대로 내장된 놀라운 도구에 대한 액세스도 부여합니다.
Rails 콘솔은 GitLab과 직접 상호 작용합니다. 많은 경우 프로덕션 데이터를 영구적으로 수정하거나 손상시키거나 파괴하는 것을 막아 주는 안전장치가 없습니다. 아무런 여파 없이 Rails 콘솔을 살펴보려면 테스트 환경에서 진행할 것을 강력히 권장합니다.
Rails 콘솔은 문제를 해결하고 있거나, GitLab 애플리케이션에 직접 접근해야만 가져올 수 있는 데이터가 필요한 GitLab 시스템 관리자를 위한 것입니다. Ruby에 대한 기본 지식이 필요합니다(간단한 입문으로는 30분 분량의 이 튜토리얼을 참고합니다). Rails 경험은 유용하지만 필수는 아닙니다.
Rails 콘솔 세션 시작#
Rails 콘솔 세션을 시작하는 절차는 GitLab 설치 유형에 따라 다릅니다.
sudo gitlab-rails console
docker exec -it <container-id> gitlab-rails console
sudo -u git -H bundle exec rails console -e production
namespace=<namespace>
kubectl exec -it --namespace "$namespace" -c toolbox "$(kubectl get pods --namespace "$namespace" -lapp=toolbox -o jsonpath='{.items[0].metadata.name}')" -- gitlab-rails console
콘솔을 종료하려면 quit를 입력합니다.
자동 완성 비활성화#
Ruby 자동 완성은 터미널을 느리게 만들 수 있습니다. 다음과 같이 설정합니다.
- 자동 완성을 비활성화하려면
Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE] = false를 실행합니다. - 자동 완성을 다시 활성화하려면
Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE] = true를 실행합니다.
Active Record 로깅 활성화#
Rails 콘솔 세션에서 Active Record 디버그 로깅 출력을 활성화하려면 다음을 실행합니다.
ActiveRecord::Base.logger = Logger.new($stdout)
기본적으로 앞의 스크립트는 표준 출력에 로그를 기록합니다. $stdout을 원하는 파일 경로로
바꾸면 출력을 리디렉션할 로그 파일을 지정할 수 있습니다. 예를 들어 다음 코드는 모든 내용을
/tmp/output.log에 기록합니다.
ActiveRecord::Base.logger = Logger.new('/tmp/output.log')
이렇게 하면 콘솔에서 실행하는 Ruby 코드가 유발한 데이터베이스 쿼리 정보가 표시됩니다. 로깅을 다시 끄려면 다음을 실행합니다.
ActiveRecord::Base.logger = nil
속성#
pretty print(pp)로 형식을 지정하여 사용 가능한 속성을 확인합니다.
예를 들어 어떤 속성에 사용자 이름과 이메일 주소가 들어 있는지 확인합니다.
u = User.find_by_username('someuser')
pp u.attributes
출력 일부는 다음과 같습니다.
{"id"=>1234,
"email"=>"someuser@example.com",
"sign_in_count"=>99,
"name"=>"S User",
"username"=>"someuser",
"first_name"=>nil,
"last_name"=>nil,
"bot_type"=>nil}
그런 다음 이 속성을 활용합니다. 예를 들어 SMTP를 테스트합니다.
e = u.email
n = u.name
Notify.test_email(e, "Test email for #{n}", 'Test email').deliver_now
#
Notify.test_email(u.email, "Test email for #{u.name}", 'Test email').deliver_now
데이터베이스 명령문 타임아웃 비활성화#
현재 Rails 콘솔 세션에 대해 PostgreSQL 명령문 타임아웃을 비활성화할 수 있습니다.
GitLab은 기본적으로 데이터베이스 연결 두 개를 사용합니다. 데이터베이스 명령문 타임아웃을 비활성화하려면 다음을 실행합니다.
ActiveRecord::Base.connection.execute('SET statement_timeout TO 0')
Ci::ApplicationRecord.connection.execute('SET statement_timeout TO 0')
단일 데이터베이스 연결을 사용하도록 재구성한 인스턴스는 다음을 실행하여 데이터베이스 명령문 타임아웃을 비활성화합니다.
ActiveRecord::Base.connection.execute('SET statement_timeout TO 0')
데이터베이스 명령문 타임아웃 비활성화는 현재 Rails 콘솔 세션에만 적용되며, GitLab 프로덕션 환경이나 다음 Rails 콘솔 세션에는 유지되지 않습니다.
Rails 콘솔 세션 히스토리 출력#
명령 히스토리를 표시하려면 rails 콘솔에 다음 명령을 입력합니다.
puts Reline::HISTORY.to_a
그런 다음 클립보드에 복사하여 나중에 참고할 수 있도록 저장할 수 있습니다.
Rails Runner 사용#
GitLab 프로덕션 환경의 컨텍스트에서 Ruby 코드를 실행해야 한다면
Rails Runner를 사용할 수 있습니다.
스크립트 파일을 실행할 때는 git 사용자가 그 스크립트에 접근할 수 있어야 합니다.
명령이나 스크립트가 완료되면 Rails Runner 프로세스도 종료됩니다. 예를 들어 다른 스크립트나 cron job에서 실행할 때 유용합니다.
-
Linux 패키지 설치에서는 다음과 같이 실행합니다.
sudo gitlab-rails runner "RAILS_COMMAND" # Example with a two-line Ruby script sudo gitlab-rails runner "user = User.first; puts user.username" # Example with a ruby script file (make sure to use the full path) sudo gitlab-rails runner /path/to/script.rb -
자체 컴파일 설치에서는 다음과 같이 실행합니다.
sudo -u git -H bundle exec rails runner -e production "RAILS_COMMAND" # Example with a two-line Ruby script sudo -u git -H bundle exec rails runner -e production "user = User.first; puts user.username" # Example with a ruby script file (make sure to use the full path) sudo -u git -H bundle exec rails runner -e production /path/to/script.rb
Rails Runner는 콘솔과 같은 출력을 내지 않습니다.
콘솔에서 변수를 설정하면 콘솔은 변수의 내용이나 참조된 엔터티의 속성처럼 유용한 디버그 출력을 생성합니다.
irb(main):001:0> user = User.first
=> #
Rails Runner는 그렇게 하지 않으므로, 출력을 생성하도록 명시적으로 지정해야 합니다.
$ sudo gitlab-rails runner "user = User.first"
$ sudo gitlab-rails runner "user = User.first; puts user.username ; puts user.id"
root
1
Ruby에 대한 기본 지식이 매우 유용합니다. 간단한 입문으로는 30분 분량의 이 튜토리얼을 참고합니다. Rails 경험은 도움이 되지만 필수는 아닙니다.
객체의 특정 메서드 찾기#
Array.methods.select { |m| m.to_s.include? "sing" }
Array.methods.grep(/sing/)
메서드 소스 찾기#
instance_of_object.method(:foo).source_location
# Example for when we would call project.private?
project.method(:private?).source_location
출력 제한#
명령문 끝에 세미콜론(;)과 후속 명령문을 추가하면 기본 암시적 반환 출력이 표시되지 않습니다. 이미 세부 정보를 명시적으로 출력하고 있고 반환 출력이 많을 수 있는 경우에 사용할 수 있습니다.
puts ActiveRecord::Base.descendants; :ok
Project.select(&:pages_deployed?).each {|p| puts p.path }; true
마지막 작업의 결과 가져오기 또는 저장#
밑줄(_)은 이전 명령문의 암시적 반환값을 나타냅니다. 이를 사용하면 이전 명령의 출력으로 변수를 빠르게 할당할 수 있습니다.
Project.last
# => #>
project = _
# => #>
project.id
# => 2537
작업 시간 측정#
하나 이상의 작업 시간을 측정하려면 다음 형식을 사용하고, 자리 표시자 <operation>을
원하는 Ruby 또는 Rails 명령으로 바꿉니다.
# A single operation
Benchmark.measure { <operation> }
# A breakdown of multiple operations
Benchmark.bm do |x|
x.report(:label1) { <operation_1> }
x.report(:label2) { <operation_2> }
end
자세한 내용은 벤치마크에 대한 개발자 문서를 참고합니다.
Active Record 객체#
데이터베이스에 저장된 객체 조회#
내부적으로 Rails는 객체 관계 매핑 시스템인 Active Record를
사용하여 애플리케이션 객체를 PostgreSQL 데이터베이스에 읽고 쓰고 매핑합니다.
이 매핑은 Active Record 모델이 처리하며, 이 모델은 Rails 앱에 정의된 Ruby 클래스입니다.
GitLab에서 모델 클래스는
/opt/gitlab/embedded/service/gitlab-rails/app/models에 있습니다.
내부적으로 실행되는 데이터베이스 쿼리를 볼 수 있도록 Active Record의 디버그 로깅을 활성화합니다.
ActiveRecord::Base.logger = Logger.new($stdout)
이제 데이터베이스에서 사용자를 조회해 봅니다.
user = User.find(1)
다음이 반환됩니다.
D, [2020-03-05T16:46:25.571238 #910] DEBUG -- : User Load (1.8ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
=> #
데이터베이스의 users 테이블에서 id 칼럼 값이 1인 행을 쿼리했고, Active Record가
그 데이터베이스 레코드를 상호 작용할 수 있는 Ruby 객체로 변환했음을 알 수
있습니다. 다음을 실행해 봅니다.
user.usernameuser.created_atuser.admin
관례상 칼럼 이름은 Ruby 객체 속성으로 그대로 변환되므로,
user.<column_name>으로 해당 속성 값을 확인할 수 있습니다.
마찬가지로 관례상 Active Record 클래스 이름(단수형, 카멜 케이스)은 테이블 이름(복수형,
스네이크 케이스)에 그대로 매핑되며 그 반대도 같습니다. 예를 들어
users 테이블은 User 클래스에 매핑되고, application_settings
테이블은 ApplicationSetting 클래스에 매핑됩니다.
테이블과 칼럼 이름 목록은 Rails 데이터베이스 스키마에서 확인할 수 있으며,
이 스키마는 /opt/gitlab/embedded/service/gitlab-rails/db/schema.rb에 있습니다.
속성 이름으로 데이터베이스에서 객체를 조회할 수도 있습니다.
user = User.find_by(username: 'root')
다음이 반환됩니다.
D, [2020-03-05T17:03:24.696493 #910] DEBUG -- : User Load (2.1ms) SELECT "users".* FROM "users" WHERE "users"."username" = 'root' LIMIT 1
=> #
다음을 실행해 봅니다.
User.find_by(username: 'root')User.where.not(admin: true)User.where('created_at < ?', 7.days.ago)
마지막 두 명령은 여러 User 객체를 담고 있는 것으로 보이는 ActiveRecord::Relation
객체를 반환했습니다.
지금까지는 객체 하나만 반환하도록 설계된 .find나 .find_by를 사용했습니다
(생성된 SQL 쿼리의 LIMIT 1을 확인합니다).
.where는 객체 컬렉션을 가져오려 할 때 사용합니다.
관리자가 아닌 사용자 컬렉션을 가져와 무엇을 할 수 있는지 살펴봅니다.
users = User.where.not(admin: true)
다음이 반환됩니다.
D, [2020-03-05T17:11:16.845387 #910] DEBUG -- : User Load (2.8ms) SELECT "users".* FROM "users" WHERE "users"."admin" != TRUE LIMIT 11
=> #, #, #, #, #]>
이제 다음을 실행해 봅니다.
users.countusers.order(created_at: :desc)users.where(username: 'support-bot')
마지막 명령에서는 .where 문을 연결하여 더 복잡한 쿼리를 생성할 수 있음을 알 수
있습니다. 또한 반환된 컬렉션에 객체가 하나만 들어 있더라도 그 객체와 직접 상호
작용할 수는 없다는 점에 유의합니다.
users.where(username: 'support-bot').username
다음이 반환됩니다.
Traceback (most recent call last):
1: from (irb):37
D, [2020-03-05T17:18:25.637607 #910] DEBUG -- : User Load (1.6ms) SELECT "users".* FROM "users" WHERE "users"."admin" != TRUE AND "users"."username" = 'support-bot' LIMIT 11
NoMethodError (undefined method `username' for #]>)
Did you mean? by_username
.first 메서드로 컬렉션의 첫 번째 항목을 가져와 컬렉션에서 객체 하나를
조회합니다.
users.where(username: 'support-bot').first.username
이제 원하던 결과를 얻습니다.
D, [2020-03-05T17:18:30.406047 #910] DEBUG -- : User Load (2.6ms) SELECT "users".* FROM "users" WHERE "users"."admin" != TRUE AND "users"."username" = 'support-bot' ORDER BY "users"."id" ASC LIMIT 1
=> "support-bot"
Active Record로 데이터베이스에서 데이터를 조회하는 여러 방법에 대한 자세한 내용은 Active Record Query Interface 문서를 참고합니다.
Active Record 모델을 사용하여 데이터베이스 쿼리#
m = Model.where('attribute like ?', 'ex%')
# for example to query the projects
projects = Project.where('path like ?', 'Oumua%')
Active Record 객체 수정#
앞 절에서는 Active Record로 데이터베이스 레코드를 조회하는 방법을 살펴봤습니다. 이제 데이터베이스에 변경 사항을 기록하는 방법을 살펴봅니다.
먼저 root 사용자를 조회합니다.
user = User.find_by(username: 'root')
다음으로 사용자의 비밀번호를 업데이트해 봅니다.
user.password = 'password'
user.save
다음이 반환됩니다.
Enqueued ActionMailer::MailDeliveryJob (Job ID: 05915c4e-c849-4e14-80bb-696d5ae22065) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", #>
=> true
여기서 .save 명령이 true를 반환한 것을 볼 수 있으며, 이는 비밀번호 변경이
데이터베이스에 성공적으로 저장되었음을 의미합니다.
또한 저장 작업이 다른 동작을 유발한 것도 볼 수 있습니다. 이 경우에는 이메일 알림을 보내는 백그라운드 job입니다. 이는 Active Record 콜백의 예로, Active Record 객체 수명 주기의 이벤트에 반응하여 실행되도록 지정된 코드입니다. 데이터를 직접 변경해야 할 때 Rails 콘솔을 사용하는 편이 나은 이유도 이 때문입니다. 데이터베이스 쿼리를 직접 실행해 변경하면 이러한 콜백이 실행되지 않기 때문입니다.
한 줄로 속성을 업데이트할 수도 있습니다.
user.update(password: 'password')
또는 여러 속성을 한 번에 업데이트합니다.
user.update(password: 'password', email: 'hunter2@example.com')
이제 다른 것을 시도해 봅니다.
# Retrieve the object again so we get its latest state
user = User.find_by(username: 'root')
user.password = 'password'
user.password_confirmation = 'hunter2'
user.save
이 명령은 false를 반환하며, 변경 사항이 데이터베이스에 저장되지 않았음을
의미합니다. 이유는 짐작할 수 있겠지만 확실히 확인해 봅니다.
user.save!
다음이 반환됩니다.
Traceback (most recent call last):
1: from (irb):64
ActiveRecord::RecordInvalid (Validation failed: Password confirmation doesn't match Password)
Active Record 검증에 걸렸습니다. 검증은 원하지 않는 데이터가 데이터베이스에 저장되지 않도록 애플리케이션 수준에 적용한 비즈니스 로직이며, 대부분의 경우 문제가 된 입력을 어떻게 고칠지 알려 주는 유용한 메시지를 함께 제공합니다.
.update에도 bang(Ruby에서 !를 가리키는 말)을 붙일 수 있습니다.
user.update!(password: 'password', password_confirmation: 'hunter2')
Ruby에서 !로 끝나는 메서드 이름은 흔히 "bang 메서드"라고 부릅니다. 관례상
bang은 변환된 결과를 반환하고 원본 객체는 그대로 두는 대신, 메서드가 대상 객체를
직접 수정한다는 것을 나타냅니다. 데이터베이스에 쓰기를 수행하는 Active Record
메서드에서 bang 메서드는 기능을 하나 더 수행합니다. 오류가 발생할 때마다
false만 반환하는 대신 명시적으로 예외를
발생시킵니다.
검증을 완전히 건너뛸 수도 있습니다.
# Retrieve the object again so we get its latest state
user = User.find_by(username: 'root')
user.password = 'password'
user.password_confirmation = 'hunter2'
user.save!(validate: false)
검증은 보통 사용자가 제공한 데이터의 무결성과 일관성을 보장하기 위해 마련된 것이므로 이 방법은 권장하지 않습니다.
검증 오류가 발생하면 객체 전체가 데이터베이스에 저장되지 않습니다. 아래 절에서 이에 대한 예를 일부 확인할 수 있습니다. 폼을 제출할 때 GitLab UI에 원인을 알 수 없는 빨간 배너가 표시된다면, 이 방법이 문제의 근본 원인에 가장 빠르게 다가가는 방법인 경우가 많습니다.
Active Record 객체와 상호 작용#
결국 Active Record 객체도 표준 Ruby 객체일 뿐입니다. 따라서 임의의 동작을 수행하는 메서드를 객체에 정의할 수 있습니다.
예를 들어 GitLab 개발자들은 2단계 인증에 도움이 되는 메서드를 몇 가지 추가했습니다.
def disable_two_factor!
transaction do
update(
otp_required_for_login: false,
encrypted_otp_secret: nil,
encrypted_otp_secret_iv: nil,
encrypted_otp_secret_salt: nil,
otp_grace_period_started_at: nil,
otp_backup_codes: nil
)
self.second_factor_webauthn_registrations.destroy_all # rubocop: disable DestroyAll
end
end
def two_factor_enabled?
two_factor_otp_enabled? || two_factor_webauthn_enabled?
end
(/opt/gitlab/embedded/service/gitlab-rails/app/models/user.rb를 참고합니다.)
그런 다음 어떤 사용자 객체에서든 이 메서드를 사용할 수 있습니다.
user = User.find_by(username: 'root')
user.two_factor_enabled?
user.disable_two_factor!
일부 메서드는 GitLab이 사용하는 gem, 즉 Ruby 소프트웨어 패키지가 정의합니다. 예를 들어 GitLab이 사용자 상태를 관리하는 데 사용하는 StateMachines gem이 그렇습니다.
state_machine :state, initial: :active do
event :block do
...
event :activate do
...
end
다음을 실행해 봅니다.
user = User.find_by(username: 'root')
user.state
user.block
user.state
user.activate
user.state
앞에서 검증 오류가 발생하면 객체 전체가 데이터베이스에 저장되지 않는다고 설명했습니다. 이것이 어떻게 예상치 못한 상호 작용을 일으킬 수 있는지 살펴봅니다.
user.password = 'password'
user.password_confirmation = 'hunter2'
user.block
false가 반환됩니다. 앞에서와 같이 bang을 붙여 무슨 일이 일어났는지
확인합니다.
user.block!
다음이 반환됩니다.
Traceback (most recent call last):
1: from (irb):87
StateMachines::InvalidTransition (Cannot transition state via :block from :active (Reason(s): Password confirmation doesn't match Password))
완전히 별개로 보이는 속성에서 발생한 검증 오류가, 사용자를 어떤 방식으로든 업데이트하려 할 때 다시 발목을 잡는다는 것을 알 수 있습니다.
실제로 GitLab 관리 설정에서 이런 일이 가끔 발생합니다. GitLab 업데이트에서 검증이 추가되거나 변경되면서, 이전에 저장된 설정이 이제 검증에 실패하는 경우입니다. UI에서는 설정의 일부만 한 번에 업데이트할 수 있으므로, 이 경우 정상 상태로 되돌리는 유일한 방법은 Rails 콘솔을 통한 직접 조작입니다.
일반적으로 사용되는 Active Record 모델과 객체 조회 방법#
기본 이메일 주소 또는 사용자 이름으로 사용자 가져오기:
User.find_by(email: 'admin@example.com')
User.find_by(username: 'root')
기본 또는 보조 이메일 주소로 사용자 가져오기:
User.find_by_any_email('user@example.com')
find_by_any_email 메서드는 Rails가 제공하는 기본 메서드가 아니라 GitLab 개발자가
추가한 사용자 지정 메서드입니다.
관리자 사용자 컬렉션 가져오기:
User.admins
admins는 내부적으로 where(admin: true)를 수행하는
스코프 편의 메서드입니다.
경로로 프로젝트 가져오기:
Project.find_by_full_path('group/subgroup/project')
find_by_full_path는 Rails가 제공하는 기본 메서드가 아니라 GitLab 개발자가 추가한
사용자 지정 메서드입니다.
숫자 ID로 프로젝트의 이슈 또는 머지 리퀘스트 가져오기:
project = Project.find_by_full_path('group/subgroup/project')
project.issues.find_by(iid: 42)
project.merge_requests.find_by(iid: 42)
iid는 "internal ID"를 뜻하며, 이슈와 머지 리퀘스트 ID를 GitLab 프로젝트별로
구분해 유지하는 방식입니다.
경로로 그룹 가져오기:
Group.find_by_full_path('group/subgroup')
그룹의 관련 그룹 가져오기:
group = Group.find_by_full_path('group/subgroup')
# Get a group's parent group
group.parent
# Get a group's child groups
group.children
그룹의 프로젝트 가져오기:
group = Group.find_by_full_path('group/subgroup')
# Get group's immediate child projects
group.projects
# Get group's child projects, including those in subgroups
group.all_projects
CI 파이프라인 또는 빌드 가져오기:
Ci::Pipeline.find(4151)
Ci::Build.find(66124)
파이프라인과 job의 ID 번호는 GitLab 인스턴스 전체에서 전역적으로 증가하므로, 이슈나 머지 리퀘스트와 달리 이를 조회할 때 내부 ID 속성을 사용할 필요가 없습니다.
현재 애플리케이션 설정 객체 가져오기:
ApplicationSetting.current
irb에서 객체 열기#
데이터를 변경하는 명령은 올바르게 실행하지 않거나 적절한 조건에서 실행하지 않으면 손상을 일으킬 수 있습니다. 항상 테스트 환경에서 명령을 먼저 실행하고, 복원할 수 있는 백업 인스턴스를 준비해 둡니다.
객체의 컨텍스트 안에 있으면 메서드를 살펴보기가 더 쉬울 때가 있습니다. Object의 네임스페이스에 심을 넣으면 어떤 객체의 컨텍스트에서든 irb를 열 수 있습니다.
Object.define_method(:irb) { binding.irb }
project = Project.last
# => #>
project.irb
# Notice new context
irb(#)> web_url
# => "https://gitlab-example/root/discard"
문제 해결#
Rails Runner syntax error#
gitlab-rails 명령은 기본적으로 root가 아닌 계정과 그룹(git:git)으로 Rails Runner를 실행합니다.
root가 아닌 계정이 gitlab-rails runner에 전달된 Ruby 스크립트 파일 이름을 찾지 못하면,
파일에 접근할 수 없다는 오류가 아니라 구문 오류가 발생할 수 있습니다.
이런 일이 생기는 흔한 이유는 스크립트를 root 계정의 홈 디렉터리에 두었기 때문입니다.
runner는 경로와 파일 매개변수를 Ruby 코드로 파싱하려고 시도합니다.
예를 들면 다음과 같습니다.
[root ~]# echo 'puts "hello world"' > ./helloworld.rb
[root ~]# sudo gitlab-rails runner ./helloworld.rb
Please specify a valid ruby command or the path of a script to run.
Run 'rails runner -h' for help.
/opt/gitlab/..../runner_command.rb:45: syntax error, unexpected '.'
./helloworld.rb
^
[root ~]# sudo gitlab-rails runner /root/helloworld.rb
Please specify a valid ruby command or the path of a script to run.
Run 'rails runner -h' for help.
/opt/gitlab/..../runner_command.rb:45: unknown regexp options - hllwrld
[root ~]# mv ~/helloworld.rb /tmp
[root ~]# sudo gitlab-rails runner /tmp/helloworld.rb
hello world
디렉터리에는 접근할 수 있지만 파일에 접근할 수 없으면 의미 있는 오류가 생성됩니다.
[root ~]# chmod 400 /tmp/helloworld.rb
[root ~]# sudo gitlab-rails runner /tmp/helloworld.rb
Traceback (most recent call last):
[traceback removed]
/opt/gitlab/..../runner_command.rb:42:in `load': cannot load such file -- /tmp/helloworld.rb (LoadError)
다음과 비슷한 오류가 발생하는 경우입니다.
[root ~]# sudo gitlab-rails runner helloworld.rb
Please specify a valid ruby command or the path of a script to run.
Run 'rails runner -h' for help.
undefined local variable or method `helloworld' for main:Object
파일을 /tmp 디렉터리로 옮기거나, git 사용자가 소유한 새 디렉터리를 만들어 아래 예시처럼 그 디렉터리에 스크립트를 저장할 수 있습니다.
sudo mkdir /scripts
sudo mv /script_path/helloworld.rb /scripts
sudo chown -R git:git /scripts
sudo chmod 700 /scripts
sudo gitlab-rails runner /scripts/helloworld.rb
필터링된 콘솔 출력#
변수, 로그, 시크릿 같은 특정 값이 유출되지 않도록 콘솔의 일부 출력은 기본적으로
필터링될 수 있습니다. 이러한 출력은 [FILTERED]로 표시됩니다. 예를 들면 다음과 같습니다.
> Plan.default.actual_limits
=> ci_instance_level_variables: "[FILTERED]",
이 필터링을 우회하려면 객체에서 값을 직접 읽습니다. 예를 들면 다음과 같습니다.
> Plan.default.limits.ci_instance_level_variables
=> 25