Skip to content

Conversation

@avishayt
Copy link
Contributor

@avishayt avishayt commented May 11, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a kiosk demo environment with region-specific web content for US East and US West, including interactive product displays and animated, responsive UI.
    • Added automated kiosk user creation and autologin setup for seamless GNOME-based kiosk sessions.
    • Enabled region-based content delivery using a lightweight HTTP server within containerized environments.
    • Provided scripts and configuration for automated browser launch in kiosk mode and dynamic content updates.
    • Deployed a Kubernetes fleet resource to orchestrate kiosk deployments with automated content and configuration management.

@coderabbitai
Copy link

coderabbitai bot commented May 11, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This change introduces a complete kiosk demo environment, including container images, systemd services, user and autologin setup, GNOME kiosk scripting, Kubernetes fleet deployment, and region-specific web content. It establishes automated deployment and configuration for kiosk devices running a graphical interface and serving dynamic content via a lightweight HTTP server.

Changes

File(s) Change Summary
demos/kiosk/bootc/Containerfile
demos/kiosk/bootc/configure-kiosk-autologin.sh
demos/kiosk/bootc/kiosk-autologin-setup.service
Introduces a new BootC-based container image for the kiosk, installing system components (cloud-init, open-vm-tools, podman-compose with CRB repo enabled), GNOME Shell, Firefox, GNOME kiosk packages, and creating a kiosk user. Adds a shell script and systemd service for configuring GDM autologin for the kiosk user, ensuring the setup runs only once at boot. Also disables the bootc auto-update timer and sets graphical target as default. Adds a flightctl config file.
demos/kiosk/content/content-useast/index.html
demos/kiosk/content/content-uswest/index.html
Adds HTML scaffolds for the US East and US West kiosk content pages, each with a header, main content area, and references to shared CSS and JS for dynamic content rendering.
demos/kiosk/content/content-useast/products.json
demos/kiosk/content/content-uswest/products.json
Adds region-specific JSON files listing products for display in the kiosk UI, each with name, description, price (as a tagline), and image fields.
demos/kiosk/content/content-useast/script.js
demos/kiosk/content/content-uswest/script.js
Adds JavaScript files for each region's kiosk content, dynamically loading the corresponding products.json and rendering product cards into the page.
demos/kiosk/content/content-useast/styles.css
demos/kiosk/content/content-uswest/styles.css
Adds CSS stylesheets for the kiosk content pages, providing a dark theme, responsive grid, card styling, branding, and subtle animations.
demos/kiosk/deployment/fleet.yaml Adds a Kubernetes Fleet resource defining the deployment of kiosk devices: specifies OS image, podman-compose application running a Python HTTP server, region-specific content mounting, GNOME kiosk scripting, and a hook for restarting GDM on content/config changes.
demos/kiosk/kiosk-script/gnome-kiosk-script Adds a GNOME kiosk session script that launches Firefox in kiosk mode with a configurable URL, restarts itself after browser exit, and logs activity for debugging.
demos/kiosk/webserver/Containerfile
demos/kiosk/webserver/podman-compose.yaml
Adds a minimal container image and compose file for running a Python HTTP server, serving static content from a mounted directory at port 8080, suitable for use in the kiosk deployment.
centos-bootc/bootc/Containerfile.amd64 Modifies the CentOS BootC container image build to install dnf-plugins-core and enable the crb repository before installing podman-compose. Removes the previous linting step and adds a static flightctl config file to /etc/flightctl/config.yaml.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Kiosk Device
    participant GNOME Display Manager (GDM)
    participant Systemd
    participant HTTP Server (Podman Compose)
    participant Fleet Controller

    Note over Kiosk Device: Boot process starts
    Systemd->>Kiosk Device: Initialize system, enable graphical target
    Systemd->>kiosk-autologin-setup.service: Run on first boot (oneshot)
    kiosk-autologin-setup.service->>configure-kiosk-autologin.sh: Execute script
    configure-kiosk-autologin.sh->>GDM: Configure autologin for 'kiosk' user
    Systemd->>GDM: Start GDM with autologin enabled
    GDM->>User: Log in 'kiosk' user automatically
    GDM->>gnome-kiosk-script: Start kiosk session
    gnome-kiosk-script->>HTTP Server: Launch Firefox in kiosk mode with configured URL
    HTTP Server->>User: Serve region-specific content (HTML/CSS/JS)
    Fleet Controller->>Kiosk Device: Deploy content/scripts/config via gitRef and inline configs
    Fleet Controller->>Systemd: Trigger GDM restart if content/config changes detected
Loading

Possibly related PRs

  • flightctl/flightctl-demos#73: Adds installation and enabling of cloud-init and open-vm-tools in a BootC container image, directly modifying the same Containerfile for system component setup as in this PR.

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a13ee81 and 7625bc8.

⛔ Files ignored due to path filters (8)
  • demos/kiosk/content/content-useast/images/cities.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/logo.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/telecom.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/transportation.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/healthcare.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/industrial.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/logo.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/retail.png is excluded by !**/*.png
📒 Files selected for processing (16)
  • centos-bootc/bootc/Containerfile.amd64 (1 hunks)
  • demos/kiosk/bootc/Containerfile (1 hunks)
  • demos/kiosk/bootc/configure-kiosk-autologin.sh (1 hunks)
  • demos/kiosk/bootc/kiosk-autologin-setup.service (1 hunks)
  • demos/kiosk/content/content-useast/index.html (1 hunks)
  • demos/kiosk/content/content-useast/products.json (1 hunks)
  • demos/kiosk/content/content-useast/script.js (1 hunks)
  • demos/kiosk/content/content-useast/styles.css (1 hunks)
  • demos/kiosk/content/content-uswest/index.html (1 hunks)
  • demos/kiosk/content/content-uswest/products.json (1 hunks)
  • demos/kiosk/content/content-uswest/script.js (1 hunks)
  • demos/kiosk/content/content-uswest/styles.css (1 hunks)
  • demos/kiosk/deployment/fleet.yaml (1 hunks)
  • demos/kiosk/kiosk-script/gnome-kiosk-script (1 hunks)
  • demos/kiosk/webserver/Containerfile (1 hunks)
  • demos/kiosk/webserver/podman-compose.yaml (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🔭 Outside diff range comments (1)
demos/kiosk/bootc/configure-kiosk-autologin.sh (1)

1-21: 💡 Verification agent

🧩 Analysis chain

Validate the path to the systemd service file.

The pipeline failure suggests there might be a mismatch in the directory structure. Ensure the referenced service file exists in the right location.


🏁 Script executed:

#!/bin/bash
# Check if the directory structure matches the pipeline expectations
echo "Repository structure in demos/kiosk:"
find demos/kiosk -type f -name "*.service" | sort

echo -e "\nChecking if bootc directory exists at the root level:"
if [ -d "kiosk/bootc" ]; then
  echo "Directory kiosk/bootc exists at the root level"
else
  echo "Directory kiosk/bootc does not exist at the root level - this matches the pipeline error"
fi

Length of output: 517


Ensure systemd service path matches repository layout

The pipeline is looking for kiosk/bootc/kiosk-autologin-setup.service at the repo root, but the file actually lives at demos/kiosk/bootc/kiosk-autologin-setup.service. Adjust one of the following:

  • Update your installation or packaging scripts (e.g. in your Makefile/installer/config) to reference
    demos/kiosk/bootc/kiosk-autologin-setup.service
  • Or move the service file to kiosk/bootc/kiosk-autologin-setup.service so it matches the expected path
🧰 Tools
🪛 GitHub Actions: Build changed OS images (bootc)

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

♻️ Duplicate comments (1)
demos/kiosk/content/content-uswest/styles.css (1)

33-33: Fix invalid CSS property prefix (duplicate).
As in the US East stylesheet, change #animation to animation so the keyframes are applied correctly:

-  #animation: spin3d 20s linear infinite;
+  animation: spin3d 20s linear infinite;
🧰 Tools
🪛 Biome (1.9.4)

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)

🧹 Nitpick comments (13)
demos/kiosk/webserver/Containerfile (1)

1-5: Containerfile is minimalistic but could use improvements.

The Containerfile uses the scratch base image, which is extremely minimal and doesn't include any utilities. For a compose file, this is a valid approach since the actual runtime environment will be determined by the podman-compose.yaml.

Add a maintainer label to the Containerfile for better documentation:

FROM scratch

COPY podman-compose.yaml /podman-compose.yaml

LABEL appType="compose"
+ LABEL maintainer="Your Name <your.email@example.com>"
demos/kiosk/bootc/kiosk-autologin-setup.service (1)

7-9: Consider adding security settings to the systemd service.

While the service definition is correct, it lacks security-related settings that are recommended for production systemd services.

Add standard security settings to harden the service:

[Service]
Type=oneshot
ExecStart=/usr/local/bin/configure-kiosk-autologin.sh
RemainAfterExit=true
+ # Security settings
+ PrivateTmp=true
+ ProtectSystem=strict
+ ProtectHome=true
+ NoNewPrivileges=true

These settings restrict what the service can access, preventing potential security issues if the script is compromised.

demos/kiosk/content/content-useast/products.json (2)

1-20: JSON structure looks good and content is appropriate for a kiosk demo.

The JSON file contains a well-formed array of product entries representing different industry verticals. Each product has a name, description, price (used as a tagline), and image path.

I suggest adding a "key" or "id" field to each product for better programmatic handling.

[
  {
+   "id": "transportation",
    "name": "Transportation & Logistics",
    "description": "Track, analyze, and adapt in motion. From real-time route optimization to vehicle-based edge AI, RHEM ensures your fleet stays in sync.",
    "price": "No delays, no detours",
    "image": "images/transportation.png"
  },

22-22: Remove trailing empty line

There's an unnecessary empty line at the end of the file.

  }
]
-
demos/kiosk/webserver/podman-compose.yaml (1)

1-10: Simple HTTP server setup looks good

The Podman Compose file configures a simple Python HTTP server that serves content from a mounted volume. This is appropriate for a demo kiosk setup.

For a production environment, consider security improvements:

  1. Use a non-root user in the container
  2. Add resource limits
  3. Consider a more robust webserver like nginx

Example resource limits addition:

    volumes:
      - /var/kiosk/catalog:/app:ro,z
    ports:
      - "8080:8080"
+   deploy:
+     resources:
+       limits:
+         cpus: '0.5'
+         memory: 256M
demos/kiosk/content/content-uswest/products.json (2)

1-21: Consider renaming the "price" field to better reflect its content.

The "price" field in each product entry is actually being used to store taglines or marketing phrases rather than actual price values. This could be confusing for developers working with this data.

A more descriptive field name like "tagline" would better represent the actual content:

  {
    "name": "Industrial / Manufacturing",
    "description": "Run your factory floor with confidence. Whether you're deploying predictive maintenance systems or real-time analytics, RHEM gives your edge infrastructure the resilience and speed to keep production humming.",
-   "price": "Runs like clockwork",
+   "tagline": "Runs like clockwork",
    "image": "images/industrial.png"
  },

1-1: Remove unnecessary blank line at the beginning of the file.

There's an empty line at the beginning of the JSON file that isn't needed.

-
[
demos/kiosk/content/content-uswest/index.html (1)

1-19: Consider using templates to reduce duplication.

The US East and US West index.html files are nearly identical, with only the title being different. Consider using a templating system to reduce duplication and make maintenance easier.

A simple approach would be to use a template file with a placeholder for the region, which gets replaced during the build process or at runtime.

demos/kiosk/bootc/configure-kiosk-autologin.sh (1)

15-17: Add comments explaining the session configuration.

The script configures a custom session gnome-kiosk-script but doesn't explain what this session does. Add comments to explain the purpose and behavior of this session type.

# Add user session info
mkdir -p /var/lib/AccountsService/users
cat <<EOF > /var/lib/AccountsService/users/kiosk
[User]
+# Use the gnome-kiosk-script session which launches Firefox in kiosk mode
Session=gnome-kiosk-script
SystemAccount=false
EOF
demos/kiosk/bootc/Containerfile (1)

34-34: Consider security implications of passwordless user.

Creating a user without a password (passwd -d kiosk) may be appropriate for a kiosk demo, but could be a security risk if these devices are accessible or connected to sensitive networks.

Consider adding a comment explaining the security considerations:

# Create kiosk user
-RUN useradd -m kiosk && passwd -d kiosk
+# Create passwordless kiosk user - acceptable for demo purposes only
+# In production environments, consider using more secure authentication methods
+RUN useradd -m kiosk && passwd -d kiosk
demos/kiosk/content/content-useast/styles.css (1)

2-18: Extract shared base styles into a common CSS.
The body rules and @keyframes spin3d are duplicated across your region-specific stylesheets. Consider moving these into a shared base.css (e.g., under demos/kiosk/content/shared/) and importing it in each directory. This reduces duplication and eases future updates.

demos/kiosk/content/content-uswest/styles.css (1)

2-18: Extract shared base styles into a common CSS (duplicate suggestion).
This file shares the same base styles (body rules, keyframes) with the US East variant. Extract them to a shared base.css to eliminate redundancy and streamline maintenance.

demos/kiosk/deployment/fleet.yaml (1)

23-29: Consider a more robust static webserver.
Python’s built-in HTTP server is fine for a demo but lacks caching, headers, and performance tuning. You could switch to an nginx:alpine image for better static‐file serving:

services:
  kiosk:
    image: nginx:alpine
    volumes:
      - /var/kiosk/catalog:/usr/share/nginx/html:ro,z
    ports:
      - "8080:80"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c881bbb and 78deb06.

⛔ Files ignored due to path filters (8)
  • demos/kiosk/content/content-useast/images/cities.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/logo.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/telecom.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/transportation.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/healthcare.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/industrial.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/logo.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/retail.png is excluded by !**/*.png
📒 Files selected for processing (16)
  • demos/kiosk/README.md (1 hunks)
  • demos/kiosk/bootc/Containerfile (1 hunks)
  • demos/kiosk/bootc/configure-kiosk-autologin.sh (1 hunks)
  • demos/kiosk/bootc/kiosk-autologin-setup.service (1 hunks)
  • demos/kiosk/content/content-useast/index.html (1 hunks)
  • demos/kiosk/content/content-useast/products.json (1 hunks)
  • demos/kiosk/content/content-useast/script.js (1 hunks)
  • demos/kiosk/content/content-useast/styles.css (1 hunks)
  • demos/kiosk/content/content-uswest/index.html (1 hunks)
  • demos/kiosk/content/content-uswest/products.json (1 hunks)
  • demos/kiosk/content/content-uswest/script.js (1 hunks)
  • demos/kiosk/content/content-uswest/styles.css (1 hunks)
  • demos/kiosk/deployment/fleet.yaml (1 hunks)
  • demos/kiosk/kiosk-script/gnome-kiosk-script (1 hunks)
  • demos/kiosk/webserver/Containerfile (1 hunks)
  • demos/kiosk/webserver/podman-compose.yaml (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Build changed OS images (bootc)
demos/kiosk/bootc/kiosk-autologin-setup.service

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

demos/kiosk/bootc/configure-kiosk-autologin.sh

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

demos/kiosk/bootc/Containerfile

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

🪛 Biome (1.9.4)
demos/kiosk/content/content-useast/styles.css

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)


[error] 36-37: expected , but instead found .

Remove .

(parse)


[error] 109-109: expected } but instead the file ends

the file ends here

(parse)


[error] 27-27: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

demos/kiosk/content/content-uswest/styles.css

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)


[error] 36-37: expected , but instead found .

Remove .

(parse)


[error] 109-109: expected } but instead the file ends

the file ends here

(parse)


[error] 27-27: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

🔇 Additional comments (5)
demos/kiosk/bootc/kiosk-autologin-setup.service (1)

1-12: Well-structured systemd service but pipeline failure detected.

The systemd service is properly configured with oneshot type, appropriate ordering constraints, and condition to prevent repeated execution.

The pipeline failure indicates that the directory structure doesn't match what's expected. The error message states:

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

This suggests that either:

  1. The directory should be created at kiosk/bootc instead of demos/kiosk/bootc
  2. The CI pipeline is looking in the wrong location

Please verify the correct path and update either the file location or the CI configuration.

🧰 Tools
🪛 GitHub Actions: Build changed OS images (bootc)

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

demos/kiosk/kiosk-script/gnome-kiosk-script (2)

1-4: Script redirects output correctly and handles failures

The script properly redirects output to a log file and sets up exit on failure with set -e.


14-14: Sleep period may be unnecessary

The 5-second sleep doesn't have a documented purpose.

Is this delay necessary? If it's waiting for display initialization or network, please add a comment explaining its purpose:

+# Wait for X server to be fully initialized
sleep 5
demos/kiosk/content/content-useast/index.html (1)

1-19:

Details

✅ Verification successful

Verify CSS and JavaScript files exist.

The HTML references external CSS and JavaScript files. Ensure these files exist in the content directory.


🏁 Script executed:

#!/bin/bash
# Check if the referenced CSS and JS files exist
cd demos/kiosk/content
echo "Checking for CSS and JS files referenced in index.html:"
for region in content-useast content-uswest; do
  echo "Region: $region"
  for file in styles.css script.js; do
    if [ -f "$region/$file" ]; then
      echo "$region/$file exists"
    else
      echo "$region/$file is missing"
    fi
  done
done

Length of output: 953


CSS and JavaScript files verified
The referenced styles.css and script.js files are present in both content-useast and content-uswest directories. No further action required.

demos/kiosk/bootc/Containerfile (1)

37-38:

Details

✅ Verification successful

Ensure the kiosk-autologin-setup.service file exists.

The Containerfile copies a service file, but its existence isn't verified by the provided code. Make sure this file exists in the repository.


🏁 Script executed:

#!/bin/bash
# Check for the existence of the service file
if [ -f "demos/kiosk/bootc/kiosk-autologin-setup.service" ]; then
  echo "Service file exists: demos/kiosk/bootc/kiosk-autologin-setup.service"
  echo "Content:"
  cat "demos/kiosk/bootc/kiosk-autologin-setup.service"
else
  echo "Missing service file: demos/kiosk/bootc/kiosk-autologin-setup.service"
fi

Length of output: 557


✅ kiosk-autologin-setup.service file is present

The service file demos/kiosk/bootc/kiosk-autologin-setup.service exists and contains the expected unit definition for kiosk autologin. No further action is required here.

Comment on lines +1 to +25
document.addEventListener('DOMContentLoaded', () => {
fetch('products.json')
.then(response => response.json())
.then(products => {
const grid = document.getElementById('product-grid');
products.forEach((product, index) => {
const card = document.createElement('div');
card.className = 'card';
card.style.animationDelay = `${index * 0.2}s`;

card.innerHTML = `
<img src="${product.image}" alt="${product.name}" />
<div class="card-content">
<h2>${product.name}</h2>
<p>${product.description}</p>
<p>${product.price}</p>
</div>
`;
grid.appendChild(card);
});
})
.catch(error => {
console.error('Error loading products:', error);
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Web content script looks functional but has security vulnerabilities.

The script dynamically renders product cards from JSON data, but there are several security and best practice concerns:

  1. No sanitization of the product data before inserting into innerHTML
  2. No error handling for missing product properties
  3. No loading state to indicate when products are being fetched

The script is vulnerable to XSS attacks because it directly injects data from products.json into innerHTML without sanitization. If an attacker can modify the JSON source, they could inject malicious scripts that would execute in the browser context.

- card.innerHTML = `
-   <img src="${product.image}" alt="${product.name}" />
-   <div class="card-content">
-     <h2>${product.name}</h2>
-     <p>${product.description}</p>
-     <p>${product.price}</p>
-   </div>
- `;
+ // Create elements instead of using innerHTML for better security
+ const img = document.createElement('img');
+ img.src = product.image || '';
+ img.alt = product.name || '';
+ 
+ const title = document.createElement('h2');
+ title.textContent = product.name || '';
+ 
+ const description = document.createElement('p');
+ description.textContent = product.description || '';
+ 
+ const price = document.createElement('p');
+ price.textContent = product.price || '';
+ 
+ const cardContent = document.createElement('div');
+ cardContent.className = 'card-content';
+ cardContent.appendChild(title);
+ cardContent.appendChild(description);
+ cardContent.appendChild(price);
+ 
+ card.appendChild(img);
+ card.appendChild(cardContent);

Also, consider adding a loading indicator while products are being fetched, and proper error handling for the UI if the fetch fails.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
document.addEventListener('DOMContentLoaded', () => {
fetch('products.json')
.then(response => response.json())
.then(products => {
const grid = document.getElementById('product-grid');
products.forEach((product, index) => {
const card = document.createElement('div');
card.className = 'card';
card.style.animationDelay = `${index * 0.2}s`;
card.innerHTML = `
<img src="${product.image}" alt="${product.name}" />
<div class="card-content">
<h2>${product.name}</h2>
<p>${product.description}</p>
<p>${product.price}</p>
</div>
`;
grid.appendChild(card);
});
})
.catch(error => {
console.error('Error loading products:', error);
});
});
document.addEventListener('DOMContentLoaded', () => {
fetch('products.json')
.then(response => response.json())
.then(products => {
const grid = document.getElementById('product-grid');
products.forEach((product, index) => {
const card = document.createElement('div');
card.className = 'card';
card.style.animationDelay = `${index * 0.2}s`;
// Create elements instead of using innerHTML for better security
const img = document.createElement('img');
img.src = product.image || '';
img.alt = product.name || '';
const title = document.createElement('h2');
title.textContent = product.name || '';
const description = document.createElement('p');
description.textContent = product.description || '';
const price = document.createElement('p');
price.textContent = product.price || '';
const cardContent = document.createElement('div');
cardContent.className = 'card-content';
cardContent.appendChild(title);
cardContent.appendChild(description);
cardContent.appendChild(price);
card.appendChild(img);
card.appendChild(cardContent);
grid.appendChild(card);
});
})
.catch(error => {
console.error('Error loading products:', error);
});
});

Comment on lines +1 to +25
document.addEventListener('DOMContentLoaded', () => {
fetch('products.json')
.then(response => response.json())
.then(products => {
const grid = document.getElementById('product-grid');
products.forEach((product, index) => {
const card = document.createElement('div');
card.className = 'card';
card.style.animationDelay = `${index * 0.2}s`;

card.innerHTML = `
<img src="${product.image}" alt="${product.name}" />
<div class="card-content">
<h2>${product.name}</h2>
<p>${product.description}</p>
<p>${product.price}</p>
</div>
`;
grid.appendChild(card);
});
})
.catch(error => {
console.error('Error loading products:', error);
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Code duplication identified and XSS vulnerabilities present.

This script is identical to the one in content-useast/script.js, suggesting code duplication. It has the same XSS vulnerability and lack of error handling as the East region script.

  1. The identical code in both US East and US West regions indicates a violation of the DRY principle.
  2. The same XSS vulnerability exists here as in the East region script.
- // Duplicate scripts in content-useast/script.js and content-uswest/script.js
+ // Consider refactoring to share a common script file and parameterize any region-specific behavior

For maintainability, consider:

  1. Moving this shared code to a common JavaScript file
  2. Including that file in both region's HTML
  3. Parameterizing any region-specific behavior

Additionally, apply the same security fixes recommended for the East region script to prevent XSS attacks.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 1 to 20
# Kiosk demo

This demo boots a device with Firefox in kiosk mode for a retail use case.

## Device image

You can build the image in the bootc directory yourself, or use the latest
version of ```quay.io/atraeger/rhel-kiosk-demo```

## Application

The application runs a simple webserver that mounts the
```/var/kiosk/catalog``` directory from the device's file system. Add your
kiosk content there. You can optionally have FC sync this content from a git
repo.

## Kiosk script

The gnome-kiosk-script script needs to be placed in
```/home/kiosk/.local/bin/``` .
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

README provides basic information but lacks detailed setup instructions

The README provides a high-level overview but could benefit from more detailed instructions:

  1. Add instructions for building the image locally
  2. Include details about the required content structure for /var/kiosk/catalog
  3. Provide guidance on how to configure the FC (Flight Control) sync
  4. Add troubleshooting section for common issues

Also, for better readability and consistency:

- ```quay.io/atraeger/rhel-kiosk-demo```
+ `quay.io/atraeger/rhel-kiosk-demo`
- ```/var/kiosk/catalog``` 
+ `/var/kiosk/catalog`
- ```/home/kiosk/.local/bin/``` 
+ `/home/kiosk/.local/bin/`

Comment on lines +7 to +9
CONFIG_FILE="/etc/kiosk-mode/bin/url.conf"
DEFAULT_URL="https://github.com/flightctl/flightctl"
BROWSER="firefox"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Default URL points to external site

The default URL points to GitHub which requires internet access. For a kiosk demo, consider pointing to a local URL by default:

CONFIG_FILE="/etc/kiosk-mode/bin/url.conf"
-DEFAULT_URL="https://github.com/flightctl/flightctl"
+DEFAULT_URL="http://localhost:8080"
BROWSER="firefox"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CONFIG_FILE="/etc/kiosk-mode/bin/url.conf"
DEFAULT_URL="https://github.com/flightctl/flightctl"
BROWSER="firefox"
CONFIG_FILE="/etc/kiosk-mode/bin/url.conf"
DEFAULT_URL="http://localhost:8080"
BROWSER="firefox"

Comment on lines +25 to +26
sleep 1.0
exec "$0" "$@"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Infinite restart loop could be problematic

The script automatically restarts itself when Firefox exits, creating an infinite loop that could:

  1. Mask error conditions
  2. Create log spam in case of rapid failures
  3. Make it difficult to exit the kiosk mode

Consider adding:

sleep 1.0
+echo "[kiosk] Browser exited, restarting in 5 seconds..."
+# Add exponential backoff to prevent rapid restarts
+if [[ -f /tmp/kiosk_restarts ]]; then
+  RESTARTS=$(($(cat /tmp/kiosk_restarts) + 1))
+else
+  RESTARTS=1
+fi
+echo $RESTARTS > /tmp/kiosk_restarts
+
+# If we've restarted too many times in a short period, wait longer
+if [[ $RESTARTS -gt 5 ]]; then
+  echo "[kiosk] Too many restarts, waiting 30 seconds..."
+  sleep 30
+fi
+
exec "$0" "$@"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sleep 1.0
exec "$0" "$@"
sleep 1.0
echo "[kiosk] Browser exited, restarting in 5 seconds..."
# Add exponential backoff to prevent rapid restarts
if [[ -f /tmp/kiosk_restarts ]]; then
RESTARTS=$(($(cat /tmp/kiosk_restarts) + 1))
else
RESTARTS=1
fi
echo $RESTARTS > /tmp/kiosk_restarts
# If we've restarted too many times in a short period, wait longer
if [[ $RESTARTS -gt 5 ]]; then
echo "[kiosk] Too many restarts, waiting 30 seconds..."
sleep 30
fi
exec "$0" "$@"

Comment on lines 1 to 42
FROM quay.io/centos-bootc/centos-bootc:stream9

# Add Flight Control agent
RUN dnf -y copr enable @redhat-et/flightctl && \
dnf -y install flightctl-agent && \
rm -rf /var/{cache,log} /var/lib/{dnf,rhsm} && \
systemctl enable flightctl-agent.service

# Add cloud-init and open-vm-tools
RUN dnf -y install cloud-init open-vm-tools && \
ln -s ../cloud-init.target /usr/lib/systemd/system/default.target.wants && \
rm -rf /var/{cache,log} /var/lib/{dnf,rhsm} && \
systemctl enable vmtoolsd.service

# Add podman-compose tool
RUN dnf -y install epel-release && \
dnf -y install podman-compose && \
rm -rf /var/{cache,log} /var/lib/{dnf,rhsm} && \
systemctl enable podman.service

# Add browser, kiosk UI, and other tools.
# Also disable bootc auto-update timer to avoid interference during demo.
RUN dnf install -y \
gnome-shell \
gnome-kiosk \
gnome-kiosk-script-session \
firefox \
unzip \
&& dnf -y clean all \
&& systemctl mask bootc-fetch-apply-updates.timer \
&& systemctl set-default graphical.target

# Create kiosk user
RUN useradd -m kiosk && passwd -d kiosk

# Set up autologin using a one-shot systemd service
COPY --chmod=755 configure-kiosk-autologin.sh /usr/local/bin/configure-kiosk-autologin.sh
COPY kiosk-autologin-setup.service /usr/lib/systemd/system/kiosk-autologin-setup.service

# Enable the one-shot service so it runs at first boot
RUN systemctl enable kiosk-autologin-setup.service
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Address the pipeline failure by correcting directory structure.

The pipeline is failing with "Directory 'kiosk/bootc' does not exist", but your file is in 'demos/kiosk/bootc'. This suggests a mismatch between the pipeline configuration and the actual repository structure.

Either the pipeline needs to be updated to look in 'demos/kiosk/bootc' instead of 'kiosk/bootc', or the files need to be moved to match the expected structure. Check with your team to determine the correct approach.

🧰 Tools
🪛 GitHub Actions: Build changed OS images (bootc)

[error] 1-1: Directory 'kiosk/bootc' does not exist. Command 'pushd kiosk/bootc' failed with exit code 1.

z-index: -1;
pointer-events: none;
transform: translate(-50%);
#animation: spin3d 20s linear infinite;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix invalid CSS property prefix.
The line uses #animation, which is not a valid CSS declaration. Replace it with a proper animation property to enable the 3D spin effect:

-  #animation: spin3d 20s linear infinite;
+  animation: spin3d 20s linear infinite;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#animation: spin3d 20s linear infinite;
animation: spin3d 20s linear infinite;
🧰 Tools
🪛 Biome (1.9.4)

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)

Comment on lines +3 to +5
metadata:
labels: {}
name: kiosks
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Missing region metadata label for content mount.
The kiosk-content entry uses path: /content-{{ .metadata.labels.region }}, but metadata.labels is empty. This will resolve to /content- and fail to mount the intended directory. Add a region label, for example:

metadata:
  labels:
    type: kiosk
    region: useast

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
demos/kiosk/content/content-useast/styles.css (1)

32-34: Fix invalid CSS property prefix for animation.
The #animation property on body::before is invalid. It should be:

animation: spin3d 20s linear infinite;
🧰 Tools
🪛 Biome (1.9.4)

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)

demos/kiosk/content/content-uswest/styles.css (1)

32-34: Fix invalid CSS property prefix for animation.
Same issue here: replace #animation with:

animation: spin3d 20s linear infinite;
🧰 Tools
🪛 Biome (1.9.4)

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)

demos/kiosk/deployment/fleet.yaml (1)

3-5: Missing region metadata label for content mount.
The interpolation content-{{ .metadata.labels.region }} will break since metadata.labels.region is empty. Add a region label under metadata.labels, for example:

metadata:
  labels:
    region: useast
🧹 Nitpick comments (3)
demos/kiosk/content/content-useast/styles.css (1)

5-5: Ensure the "Red Hat Display" font is loaded.
You’re referencing "Red Hat Display" without importing it. Consider adding an @import or @font-face rule at the top, for example:

@import url('https://fonts.googleapis.com/css2?family=Red+Hat+Display&display=swap');
demos/kiosk/content/content-uswest/styles.css (1)

1-110: DRY up duplicated styles across regions.
Both regional stylesheets are identical. Extract shared rules into a common CSS file (e.g., common-styles.css) and import it in each index.html to reduce duplication and ease maintenance.

🧰 Tools
🪛 Biome (1.9.4)

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)


[error] 36-37: expected , but instead found .

Remove .

(parse)


[error] 109-109: expected } but instead the file ends

the file ends here

(parse)


[error] 27-27: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

demos/kiosk/deployment/fleet.yaml (1)

17-25: Consider sourcing the Podman Compose file via gitRef.
Instead of inlining podman-compose.yaml, reference it with a gitRef (as done for kiosk content and scripts). This centralizes configuration and keeps the Fleet manifest cleaner:

- name: kiosk-app
  appType: compose
  gitRef:
    repository: flightctl-demos
    targetRevision: fckiosk
    path: /demos/kiosk/webserver/podman-compose.yaml
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78deb06 and a13ee81.

⛔ Files ignored due to path filters (8)
  • demos/kiosk/content/content-useast/images/cities.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/logo.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/telecom.png is excluded by !**/*.png
  • demos/kiosk/content/content-useast/images/transportation.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/healthcare.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/industrial.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/logo.png is excluded by !**/*.png
  • demos/kiosk/content/content-uswest/images/retail.png is excluded by !**/*.png
📒 Files selected for processing (15)
  • demos/kiosk/bootc/Containerfile (1 hunks)
  • demos/kiosk/bootc/configure-kiosk-autologin.sh (1 hunks)
  • demos/kiosk/bootc/kiosk-autologin-setup.service (1 hunks)
  • demos/kiosk/content/content-useast/index.html (1 hunks)
  • demos/kiosk/content/content-useast/products.json (1 hunks)
  • demos/kiosk/content/content-useast/script.js (1 hunks)
  • demos/kiosk/content/content-useast/styles.css (1 hunks)
  • demos/kiosk/content/content-uswest/index.html (1 hunks)
  • demos/kiosk/content/content-uswest/products.json (1 hunks)
  • demos/kiosk/content/content-uswest/script.js (1 hunks)
  • demos/kiosk/content/content-uswest/styles.css (1 hunks)
  • demos/kiosk/deployment/fleet.yaml (1 hunks)
  • demos/kiosk/kiosk-script/gnome-kiosk-script (1 hunks)
  • demos/kiosk/webserver/Containerfile (1 hunks)
  • demos/kiosk/webserver/podman-compose.yaml (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • demos/kiosk/content/content-useast/script.js
  • demos/kiosk/content/content-uswest/script.js
  • demos/kiosk/bootc/kiosk-autologin-setup.service
🚧 Files skipped from review as they are similar to previous changes (9)
  • demos/kiosk/webserver/Containerfile
  • demos/kiosk/content/content-useast/products.json
  • demos/kiosk/content/content-uswest/index.html
  • demos/kiosk/bootc/Containerfile
  • demos/kiosk/content/content-uswest/products.json
  • demos/kiosk/content/content-useast/index.html
  • demos/kiosk/kiosk-script/gnome-kiosk-script
  • demos/kiosk/webserver/podman-compose.yaml
  • demos/kiosk/bootc/configure-kiosk-autologin.sh
🧰 Additional context used
🪛 Biome (1.9.4)
demos/kiosk/content/content-useast/styles.css

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)


[error] 36-37: expected , but instead found .

Remove .

(parse)


[error] 109-109: expected } but instead the file ends

the file ends here

(parse)


[error] 27-27: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

demos/kiosk/content/content-uswest/styles.css

[error] 33-33: Expected a compound selector but instead found '20'.

Expected a compound selector here.

(parse)


[error] 33-33: expected , but instead found s

Remove s

(parse)


[error] 33-33: expected , but instead found ;

Remove ;

(parse)


[error] 34-34: expected , but instead found transform-style

Remove transform-style

(parse)


[error] 34-34: expected , but instead found ;

Remove ;

(parse)


[error] 36-37: expected , but instead found .

Remove .

(parse)


[error] 109-109: expected } but instead the file ends

the file ends here

(parse)


[error] 27-27: Unexpected shorthand property background after background-color

(lint/suspicious/noShorthandPropertyOverrides)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant