cmlutils 는 프로젝트의 collaborator(공동 작업자와 권한)를 옮기지 않는다. 클러스터 간 마이그레이션에서 collaborator 를 보존하려면 소스에서 API v2 로 목록을 JSON 으로 뽑아 두었다가, 타깃에 프로젝트가 생긴 뒤 같은 API 로 다시 넣는다. 벤더가 제공한 export_project_collaborators.sh / import_project_collaborators.sh 는 lib/cml_api.sh 를 source 하는데 그 파일이 없으면 동작하지 않으므로, curl + jq 만으로 독립 스크립트를 만들어 썼다.
BASE='https://<workspace-url>'
export CML_API_KEY=${API_V2_KEY} # User Settings > API Keys
# 프로젝트 id / owner / name
curl -s -H "Authorization: Bearer ${CML_API_KEY}" \
"${BASE}/api/v2/projects?page_size=1000" \
| jq -r '.projects[] | [.id, .owner.username, .name] | @tsv'
# next_page_token 이 있으면 &page_token=<토큰> 으로 다음 페이지 조회
# 특정 프로젝트의 collaborator
PID='<project-id>'
curl -s -H "Authorization: Bearer ${CML_API_KEY}" \
"${BASE}/api/v2/projects/${PID}/collaborators" \
| jq '[.collaborators[] | {username: .user.username, permission}]'
collaborators 엔드포인트는 CML 버전에 따라 없을 수 있다. https://<workspace-url>/api/v2/swagger.html 에서 먼저 확인한다.
--list 로 전체 프로젝트를 project_info.txt 에 탭 구분(id, owner, name)으로 기록하되 모든 줄을 # 주석으로 낸다. 사용자는 옮길 프로젝트 줄의 # 만 지운다. --names project_info.txt --output collaborators.json 으로 주석이 아닌 줄만 추출한다. 매칭 기준은 id 컬럼이라 한글 프로젝트명이나 공백이 있어도 안전하다. 결과 파일은 permission 정보를 담으므로 600 권한으로 저장한다.--input collaborators.json --list 로 내용을 확인하고, --project-id <id> 또는 --project '<이름>' 으로 지정한 프로젝트만 등록한다. 미지정 시 전체. PUT 만 하고 삭제는 하지 않으므로 기존 collaborator 가 있어도 안전하며 멱등이다. --dry-run 을 지원한다.CML_API_KEY 환경변수로만 받고 curl 에는 config 파일 디스크립터로 전달해 ps 에 노출되지 않게 한다.manifest 구조는 다음과 같다.
{
"schema_version": 1,
"source_url": "https://...",
"exported_at": "2026-07-20T...Z",
"projects": [
{"source_project_id": "...", "name": "ProjectA", "owner_username": "user1",
"collaborators": [{"username": "user2", "permission": "read"}]}
]
}
타깃에 프로젝트가 먼저 있어야 하므로 cmlutils import → collaborator import 순으로 진행한다. 프로젝트 매칭은 이름 + owner username 이다. cmlutils import-config.ini 의 프로젝트별 username 이 곧 타깃 owner 가 되므로, 소스와 같은 owner 로 올려야 collaborator 스크립트가 별도 매핑 없이 매칭된다. 전부 admin 으로 올리면 owner 가 달라져 매칭이 깨진다. 대상 사용자 계정은 타깃에 미리 존재해야 한다(LDAP/SSO 동기화 또는 최초 로그인). 최신 cmlutils 에는 타깃에서 프로젝트 소유권을 이전하는 기능도 있다.
--list → 한두 개만 주석 해제 → export → import --dry-run 순으로 가볍게 검증한다.