feat: add builder mode for centralized Nix builds #2

Merged
torjus merged 4 commits from feat/builder into master 2026-02-10 21:16:05 +00:00
2 changed files with 19 additions and 0 deletions
Showing only changes of commit 08f1fcc6ac - Show all commits

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
"regexp"
"sort"
"sync"
"time"
@@ -13,6 +14,10 @@ import (
"git.t-juice.club/torjus/homelab-deploy/internal/nats"
)
// hostnameRegex validates hostnames from flake output.
// Allows: alphanumeric, dashes, underscores, dots.
var hostnameRegex = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`)
// BuilderConfig holds the configuration for the builder.
type BuilderConfig struct {
NATSUrl string
@@ -197,6 +202,16 @@ func (b *Builder) handleBuildRequest(subject string, data []byte) {
}
return
}
// Filter out hostnames with invalid characters (security: prevent injection)
validHosts := make([]string, 0, len(hosts))
for _, host := range hosts {
if hostnameRegex.MatchString(host) {
validHosts = append(validHosts, host)
} else {
b.logger.Warn("skipping hostname with invalid characters", "hostname", host)
}
}
hosts = validHosts
// Sort hosts for consistent ordering
sort.Strings(hosts)
} else {

View File

@@ -45,6 +45,10 @@ func (r *BuildRequest) Validate() error {
if r.Target == "" {
return fmt.Errorf("target is required")
}
// Target must be "all" or a valid hostname (same format as revision/branch)
if r.Target != "all" && !revisionRegex.MatchString(r.Target) {
return fmt.Errorf("invalid target format: %q", r.Target)
}
if r.Branch != "" && !revisionRegex.MatchString(r.Branch) {
return fmt.Errorf("invalid branch format: %q", r.Branch)
}