Skip to content

Instantly share code, notes, and snippets.

@boileaum
Last active December 9, 2022 09:34
Show Gist options
  • Save boileaum/e28486a4a2f0e0f520fa35a410f96400 to your computer and use it in GitHub Desktop.
Save boileaum/e28486a4a2f0e0f520fa35a410f96400 to your computer and use it in GitHub Desktop.
A script to list currently published GitLab Pages projects
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
A script to list currently published GitLab Pages projects
(to be run by admin on GitLab server)
"""
import os
from pathlib import Path
GITLAB_RB = "/etc/gitlab/gitlab.rb"
# Default Pages path
PAGES_DEFAULT_PATH = "/var/opt/gitlab/gitlab-rails/shared/pages/"
def sizeof_fmt(num, suffix="B") -> str:
for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
if abs(num) < 1024.0:
return f"{num:3.1f}{unit}{suffix}"
num /= 1024.0
return f"{num:.1f}Yi{suffix}"
def get_size(path: Path) -> int:
"""return size of directory in bytes"""
return sum(f.stat().st_size for f in path.glob('**/*') if f.is_file())
found_pages_path = False
pages_path = PAGES_DEFAULT_PATH
with open(GITLAB_RB, 'r') as f:
for line in f:
if line.startswith("pages_external_url"):
# Get pages_url from gitlab.rb
pages_url = line.split()[1].strip()[1:-1]
elif line.startswith("gitlab_rails['pages_path']"):
# Get pages_path from gitlab.rb
pages_path = line.split("=")[1].strip()[1:-1]
found_pages_path = True
print((f"Exploring{' non' if found_pages_path else ' '}"
f"default Pages path: {pages_path}"))
pages_url_suffix = '.' + pages_url.split("://")[1]
# List all directories in pages_path but ./tmp
os.chdir(pages_path)
namespaces = [path for path in Path('.').iterdir()
if path.is_dir() and not path.name.startswith('@')
and path.name != 'tmp']
n_sites = 0
total_size = 0
for namespace in namespaces:
try:
# os.listdir(os.path.join(pages_path, namespace))
project_pathes = namespace.iterdir()
except (IndexError, NotADirectoryError):
continue
if project_pathes:
print(f"{namespace}:")
for project_path in project_pathes:
project_name = project_path.name
if project_name.endswith(pages_url_suffix):
# Project name is an URL
project_url = f"https://{namespace}{pages_url_suffix}"
else:
# Project name is not an URL
project_url = \
f"https://{namespace}{pages_url_suffix}/{project_name}"
project_path = pages_path / namespace / project_name / 'public'
if (project_path / "index.html").exists():
size = get_size(project_path)
print(f"\t{project_url} ({sizeof_fmt(size)})")
n_sites += 1
total_size += size
else:
try:
for d in (p for p in project_path.iterdir() if p.is_dir()):
full_path = project_path / d
size = get_size(full_path)
print(f"\t{project_url}/{d} ({sizeof_fmt(size)})")
n_sites += 1
total_size += size
except FileNotFoundError:
print(f"\t{project_url} --> WARNING: directory is empty")
except NotADirectoryError:
print(f"\t{project_url} --> WARNING: not a directory")
print('---')
print(f"Namespaces: {len(namespaces)}")
print(f"Sites : {n_sites}")
print(f"Total size: {sizeof_fmt(total_size)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment