Skip to content

Commit

Permalink
util: enhance tracevol.py script to work with volumesnapshots
Browse files Browse the repository at this point in the history
This patch adds the functionality to map the k8s volumesnapshots
to the cephfs/rbd snapshots.

This patch also adds a wrapper around oc/kubectl called `kube_client`
which will help get rid of code duplication.

Closes: ceph#3344

Signed-off-by: Niraj Yadav <[email protected]>
  • Loading branch information
black-dragon74 committed Jan 6, 2025
1 parent 18a62ec commit a82f7ab
Showing 1 changed file with 84 additions and 0 deletions.
84 changes: 84 additions & 0 deletions troubleshooting/tools/tracevol.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import re
import prettytable
PARSER = argparse.ArgumentParser()
ARGS=None # just so that the linter is happy, ARGS is global already.

# -p pvc-test -k /home/.kube/config -n default -rn rook-ceph
PARSER.add_argument("-p", "--pvcname", default="", help="PVC name")
Expand Down Expand Up @@ -562,6 +563,88 @@ def get_fsname_from_pvdata(arg, pvdata):
sys.exit()
return fsname

def kube_client(*commands):
"""
Executes a kubectl/oc command with the provided arguments and returns the JSON output.
Note: Do not pass `-o json` as an argument, this helper adds it automatically.
Example:
kube_client("get", "pvcs")
Args:
*commands: Additional command-line arguments to pass to the Kubernetes or OpenShift command.
"""
arg = ARGS
cmd = [arg.command]
if arg.kubeconfig != "":
cmd += ["--kubeconfig", arg.kubeconfig]
cmd += ["--namespace", arg.namespace]
cmd += filter(lambda x: x not in ('-o', 'json'), commands)
cmd += ["-o", "json"]

with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as out:
stdout, stderr = out.communicate()

if stderr is not None:
if arg.debug:
print(f"failed to execute command {commands} due to {stderr}")
sys.exit()
try:
data = json.loads(stdout)
except ValueError as err:
print(err, stdout)
sys.exit()

return data

def parse_volume_snapshots(volsnapshots):
"""
Parses a list of volume snapshots and prints a table with their details.
"""
cephfs_snap_tbl = prettytable.PrettyTable()
cephfs_snap_tbl.title = "CephFS Volume Snapshots"
cephfs_snap_tbl.field_names = ["Name", "PVC", "Subvolume Name", "Snapshot ID"]

rbd_snap_tbl = prettytable.PrettyTable()
rbd_snap_tbl.title = "RBD Volume Snapshots"
rbd_snap_tbl.field_names = ["Name", "PVC", "Image Name", "Snapshot ID"]

for snapshot in volsnapshots['items']:
snap_name = snapshot['metadata']['name']
pvc_name = snapshot['spec']['source']['persistentVolumeClaimName']

# Fetch the PVC and its PV, useful later
pvc = kube_client("get", "pvc", pvc_name)
pv_data = kube_client("get", "pv", pvc['spec']['volumeName'])

# Find the type of the PVC (RBD or CephFS)
fs_type = "CephFS" if "fsName" in pv_data['spec']['csi']['volumeAttributes'] else "RBD"

# Get the vol name inside ceph
prefix = get_volname_prefix(ARGS, pv_data)
img_id = prefix + get_image_uuid(pv_data['spec']['csi']['volumeHandle'])

# Get the snapshot ID, we can inspect volumesnapshotcontent to get the snapshot handle
# Alternatively, we can use the toolbox pod to fetch these values from ceph directly
snap_content_name = snapshot['status']['boundVolumeSnapshotContentName']
snap_content = kube_client("get", "volumesnapshotcontent", snap_content_name)
snap_id = "csi-snap-" + get_image_uuid(snap_content['status']['snapshotHandle'])

if fs_type == "CephFS":
cephfs_snap_tbl.add_row([snap_name, pvc_name, img_id, snap_id])
else:
rbd_snap_tbl.add_row([snap_name, pvc_name, img_id, snap_id])

print(rbd_snap_tbl)
print(cephfs_snap_tbl)

def list_volume_snapshots():
"""
Retrieve and parse the list of volume snapshots from the cluster.
"""
volumesnapshots = kube_client("get", "volumesnapshots")
parse_volume_snapshots(volumesnapshots)

if __name__ == "__main__":
ARGS = PARSER.parse_args()
if ARGS.command not in ["kubectl", "oc"]:
Expand All @@ -571,3 +654,4 @@ def get_fsname_from_pvdata(arg, pvdata):
print("python version less than 3 is not supported.")
sys.exit(1)
list_pvc_vol_name_mapping(ARGS)
list_volume_snapshots()

0 comments on commit a82f7ab

Please sign in to comment.