Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
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
2 changes: 1 addition & 1 deletion 2 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ It is currently under active development and has not yet had a formal release.

☑︎ CentOS 8.Stream mostly works - but has not yet passed a Ceph test

☐ A recent Fedora should work but has not been tested
☑︎ Works for Fedora 41

☒ Ubuntu does not currently ship a new enough podman

Expand Down
27 changes: 27 additions & 0 deletions 27 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 2 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 11 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 75 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


Morty Proxy This is a proxified and sanitized view of the page, visit original site.