Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions ceph_devstack/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,33 @@ def parse_args(args: List[str]) -> argparse.Namespace:
help="The container to wait for",
)
subparsers.add_parser("show-conf", help="show the configuration")
parser_log= subparsers.add_parser(
"teuthology-log", help="See the teuthology test log files"
)
parser_log.add_argument(
"--latest",
default=True,
action='store_true',
help="(Default) Get the latest teuthology test log",
)
parser_log.add_argument(
"--dir",
default=False,
help="(Optional) Specify a custom logs archive directory instead of ~/.local/share/ceph-devstack \n FORMAT /your/custom/dir/ceph-devstack/archive",
)
parser_log.add_argument(
"--path-only",
"-p",
default=False,
action='store_true',
help="Print the full path of teuthology.log instead of displaying its contents",
)
parser_log.add_argument(
"--job",
"-j",
default=False,
help="(Optional) Specify a job ID to display logs for a particular job",
)
return parser.parse_args(args)


Expand Down
2 changes: 2 additions & 0 deletions ceph_devstack/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ async def run():
return
elif args.command == "wait":
return await obj.wait(container_name=args.container)
elif args.command == "teuthology-log":
return await obj.teuthology_log(args)
else:
await obj.apply(args.command)
return 0
Expand Down
11 changes: 11 additions & 0 deletions ceph_devstack/resources/ceph/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
LoopControlDeviceWriteable,
SELinuxModule,
)
from ceph_devstack.resources.log import LogCapabilities


class SSHKeyPair(Secret):
Expand Down Expand Up @@ -229,3 +230,13 @@ async def wait(self, container_name: str):
return await container.wait()
logger.error(f"Could not find container {container_name}")
return 1

async def teuthology_log(self,args):

if args.path_only:
LogCapabilities(path=args.dir, job_id=args.job).getPath()
else:
LogCapabilities(job_id=args.job).print_logs()
return 1


75 changes: 75 additions & 0 deletions ceph_devstack/resources/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os
from datetime import datetime
from ceph_devstack import logger

class LogCapabilities:
def __init__(self, path=None,job_id=None):
self.job_id = job_id or None
self.path = path or "~/.local/share/ceph-devstack/archive"

def find_logs_location(self,):
user_path = os.path.expanduser(self.path)
if os.path.exists(user_path):
dirs = [d for d in os.listdir(user_path) if os.path.isdir(os.path.join(user_path, d))]

if dirs:
dirs.sort(key=self._extract_timestamp, reverse=True)
latest_dir = dirs[0]
teuthology_logfiles = []
for root, dirs, files in os.walk(os.path.join(user_path, latest_dir)):
if 'teuthology.log' in files:
if self.job_id is not None:
if os.path.basename(root) == str(self.job_id):
teuthology_logfilePath = os.path.join(root, 'teuthology.log')
teuthology_logfiles.append(teuthology_logfilePath)
else:
continue
else:
teuthology_logfilePath = os.path.join(root, 'teuthology.log')
teuthology_logfiles.append(teuthology_logfilePath)
return teuthology_logfiles
return []
else:
return []

def getPath(self):
teuthology_logfile = self.find_logs_location()
if teuthology_logfile:
for idx, log in enumerate(teuthology_logfile):
logger.info(f"{idx + 1}: {log}")
else:
logger.info("teuthology.log not found in default dir. Try with --log-dir")

def print_logs(self):
teuthology_logfile = self.find_logs_location()
if teuthology_logfile:
for idx, log in enumerate(teuthology_logfile):
logger.info(f"{idx + 1}: {log}")

if len(teuthology_logfile) > 1:
selected_index = int(input("Multiple teuthology.log files found. Please select the log file by number: ")) - 1
if 0 <= selected_index < len(teuthology_logfile):
selected_log = teuthology_logfile[selected_index]
else:
logger.info("Invalid selection.")
return []
else:
selected_log = teuthology_logfile[0]

with open(selected_log, 'r') as file:
log_contents = file.read()
logger.info(log_contents)
else:
logger.info("teuthology.log not found.")



def _extract_timestamp(self, directory_name):
try:
timestamp_str = directory_name.split('-')[1] + '-' + directory_name.split('-')[2] + '-' + directory_name.split('-')[3] + '_' + directory_name.split('-')[4]
timestamp_str = timestamp_str.split('_')[0] + '_' + timestamp_str.split('_')[1].split('-')[0]
return datetime.strptime(timestamp_str, '%Y-%m-%d_%H:%M:%S')
except Exception as e:
return datetime.min