Merge branch 'dev' into LaurenceJJones-feature/installer-tui

This commit is contained in:
Owen
2026-02-25 10:48:05 -08:00
49 changed files with 1069 additions and 355 deletions

View File

@@ -19,11 +19,17 @@ import (
"time"
)
// DO NOT EDIT THIS FUNCTION; IT MATCHED BY REGEX IN CICD
// Version variables injected at build time via -ldflags
var (
pangolinVersion string
gerbilVersion string
badgerVersion string
)
func loadVersions(config *Config) {
config.PangolinVersion = "replaceme"
config.GerbilVersion = "replaceme"
config.BadgerVersion = "replaceme"
config.PangolinVersion = pangolinVersion
config.GerbilVersion = gerbilVersion
config.BadgerVersion = badgerVersion
}
//go:embed config/*
@@ -99,7 +105,10 @@ func main() {
os.Exit(1)
}
moveFile("config/docker-compose.yml", "docker-compose.yml")
if err := moveFile("config/docker-compose.yml", "docker-compose.yml"); err != nil {
fmt.Printf("Error moving docker-compose.yml: %v\n", err)
os.Exit(1)
}
fmt.Println("\nConfiguration files created successfully!")
@@ -120,7 +129,11 @@ func main() {
if !isDockerInstalled() && runtime.GOOS == "linux" && config.InstallationContainerType == Docker {
if readBool("Docker is not installed. Would you like to install it?", true) {
installDocker()
if err := installDocker(); err != nil {
fmt.Printf("Error installing Docker: %v\n", err)
return
}
// try to start docker service but ignore errors
if err := startDockerService(); err != nil {
fmt.Println("Error starting Docker service:", err)
@@ -129,7 +142,7 @@ func main() {
}
// wait 10 seconds for docker to start checking if docker is running every 2 seconds
fmt.Println("Waiting for Docker to start...")
for i := 0; i < 5; i++ {
for range 5 {
if isDockerRunning() {
fmt.Println("Docker is running!")
break
@@ -287,7 +300,8 @@ func podmanOrDocker() SupportedContainer {
os.Exit(1)
}
if chosenContainer == Podman {
switch chosenContainer {
case Podman:
if !isPodmanInstalled() {
fmt.Println("Podman or podman-compose is not installed. Please install both manually. Automated installation will be available in a later release.")
os.Exit(1)
@@ -308,7 +322,7 @@ func podmanOrDocker() SupportedContainer {
// Linux only.
if err := run("bash", "-c", "echo 'net.ipv4.ip_unprivileged_port_start=80' > /etc/sysctl.d/99-podman.conf && sysctl --system"); err != nil {
fmt.Printf("Error configuring unprivileged ports: %v\n", err)
fmt.Printf("Error configuring unprivileged ports: %v\n", err)
os.Exit(1)
}
} else {
@@ -318,7 +332,7 @@ func podmanOrDocker() SupportedContainer {
fmt.Println("Unprivileged ports have been configured.")
}
} else if chosenContainer == Docker {
case Docker:
// check if docker is not installed and the user is root
if !isDockerInstalled() {
if os.Geteuid() != 0 {
@@ -333,7 +347,7 @@ func podmanOrDocker() SupportedContainer {
fmt.Println("The installer will not be able to run docker commands without running it as root.")
os.Exit(1)
}
} else {
default:
// This shouldn't happen unless there's a third container runtime.
os.Exit(1)
}
@@ -402,10 +416,18 @@ func collectUserInput() Config {
}
func createConfigFiles(config Config) error {
os.MkdirAll("config", 0755)
os.MkdirAll("config/letsencrypt", 0755)
os.MkdirAll("config/db", 0755)
os.MkdirAll("config/logs", 0755)
if err := os.MkdirAll("config", 0755); err != nil {
return fmt.Errorf("failed to create config directory: %v", err)
}
if err := os.MkdirAll("config/letsencrypt", 0755); err != nil {
return fmt.Errorf("failed to create letsencrypt directory: %v", err)
}
if err := os.MkdirAll("config/db", 0755); err != nil {
return fmt.Errorf("failed to create db directory: %v", err)
}
if err := os.MkdirAll("config/logs", 0755); err != nil {
return fmt.Errorf("failed to create logs directory: %v", err)
}
// Walk through all embedded files
err := fs.WalkDir(configFiles, "config", func(path string, d fs.DirEntry, err error) error {
@@ -559,22 +581,24 @@ func showSetupTokenInstructions(containerType SupportedContainer, dashboardDomai
fmt.Println("To get your setup token, you need to:")
fmt.Println("")
fmt.Println("1. Start the containers")
if containerType == Docker {
switch containerType {
case Docker:
fmt.Println(" docker compose up -d")
} else if containerType == Podman {
case Podman:
fmt.Println(" podman-compose up -d")
} else {
}
fmt.Println("")
fmt.Println("2. Wait for the Pangolin container to start and generate the token")
fmt.Println("")
fmt.Println("3. Check the container logs for the setup token")
if containerType == Docker {
switch containerType {
case Docker:
fmt.Println(" docker logs pangolin | grep -A 2 -B 2 'SETUP TOKEN'")
} else if containerType == Podman {
case Podman:
fmt.Println(" podman logs pangolin | grep -A 2 -B 2 'SETUP TOKEN'")
} else {
}
fmt.Println("")
fmt.Println("4. Look for output like")
fmt.Println(" === SETUP TOKEN GENERATED ===")
@@ -636,10 +660,7 @@ func checkPortsAvailable(port int) error {
addr := fmt.Sprintf(":%d", port)
ln, err := net.Listen("tcp", addr)
if err != nil {
return fmt.Errorf(
"ERROR: port %d is occupied or cannot be bound: %w\n\n",
port, err,
)
return fmt.Errorf("ERROR: port %d is occupied or cannot be bound: %w", port, err)
}
if closeErr := ln.Close(); closeErr != nil {
fmt.Fprintf(os.Stderr,