gcx 설정 파일을 v1 형식으로 마이그레이션하기
gcx 설정 파일을 v1 형식으로 마이그레이션하기
gcx는 컨텍스트 간에 자격 증명을 재사용하기 쉽도록 설정 파일 형식을 조정하고 있어요. 이는 gcx 버전 v0.6.0 이상에 적용됩니다. v1 형식은 파일을 세 부분으로 나눕니다: Grafana 연결용 stacks, 여러 컨텍스트가 참조할 수 있는 Grafana Cloud 자격 증명용 cloud, 그리고 둘 다 이름으로 참조하는 contexts입니다.
출처: 문서
본문
마이그레이션은 어떻게 동작하나요?
gcx는 레거시 설정 파일을 로드할 때 처음으로 자동 마이그레이션을 시도합니다. gcx가 이 문서로 연결되는 경고나 오류를 출력한다면, 몇 가지 이유 중 하나로 마이그레이션이 일시 중지되거나 중단된 것이에요. 표시된 메시지를 마이그레이션이 일시 중지되거나 중단된 이유에서 찾아 단계를 따라 하세요.
설정 파일을 수동으로 변환하는 방법은 이 문서 끝의 필드 매핑 표를 참고하세요.
마이그레이션은 어떤 정보도 삭제하지 않아요
마이그레이션 상태가 어떻든 아무것도 유실되지 않습니다:
- 일시 중지되거나 중단된 마이그레이션은 아무것도 변경하지 않습니다: 파일, 백업, 자격 증명 저장소 항목 어느 것도 건드리지 않아요.
gcx는 안전하게 될 수 있는 부분에서는 메모리 내 변환으로 계속 동작합니다. - 완료된 마이그레이션은 변환 결과가 원본과 동일한 의미인지 확인한 뒤에만 파일을 교체하며, 원본을
<file>.legacy.bak으로 옆에 보관합니다.gcx는 그 백업을 절대 덮어쓰거나 삭제하지 않습니다. - OS 자격 증명 저장소(macOS의 Keychain, Windows의 Credential Manager, Linux의 Secret Service)의 자격 증명은 새 항목으로 복사됩니다. 옛 항목은 그대로 남아 있어 백업을 계속 완전히 사용할 수 있어요.
완료된 마이그레이션 되돌리기
완료된 마이그레이션을 되돌리려면 백업을 설정 파일 위에 복사하세요:
cp ~/.config/gcx/config.yaml.legacy.bak ~/.config/gcx/config.yaml
주의: 레거시 파일에 평문 자격 증명이 있었다면, 마이그레이션이 이를 OS 자격 증명 저장소로 옮긴 뒤에도
<file>.legacy.bak에 남아 있습니다. 되돌릴 일이 없다고 확신하면 백업을 직접 제거하세요.
마이그레이션이 일시 중지되거나 중단된 이유
설정 마이그레이션이 중단될 수 있는 이유와 해결 방법입니다:
- "layered configuration migration is incomplete": 설정이 여러 파일(시스템, 사용자, 또는 저장소의
.gcx.yaml)에 걸쳐 흩어져 있어요.gcx는 명령이 계속 동작하도록 메모리에서 변환하지만, 일부 설정 파일만 마이그레이션되고 다른 일부는 안 되는 상태를 피하기 위해 여러 파일을 대신 다시 쓰지는 않습니다. 해결하려면 레이어드 파일 마이그레이션 방법을 따르세요. - "cannot safely auto-migrate layered legacy configuration" 또는 "the overlapping entries require manual consolidation": 두 파일이 같은 항목의 겹치는 부분을 정의하고 있어, v1 병합 규칙이 레거시 규칙과 다르게 결합할 수 있습니다. 해결하려면 겹치는 레이어 통합 방법을 따르세요.
- "running with in-memory config migration … reason: a legacy credential could not be read from the credential store": 자격 증명 저장소가 잠겨 있거나, 잠금 해제 프롬프트가 닫혔거나,
gcx가 저장소 접근이 없는 세션(SSH, CI)에서 실행되었어요. 이 경우 마이그레이션을 영구화하면 다시 저장할 수 없는 자격 증명에 대한 참조가 남을 수 있으므로gcx는 기다립니다. 자격 증명 저장소를 잠금 해제하거나(또는 데스크톱 세션에서 실행) 아무gcx명령을 실행하면 마이그레이션이 스스로 완료됩니다. - "running with in-memory config migration" + 권한 관련 이유: 설정 파일이나 해당 디렉터리가 쓰기 가능하지 않아요. 읽기 전용 설정 명령은 메모리 내 설정으로 계속 동작하지만, 설정이나 자격 증명을 쓰는 모든 것은 파일이 쓰기 가능해지거나 v1 파일로 교체될 때까지 실패합니다. 해결하려면 권한을 고치고 아무
gcx명령을 실행하거나, CI형 환경이라면 설정 파일을 v1 형식으로 업데이트하세요. (필드 매핑 참고) - "existing legacy config backup does not match the current source": 이전 마이그레이션이
.legacy.bak을 남겼는데, 이후 파일이 레거시 형식으로 다시 쓰였어요(예: 더 오래된gcx버전에 의해).gcx는 이전 백업을 덮어쓰지 않습니다. 해결하려면 두 파일을 비교해 신뢰하는 쪽을 유지하고 아무gcx명령을 실행하세요. - "unsupported config version": 파일이 레거시 형식도 아니고
gcx가 인식하지 못해요. 더 현대적인 형식을 지원하도록gcx를 업그레이드하세요(미래를 대비한 것일 뿐이며, 현재는 v1만 있습니다). - "config migration self-check failed":
gcx가 파일을 변환하고 원본과 비교했는데 차이가 발견되어 파일을 그대로 두었습니다. 이는 버그를 의미하므로 오류 텍스트와 함께 보고하고, 그동안은 수동으로 마이그레이션하세요.
레이어드 파일 마이그레이션 방법
마이그레이션 경고는 마이그레이션해야 할 남은 레거시 파일 각각을 나열합니다. 설정 파일을 한 번에 하나씩 마이그레이션하세요 - 각 명령은 해당 파일만 v1 형식으로 다시 쓰고 옆에 .legacy.bak 백업을 남깁니다. 예시:
gcx config set --file user version 1
gcx config set --file local version 1
각 단계 후 gcx는 아직 마이그레이션해야 할 레거시 파일의 명령을 다시 출력하며, 완전한 항목을 부분 항목으로 교체할 수 있는 파일별 변환은 거부합니다. 안전한 명령을 제시할 수 없을 때는 파일을 직접 편집하라고 알려줍니다. 로드하지 않고 파일을 검사하려면 gcx config edit <system|user|local>을 실행하세요.
system 설정 파일을 편집하면 시스템의 모든 사용자에 대한 설정을 편집하게 된다는 점에 유의하세요.
모든 파일이 마이그레이션되면 경고가 사라집니다. 모든 것이 정상인지 확인하려면 결과 검증을 참고하세요.
겹치는 레이어 통합 방법
레거시 gcx는 다른 파일에 있는 같은 이름의 컨텍스트를 필드 단위로 병합했습니다. v1은 그렇지 않습니다: 우선순위가 더 높은 파일의 스택이나 Cloud 항목이 더 낮은 파일의 같은 이름 항목을 완전히 대체해요. 이렇게 함으로써 한 파일이 자신의 서버를 다른 파일의 자격 증명과 섞는 일을 방지합니다. 부분 오버라이드에 의존하던 파일은 한 번 수동으로 통합해야 합니다:
- 오류가 겹치는 항목의 이름을 알려줄 거예요.
gcx config edit <system|user|local>로 각 파일을 여세요. - 오버라이드하는 필드를 완전한 항목을 소유한 파일로 옮기거나, 오버라이드 항목의 이름을 바꿔(예: 저장소별 컨텍스트에 자체 스택 이름 부여) 겹치지 않게 하세요.
- 아무
gcx명령을 실행하세요. 사전 점검이 다시 확인하며, 겹침이 없어지면 레이어드 파일 마이그레이션으로 안내됩니다.
레거시 설정을 버전 1로 매핑하기
파일을 수동으로 변환하려면: 원본을 안전한 곳에 복사하고, 표를 사용해 각 필드를 새 위치로 옮기고, 맨 위에 version: 1을 추가하고, 검증하세요. 옛 필드 위치에서 새 위치로의 매핑입니다:
| 레거시 (컨텍스트별) | 버전 1 |
|---|---|
| contexts. |
stacks. |
| contexts. |
cloud. |
| contexts. |
cloud. |
| contexts. |
cloud. |
| contexts. |
stacks. |
| contexts. |
stacks. |
| contexts. |
stacks. |
| contexts. |
contexts. |
| contexts. |
contexts. |
| contexts. |
contexts. |
| contexts. |
contexts. |
| contexts. |
변경 없음 |
| current-context , diagnostics | 변경 없음 |
cloud 항목은 컨텍스트가 이름으로 참조하므로 원하는 대로 이름을 지을 수 있어요. 여러 컨텍스트에서 cloud 설정을 재사용할 수 있습니다.
레거시 cloud.token이 액세스 정책이 아니라 실험적 OAuth 로그인에서 나온 것이라도 여전히 token으로 마이그레이션됩니다 - 레거시 형식은 둘을 구분할 수 없어요. 다음 gcx cloud login이 해당 항목의 oauth-token 필드에 저장합니다.
레거시 설정 업데이트 예시
레거시 설정:
contexts:
prod:
grafana:
server: https://myorg.grafana.net
token: "<service account token>"
cloud:
token: "<cloud access policy token>"
stack: myorg
default-prometheus-datasource: my-prom
dev:
grafana:
server: https://myorg-dev.grafana.net
token: "<service account token>"
cloud:
token: "<cloud access policy token>" # same token as prod
current-context: prod
이것은 다음과 같이 됩니다:
version: 1
stacks:
prod:
slug: myorg
grafana:
server: https://myorg.grafana.net
token: "<service account token>"
dev:
grafana:
server: https://myorg-dev.grafana.net
token: "<service account token>"
cloud:
grafana-com:
token: "<cloud access policy token>" # shared by both contexts
contexts:
prod:
stack: prod
cloud: grafana-com
datasources:
prometheus: my-prom
dev:
stack: dev
cloud: grafana-com
current-context: prod
자격 증명 참조
레거시 파일에 keychain:gcx:prod:cloud-token 같은 값이 있으면, 이는 OS 자격 증명 저장소의 비밀에 대한 참조예요. 문자열을 직접 복사하지 말고 마이그레이션이 옮기도록 두세요.
gcx는 자신이 선택하고 소유한 파일(예: 표준 사용자 설정 파일 - 심링크된 홈이나 XDG 경로도 포함, 또는 --config나 GCX_CONFIG로 명시적으로 선택한 파일)에서만 레거시 자격 증명 참조를 해석하며, 파일이 사용자만 쓸 수 있을 때만 해석합니다. 참조는 또한 자신이 속한 곳에 있어야 합니다: 안에 명명된 컨텍스트와 필드가 파일 내 위치와 일치해야 해요. 저장소나 시스템 디렉터리에서 발견된 파일은 절대 신뢰되지 않습니다.
저장소 설정에 자격 증명 참조가 있다면, --config로 명시적으로 선택하거나(신뢰할 때만), 마이그레이션 전에 참조를 새 자격 증명으로 교체하세요. 레거시 참조를 버전 1 파일에 복사한다고 해서 비밀에 접근할 수 있게 되지는 않습니다.
버전 1 자격 증명 참조는 설정 파일의 경로, 속한 정확한 스택이나 Cloud 항목·필드, 그리고 자격 증명의 목적지에 연결됩니다. 버전 1 설정을 다른 경로로 복사하면 구조는 복사되지만 자격 증명 접근은 복사되지 않아요 - 참조 문자열을 수동으로 복사하는 대신 복사된 파일에 대해 gcx login이나 gcx cloud login을 실행하세요.
결과 검증
마이그레이션 후 설정이 파싱되고 모든 컨텍스트가 연결되는지 확인하세요:
gcx config view
gcx config check
여기서:
gcx config view는 비밀을 숨긴 채 효과적인 설정을 보여줍니다.gcx config check는 연결을 포함해 모든 컨텍스트를 검증하며, 어느 하나라도 실패하면 0이 아닌 코드로 종료합니다.--context <name>을 전달하면 해당 컨텍스트만 검증합니다.