Select Git revision
-
Jason R Laura authoredJason R Laura authored
tape_client.py 5.16 KiB
#!/usr/bin/env python
import json
import os
import paramiko
import scp
import sys
import uuid
from tape_task import TapeTask
class TapeClient(object):
EEADM = "/opt/ibm/ltfsee/bin/eeadm"
# Constructor
def __init__(self, host, port, user, keyFile):
self.host = host
self.port = port
self.user = user
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.key = paramiko.RSAKey.from_private_key_file(keyFile)
self.client.load_system_host_keys()
self.scp = None
self.taskList = []
def connect(self):
"""Connects to the tape library frontend."""
self.client.connect(hostname = self.host,
port = self.port,
username = self.user,
pkey = self.key)
def getTaskList(self):
"""Returns the whole task list."""
stdin, stdout, stderr = self.client.exec_command(f"{self.EEADM} task list --json")
exitCode = stdout.channel.recv_exit_status()
if not exitCode:
result = json.loads(stdout.readlines()[0].rstrip('\n'))
#print(result)
#print(len(result["payload"]))
#print(result["payload"][0])
for t in result["payload"]:
task = TapeTask()
task.inUseTapes = t["inuse_tapes"]
task.inUsePools = t["inuse_pools"]
task.inUseNodeGroups = t["inuse_node_groups"]
task.inUseDrives = t["inuse_drives"]
task.cmdParam = t["cmd_param"]
task.result = t["result"]
task.status = t["status"]
task.completedTime = t["completed_time"]
task.startedTime = t["started_time"]
task.createdTime = t["created_time"]
task.setInUseLibs = t["inuse_libs"]
task.type = t["type"]
task.taskId = t["task_id"]
task.id = t["id"]
self.taskList.append(task)
return self.taskList
else:
sys.exit("cmd_exit_code = FAILURE")
def copy(self, srcPath, destPath):
"""Copies files/dirs recursively by passing their absolute paths."""
self.scp = scp.SCPClient(self.client.get_transport())
print(f"Copying {srcPath} in {destPath}")
if os.path.isdir(srcPath):
self.scp.put(srcPath, recursive = True, remote_path = destPath)
elif os.path.isfile(srcPath):
self.scp.put(srcPath, destPath)
else:
sys.exit("FATAL: invalid file/dir.")
self.scp.close()
def migrate(self, fileList):
"""
Migrates to tape all files whose absolute path is
contained in 'fileList'.
"""
tmp = str(uuid.uuid1().hex) + "-vos_migrate.tmp"
fp = open(tmp, "a")
for f in fileList:
fp.write(f"{f}\n")
fp.close()
self.copy(f"./{tmp}", f"/tmp/{tmp}")
os.remove(f"./{tmp}")
cmd = f"{self.EEADM} migrate /tmp/{tmp} -p pl_generic_rw_01"
stdin, stdout, stderr = self.client.exec_command(cmd)
def recall(self, fileList):
"""
Recalls from tape all files whose absolute path is
contained in 'fileList'.
"""
tmp = str(uuid.uuid1().hex) + "-vos_recall.tmp"
fp = open(tmp, "a")
for f in fileList:
fp.write(f"{f}\n")
fp.close()
self.copy(f"./{tmp}", f"/tmp/{tmp}")
os.remove(f"./{tmp}")
cmd = f"{self.EEADM} recall /tmp/{tmp}"
stdin, stdout, stderr = self.client.exec_command(cmd)
def recallChecksumFiles(self, dirName):
"""
Recursively recalls from tape all the checksum files related to
the 'dirName' directory.
"""
cmd = f"find $(dirname {dirName}) -type f \( -iname \"*-md5sum.txt\" \) | {self.EEADM}"
stdin, stdout, stderr = self.client.exec_command(cmd)
exitCode = stdout.channel.recv_exit_status()
out = open("tape_client_log.txt", "a")
out.write(f"exitCode: {exitCode}\n")
out.close()
if exitCode:
return False
else:
return True
def disconnect(self):
"""Closes the connection."""
self.client.close()
def getSize(self, fsMountPoint):
cmd = f"df {fsMountPoint} | tail -n +2"
#out = subprocess.run(cmd, shell = True, capture_output = True)
stdin, stdout, stderr = self.client.exec_command(cmd)
#res = stdout.stdout.decode('UTF-8').rstrip('\n')
res = stdout.readlines()[0]
res = ' '.join(res.split()).split(' ')
#print(res)
total = res[1]
used = res[2]
available = res[3]
return ( total, used, available)
# Test
#tc = TapeClient("192.168.56.101", 22, "root", "ibm")
#tc.connect()
#tc.copy("/home/curban/store/mydir", "/home/mydir")
#tc.copy("/home/curban/store/foo2.txt", "/home/mydir/foo2.txt")
#tl = tc.getTaskList()
#fsSize = tc.getSize("/ia2_tape_stb_01")
#print(fsSize)
#tc.disconnect()
#for i in tl:
# print(i.id)
# print('\n')