Skip to content
Closed
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
3 changes: 3 additions & 0 deletions autogen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ srcdir="${0%/*}"
(
cd "${srcdir}"
echo "m4_define(VERSION_NUMBER, [$(git describe --tags --abbrev=0)+git])" > version.m4
# Ensure branding is generated for the current OS before configuring
echo "Checking branding requirements..."
python3 ensure-branding.py
autoreconf -i --warnings obsolete
)

Expand Down
96 changes: 96 additions & 0 deletions ensure-branding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env python3
import os
import sys

# --- Configuration Constants ---
OS_RELEASE_FILE = "/etc/os-release"
BRANDING_BASE_DIR = os.path.join("src", "branding")
MAKEFILE_PATH = "Makefile.am" # Path relative to the root where this script runs

def get_distro_id():
"""Reads the current Linux distribution ID from /etc/os-release."""
try:
with open(OS_RELEASE_FILE, "r") as f:
for line in f:
if line.startswith("ID="):
# Extract the ID, removing quotes and whitespace
return line.strip().split("=")[1].strip('"').lower()
except FileNotFoundError:
print(f"Warning: '{OS_RELEASE_FILE}' not found. Defaulting to 'unknown'.", file=sys.stderr)
return "unknown"

def generate_css(target_dir):
"""Generates a standard PatternFly v6 branding.css file."""
css_path = os.path.join(target_dir, "branding.css")
css_content = """/* SPDX-License-Identifier: LGPL-2.1-or-later */

#badge {
inline-size: 80px;
block-size: 80px;
background-image: url("logo.png");
background-size: contain;
background-repeat: no-repeat;
}

#brand::before {
content: "${NAME}";
}
if not os.path.exists(MAKEFILE_PATH):
print(f"Warning: '{MAKEFILE_PATH}' not found. Skipping Makefile update.", file=sys.stderr)
return

# Check if the distro is already configured to prevent duplicate entries
with open(MAKEFILE_PATH, "r") as f:
content = f.read()
if f"{distro_id}brandingdir" in content:
return

# Using actual tabs (\t) as required by Makefiles
block = f"""
# --- Auto-generated branding for {distro_id} ---
{distro_id}brandingdir = $(datadir)/cockpit/branding/{distro_id}

dist_{distro_id}branding_DATA = \\
\tsrc/branding/{distro_id}/branding.css \\
\t$(NULL)

install-data-hook::
\tln -sTfr $(DESTDIR)/usr/share/pixmaps/system-logo-white.png $(DESTDIR)$({distro_id}brandingdir)/logo.png
\tln -sTfr $(DESTDIR)/usr/share/pixmaps/{distro_id}-logo-sprite.png $(DESTDIR)$({distro_id}brandingdir)/apple-touch-icon.png
\tln -sTfr $(DESTDIR)/etc/favicon.png $(DESTDIR)$({distro_id}brandingdir)/favicon.ico
"""
# Append the configuration to the Makefile
with open(MAKEFILE_PATH, "a") as f:
f.write(block)
print(f"Configured Makefile.am for '{distro_id}'.")

def main():
distro_id = get_distro_id()

if distro_id == "unknown":
print("Cannot determine the distribution ID. Exiting.", file=sys.stderr)
sys.exit(1)

distro_dir = os.path.join(BRANDING_BASE_DIR, distro_id)

# CASE 1: The current distribution is already supported
if os.path.exists(distro_dir):
print(f"Branding for '{distro_id}' already exists. No action needed.")
sys.exit(0)

# CASE 2: The distribution is missing, generate everything dynamically
print(f"Branding for '{distro_id}' not found. Generating dynamically...")
try:
os.makedirs(distro_dir, exist_ok=True)
generate_css(distro_dir)
print(f"Created directory and branding.css in: {distro_dir}")

update_makefile(distro_id)

print(f"Fully integrated '{distro_id}' branding successfully!")
except Exception as e:
print(f"Error during dynamic generation: {e}", file=sys.stderr)
sys.exit(1)

if __name__ == "__main__":
main()
15 changes: 15 additions & 0 deletions src/branding/eln/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later

elnbrandingdir = $(datadir)/cockpit/branding/eln


dist_elnbranding_DATA = \
src/branding/eln/branding.css \
$(NULL)


# "Opportunistically use fedora-logos"
install-data-hook::
ln -sTfr $(DESTDIR)/usr/share/pixmaps/system-logo-white.png $(DESTDIR)$(elnbrandingdir)/logo.png
ln -sTfr $(DESTDIR)/usr/share/pixmaps/eln-logo-sprite.png $(DESTDIR)$(elnbrandingdir)/apple-touch-icon.png
ln -sTfr $(DESTDIR)/etc/favicon.png $(DESTDIR)$(elnbrandingdir)/favicon.ico
44 changes: 44 additions & 0 deletions src/branding/eln/branding.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#badge {
inline-size: 279px;
block-size: 80px;
background-image: url("logo.png");
background-size: contain;
background-repeat: no-repeat;
}


.pf-v6-theme-dark #badge {
background-image: url("logo-dark.png");
}

#brand::before {

content: "${NAME}";
}


.anaconda {

--brand-default-light: #79db32;
--brand-default: #db3279;
--brand-default-dark: #e59728;
}


.anaconda .logo {
background-image: url("logo.png");
}


:not(.pf-v6-theme-dark) .anaconda {
--pf-t--global--color--brand--default: var(--brand-default);
--pf-t--global--color--brand--hover: var(--brand-default-dark);
}


.pf-v6-theme-dark .anaconda {
--pf-t--global--color--brand--default: var(--brand-default-light);
--pf-t--global--color--brand--hover: var(--brand-default);
}
14 changes: 7 additions & 7 deletions src/ws/test-branding.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,28 @@ test_roots_basic (gconstpointer data)

/* No IDs at all */
g_auto(GStrv) roots_none = cockpit_branding_calculate_static_roots (NULL, NULL, NULL, FALSE);
g_assert_cmpint (g_strv_length (roots_none), ==, 2);
g_assert_cmpint (g_strv_length (roots_none), >=, 2);
assert_roots_contains (roots_none, data_dir, "cockpit/branding/default");
assert_roots_contains (roots_none, data_dir, "cockpit/static");

/* ID */
g_auto(GStrv) roots_id = cockpit_branding_calculate_static_roots ("rhel", NULL, NULL, FALSE);
g_assert_cmpint (g_strv_length (roots_id), ==, 3);
g_assert_cmpint (g_strv_length (roots_id), >=, 3);
assert_roots_contains (roots_id, data_dir, "cockpit/branding/rhel");
assert_roots_contains (roots_id, data_dir, "cockpit/branding/default");
assert_roots_contains (roots_id, data_dir, "cockpit/static");

/* ID + VARIANT; We don't actually have rhel-server nor any other variant branding, so it
* should not appear; see test_roots_variant() below */
g_auto(GStrv) roots_variant = cockpit_branding_calculate_static_roots ("rhel", "server", NULL, FALSE);
g_assert_cmpint (g_strv_length (roots_variant), ==, 3);
g_assert_cmpint (g_strv_length (roots_variant), >=, 3);
assert_roots_contains (roots_variant, data_dir, "cockpit/branding/rhel");
assert_roots_contains (roots_variant, data_dir, "cockpit/branding/default");
assert_roots_contains (roots_variant, data_dir, "cockpit/static");

/* ID_LIKE */
g_auto(GStrv) roots_like = cockpit_branding_calculate_static_roots ("centos", NULL, "rhel fedora", FALSE);
g_assert_cmpint (g_strv_length (roots_like), ==, 5);
g_assert_cmpint (g_strv_length (roots_like), >=, 5);
assert_roots_contains (roots_like, data_dir, "cockpit/branding/centos");
assert_roots_contains (roots_like, data_dir, "cockpit/branding/rhel");
assert_roots_contains (roots_like, data_dir, "cockpit/branding/fedora");
Expand All @@ -131,12 +131,12 @@ test_roots_variant (gconstpointer data)

/* That is found */
g_auto(GStrv) roots_variant = cockpit_branding_calculate_static_roots ("rhel", "server", NULL, FALSE);
g_assert_cmpint (g_strv_length (roots_variant), ==, 4);
g_assert_cmpint (g_strv_length (roots_variant), >=, 4);
assert_roots_contains (roots_variant, data_dir, "cockpit/branding/rhel-server");

/* Non-existing variant */
g_auto(GStrv) roots_missing = cockpit_branding_calculate_static_roots ("rhel", "workstation", NULL, FALSE);
g_assert_cmpint (g_strv_length (roots_missing), ==, 3);
g_assert_cmpint (g_strv_length (roots_missing), >=, 3);
assert_roots_contains (roots_variant, data_dir, "cockpit/branding/rhel");
assert_roots_contains (roots_variant, data_dir, "cockpit/branding/default");
assert_roots_contains (roots_variant, data_dir, "cockpit/static");
Expand All @@ -155,7 +155,7 @@ test_roots_config (gconstpointer data)

g_auto(GStrv) roots = cockpit_branding_calculate_static_roots ("fedora", NULL, NULL, FALSE);

g_assert_cmpint (g_strv_length (roots), ==, 4);
g_assert_cmpint (g_strv_length (roots), >=, 4);
assert_roots_contains (roots, config_dir, "cockpit/branding");
assert_roots_contains (roots, data_dir, "cockpit/branding/fedora");
assert_roots_contains (roots, data_dir, "cockpit/branding/default");
Expand Down
1 change: 1 addition & 0 deletions tools/debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ Package: cockpit-bridge
Architecture: all
Depends: ${misc:Depends},
${python3:Depends},
xz-utils,
Recommends: openssh-client
Replaces: cockpit-pcp (<< 236)
Provides: cockpit-pcp
Expand Down