Skip to content

Commit 1ab2c76

Browse files
Merge pull request #147 from Githubguy132010/feat-gui-docker-iso-builder
feat: Add Docker container with GUI for building ISO
2 parents adef73b + 7c51faa commit 1ab2c76

File tree

5 files changed

+235
-0
lines changed

5 files changed

+235
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: GUI Build Test
2+
3+
on:
4+
pull_request:
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
jobs:
10+
test-gui-build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
17+
- name: Build the GUI Docker image
18+
run: sudo docker build -t arch-iso-gui -f Dockerfile.gui .
19+
20+
- name: Run the GUI container
21+
run: sudo docker run --rm --privileged -d -p 8080:8080 --name arch-iso-gui-test -v $(pwd):/workdir arch-iso-gui
22+
23+
- name: Wait for the server to start
24+
run: sleep 15
25+
26+
- name: Trigger ISO build and wait for completion
27+
# This step triggers the build via the API and waits for the "BUILD_SUCCESS" message.
28+
# The build can take a long time, so a generous timeout is set.
29+
run: |
30+
curl -N --max-time 7200 http://localhost:8080/build | tee build.log
31+
grep -q "BUILD_SUCCESS" build.log
32+
33+
- name: Verify ISO file was created
34+
run: sudo docker exec arch-iso-gui-test test -f /workdir/out/Arch.iso
35+
36+
- name: Test ISO download endpoint
37+
run: curl -f -I http://localhost:8080/download | grep -q 'Content-Disposition: attachment; filename=Arch.iso'
38+
39+
- name: Stop the container
40+
if: always()
41+
run: sudo docker stop arch-iso-gui-test

Dockerfile.gui

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Use the same builder as the original Dockerfile
2+
FROM archlinux:latest AS builder
3+
4+
# Set up parallel downloads and other optimizations
5+
COPY pacman.conf /etc/pacman.conf
6+
7+
# Update system and install necessary packages
8+
RUN pacman -Syu --noconfirm && \
9+
pacman -S --noconfirm --needed \
10+
git \
11+
archiso \
12+
grub \
13+
base-devel \
14+
python-flask \
15+
&& pacman -Scc --noconfirm
16+
17+
# Set the working directory
18+
WORKDIR /build
19+
20+
# Copy only necessary files for package installation
21+
COPY packages.x86_64 bootstrap_packages.x86_64 profiledef.sh ./
22+
23+
# Create a new final image
24+
FROM builder AS final
25+
26+
# Set the working directory
27+
WORKDIR /workdir
28+
29+
# Copy the rest of the files
30+
COPY . .
31+
32+
# Use an entrypoint script for better flexibility
33+
COPY ./scripts/entrypoint.sh /entrypoint.sh
34+
RUN chmod +x /entrypoint.sh
35+
36+
# Expose the port for the web GUI
37+
EXPOSE 8080
38+
39+
# Set the entrypoint to run the Flask application
40+
ENTRYPOINT ["python", "app.py"]

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,55 @@ To install Docker, follow the instructions for your operating system:
8484
8585
Once the process completes, the ISO will be available in the `out/` directory within your local folder as `Arch.iso`.
8686
87+
---
88+
89+
## How to Build the ISO with a GUI
90+
91+
For a more user-friendly experience, you can use a Docker container that provides a web-based graphical user interface (GUI) to build the ISO.
92+
93+
### Prerequisites
94+
95+
Ensure you have Docker installed and running on your system.
96+
97+
### Steps to Build with the GUI
98+
99+
1. **Clone the repository**:
100+
101+
```bash
102+
git clone https://github.com/Githubguy132010/Arch-Linux-without-the-beeps.git
103+
cd Arch-Linux-without-the-beeps
104+
```
105+
106+
2. **Build the GUI Docker Image**:
107+
108+
Build the Docker image for the GUI application.
109+
110+
```bash
111+
docker build -t arch-iso-gui -f Dockerfile.gui .
112+
```
113+
114+
3. **Run the GUI Container**:
115+
116+
Run the container, mapping port 8080 to your host system.
117+
118+
```bash
119+
docker run --rm --privileged -p 8080:8080 -v $(pwd):/workdir arch-iso-gui
120+
```
121+
122+
4. **Access the GUI**:
123+
124+
Open your web browser and navigate to `http://localhost:8080`.
125+
126+
5. **Build the ISO**:
127+
128+
Click the "Build ISO" button to start the build process. The logs will be displayed in real-time on the page.
129+
130+
6. **Download the ISO**:
131+
132+
Once the build is complete, a download link for `Arch.iso` will appear.
133+
134+
---
135+
87136
## How to Use GitHub Actions (Automated Workflow)
88137
89138
This repository also includes a GitHub Actions workflow for building and releasing the ISO automatically on GitHub.

app.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import os
2+
import subprocess
3+
from flask import Flask, render_template, Response, send_from_directory
4+
5+
app = Flask(__name__)
6+
ISO_DIR = "/workdir/out"
7+
ISO_NAME = "Arch.iso"
8+
ISO_PATH = os.path.join(ISO_DIR, ISO_NAME)
9+
10+
@app.route('/')
11+
def index():
12+
return render_template('index.html')
13+
14+
@app.route('/build')
15+
def build():
16+
def generate():
17+
# Ensure the output directory exists
18+
os.makedirs(ISO_DIR, exist_ok=True)
19+
20+
# Command to execute the build script
21+
command = ["/entrypoint.sh", "build", "out", "work"]
22+
23+
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1, universal_newlines=True)
24+
25+
for line in process.stdout:
26+
yield f"data: {line}\n\n"
27+
28+
process.wait()
29+
30+
if process.returncode == 0:
31+
yield "data: BUILD_SUCCESS\n\n"
32+
else:
33+
yield "data: BUILD_FAILED\n\n"
34+
35+
return Response(generate(), mimetype='text/event-stream')
36+
37+
@app.route('/download')
38+
def download():
39+
if os.path.exists(ISO_PATH):
40+
return send_from_directory(directory=ISO_DIR, path=ISO_NAME, as_attachment=True)
41+
else:
42+
return "ISO not found.", 404
43+
44+
if __name__ == '__main__':
45+
app.run(host='0.0.0.0', port=8080)

templates/index.html

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Arch ISO Builder</title>
7+
<style>
8+
body { font-family: sans-serif; margin: 2em; }
9+
#log { white-space: pre-wrap; background-color: #f4f4f4; border: 1px solid #ddd; padding: 1em; height: 400px; overflow-y: scroll; }
10+
#buildBtn { padding: 0.5em 1em; font-size: 1em; }
11+
#downloadLinkContainer { margin-top: 1em; }
12+
</style>
13+
</head>
14+
<body>
15+
<h1>Arch Linux ISO Builder</h1>
16+
<button id="buildBtn">Build ISO</button>
17+
<h2>Build Log</h2>
18+
<pre id="log"></pre>
19+
<div id="downloadLinkContainer"></div>
20+
21+
<script>
22+
const buildBtn = document.getElementById('buildBtn');
23+
const log = document.getElementById('log');
24+
const downloadLinkContainer = document.getElementById('downloadLinkContainer');
25+
26+
buildBtn.addEventListener('click', () => {
27+
buildBtn.disabled = true;
28+
log.textContent = 'Starting build...\n';
29+
downloadLinkContainer.innerHTML = '';
30+
31+
const eventSource = new EventSource('/build');
32+
33+
eventSource.onmessage = function(event) {
34+
if (event.data === 'BUILD_SUCCESS') {
35+
log.textContent += '\nBuild finished successfully!\n';
36+
const downloadLink = document.createElement('a');
37+
downloadLink.href = '/download';
38+
downloadLink.textContent = 'Download ISO';
39+
downloadLinkContainer.appendChild(downloadLink);
40+
eventSource.close();
41+
buildBtn.disabled = false;
42+
} else if (event.data === 'BUILD_FAILED') {
43+
log.textContent += '\nBuild failed!\n';
44+
eventSource.close();
45+
buildBtn.disabled = false;
46+
} else {
47+
log.textContent += event.data + '\n';
48+
log.scrollTop = log.scrollHeight;
49+
}
50+
};
51+
52+
eventSource.onerror = function() {
53+
log.textContent += '\nError connecting to the server.\n';
54+
eventSource.close();
55+
buildBtn.disabled = false;
56+
};
57+
});
58+
</script>
59+
</body>
60+
</html>

0 commit comments

Comments
 (0)