1. Background
Cinder Volume 이해하기
- Openstack의 Cinder는 Block Storage 서비스로 가상 머신에 영구 스토리지를 추가한다.
- 주요 목적은 VM의 디스크나 추가 데이터 저장용 디스크를 유연하게 제공/관리/이관하는 것이다.
구성 요소
- Cinder api
- Cinder volume
- Cinder scheduler
- Cinder backup
- Messaging queue
Volume?
- Block storage가 제공하는 가장 기본 단위의 저장 공간이다.
- 사용자가 요청한 크기만큼의 디스크 공간을 하나의 volume으로 할당해서 제공한다.
- 한 번 생선되면 특정 VM에 붙였다 뗐다 할 수 있다.
- VM이 삭제 되어도 volume 데이터는 살아있다.
Volume Snapshot 이해하기
- snapshot은 특정 시점의 volume 데이터 전체를 캡처한 복제본이다.
- 주요 목적은 데이터의 백업, 복구, 복제이다.
2. Flow of volume_snapshot.py
기본 흐름은 다음과 같다.
사용자 CLI 입력
↓
osc/cmd/manager → cliff parser → get_parser()
↓
take_action()
↓
self.app.client_manager.sdk_connection.volume
↓
openstacksdk.connection.Connection.volume
↓
openstacksdk.block_storage.v3._proxy.Proxy.<메서드>()
↓
HTTP 요청 (REST API) → Cinder API (Block Storage 서비스)
ex) openstack volume snapshot create
사용자
| openstack volume snapshot create snap1 --volume myvol
v
OSC CLI (cliff.CommandManager)
| - CreateVolumeSnapshot.get_parser()로 인자 파싱
v
CreateVolumeSnapshot.take_action()
| - self.app.client_manager.sdk_connection.volume 호출
v
openstacksdk.connection.Connection.volume
| - v3 Block Storage Proxy 객체 반환
v
Proxy.find_volume(name_or_id='myvol')
| - GET /volumes?name=myvol → Cinder API
v
Proxy.create_snapshot(volume_id=..., ...)
| - POST /snapshots → Cinder API
v
Cinder API (volumev3)
| - 스냅샷 생성 처리
v
응답(Snapshot JSON)
| - Snapshot 객체로 변환 (openstacksdk.snapshot.Snapshot)
v
_format_snapshot()로 가공
v
CLI 출력 (cliff.ShowOne 포맷터)
3. Breakdown volume_snapshot.py
volume snapshot관련 CLI 서브커맨드를 구현했다.- 사용자는
openstack volume snapshot create,delete,list,set,show,unset등의 명령어를 CLI로 입력한다.
Class 구성
Utility Class
VolumeIDColumn: Lister를 출력할 시 volume ID 대신 volume name을 표시한다._format_snapshot: openstackdsk의 snapshot 객체를 CLI 표시용으로 변경하는 작업이 포함되어 있다.ignored하는 내용이 포함되어있다.
Command Class
CreateVolumeSnapshotDeleteVolumeSnapshotListVolumeSnapshotListVolumeSnapshotListVolumeSnapshotUnsetVolumeSnapshot
Utility
1 VolumeIdColumn
- functools.partial을 사용하여 volume_cache를 미리 바인딩해(
FormattableColumn) CLI 출력 시 사용 - CLI 출력 시
volume_id를human_readable로 변환해서 출력 __init__: volume_cache 전달human_readable():
캐시에 해당 ID가 있으면 volume name 반환
없으면 그냥 ID 반환
2 _format_snapshot
- Snapshot 객체를 dict로 변환하되 불필요한/중복 컬럼 제거
- metadata는 DictColumn으로 변환해 CLI에서 깔끔하게 표시
Command
1 CreateVolumeSnapshot
CLI 인자
<snapshot-name> 필수
--volume
--description
--force Create a snapshot attached to an instance.
--property Set up metadata
--remote-source admin용 참조 정보?
동작
volume_id = volume_client.find_volume(volume, ignore_missing=False).id
볼륨 아이디를 조회
volume_id = volume_client.find_volume(volume, ignore_missing=False).id
remote source가 있으면 manage_snapshot 호출
없다면 create_snapshot 호출
결과를 _format_snapshot 후 zip(*sorted(data.items()))로 출력 준비
2 DeleteVolumeSnapshot
CLI 인자
<snapshot>
--force 상태를 무시하고 강제 삭제
--remote block storage에서는 삭제하고, 백엔드에는 남음
동작
remote+force 조합이면 CommandError 즉시 발생
각 snapshot에 대해:
- id 조회
- remote면
unmanage_snapshot호출 - 아니면
delete_snapshot호출 - 실패하면 LOG.error + 실패 카운트 증가
- 실패 건수(result) > 0 이면 전체 실패 수 / 총 수로 CommandError 발생
3 ListVolumeSnapshot
CLI 인자
--all-projects admin
--project Filter results by project, admin
--long List additional fields
--name --status --volume
pagination.add_marker_pagination_option_to_parser(parser) ? 이건 무엇인지 좀 더 찾아봐야 함
동작
volume cache 생성 → 출력 시 volume_id를 name으로 변환 가능
volume_client와 identity_client를 사용해 volume_id와 project_id를 처리
project라는 옵션이 있을 시 all_project를 True로 만듬
snapshot() 호출로 목록을 data에 저장
Lister가 기대하는 heders와 rows 반환 (출력 포맷은 metadata → DictColumn / volume_id → VolumeIdColumn)
4 SetVolumeSnapshot
CLI 인자
<snapshot>
--name --description
--no-property Remove all properties
--property Property to add/change for this snapshot
--state New snapshot state
동작
find_snapshot()으로 찾기
no-property면 delete_snapshot_metadata로 모두 삭제
properties 있으면 set_snapshot_metadata
state 있으면 reset_snapshot_status (DB만 변경한다고 함, state 변경은 실제 상태 무관하고 admin만 사용 권장)
name/description 변경 있으면 update_snapshot
하나라도 실패하면 CommandError
5 ShowVolumeSnapshot
CLI 인자
<snapshot>
--property
동작
find_snapshot()으로 찾기
_format_snapshot으로 가공 후 ShowOne 포맷으로 반환
6 UnsetVolumeSnapshot
CLI 인자
<snapshot>
--property
동작
find_snapshot()으로 찾기
지정 properties 있으면 delete_snapshot_metadata