4주차 과제 - 김윤수 (1)

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

  • CreateVolumeSnapshot
  • DeleteVolumeSnapshot
  • ListVolumeSnapshot
  • ListVolumeSnapshot
  • ListVolumeSnapshot
  • UnsetVolumeSnapshot

Utility

1 VolumeIdColumn

  • functools.partial을 사용하여 volume_cache를 미리 바인딩해(FormattableColumn) CLI 출력 시 사용
  • CLI 출력 시 volume_idhuman_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_snapshotzip(*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_clientidentity_client를 사용해 volume_idproject_id를 처리
project라는 옵션이 있을 시 all_projectTrue로 만듬
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