mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 06:43:01 +00:00
Updated installation process simplified it
This commit is contained in:
parent
749d5ed5e7
commit
ba4e2688e4
2
Makefile
2
Makefile
@ -94,6 +94,8 @@ build-linux: deps
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "$(LDFLAGS_LINUX)" -trimpath -o bin-linux/orama-cli ./cmd/cli
|
||||
@echo "Building Olric for linux/amd64..."
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -trimpath -o bin-linux/olric-server github.com/olric-data/olric/cmd/olric-server
|
||||
@echo "Building IPFS Cluster Service for linux/amd64..."
|
||||
GOOS=linux GOARCH=amd64 GOBIN=$(CURDIR)/bin-linux go install -ldflags "-s -w" -trimpath github.com/ipfs-cluster/ipfs-cluster/cmd/ipfs-cluster-service@latest
|
||||
@echo "✓ All Linux binaries built in bin-linux/"
|
||||
@echo ""
|
||||
@echo "Next steps:"
|
||||
|
||||
@ -14,7 +14,26 @@ func Handle(args []string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Create orchestrator
|
||||
// Resolve base domain interactively if not provided (before local/VPS branch)
|
||||
if flags.BaseDomain == "" {
|
||||
flags.BaseDomain = promptForBaseDomain()
|
||||
}
|
||||
|
||||
// Local mode: not running as root → orchestrate install via SSH
|
||||
if os.Geteuid() != 0 {
|
||||
remote, err := NewRemoteOrchestrator(flags)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := remote.Execute(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// VPS mode: running as root on the VPS — existing behavior
|
||||
orchestrator, err := NewOrchestrator(flags)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ %v\n", err)
|
||||
@ -27,12 +46,6 @@ func Handle(args []string) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Check root privileges
|
||||
if err := orchestrator.validator.ValidateRootPrivileges(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Check port availability before proceeding
|
||||
if err := orchestrator.validator.ValidatePorts(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "❌ %v\n", err)
|
||||
|
||||
@ -8,15 +8,12 @@ import (
|
||||
|
||||
// Flags represents install command flags
|
||||
type Flags struct {
|
||||
VpsIP string
|
||||
Domain string
|
||||
BaseDomain string // Base domain for deployment routing (e.g., "dbrs.space")
|
||||
Branch string
|
||||
NoPull bool
|
||||
Force bool
|
||||
DryRun bool
|
||||
SkipChecks bool
|
||||
PreBuilt bool // Skip building binaries, use pre-built binaries already on disk
|
||||
VpsIP string
|
||||
Domain string
|
||||
BaseDomain string // Base domain for deployment routing (e.g., "dbrs.space")
|
||||
Force bool
|
||||
DryRun bool
|
||||
SkipChecks bool
|
||||
Nameserver bool // Make this node a nameserver (runs CoreDNS + Caddy)
|
||||
JoinAddress string // HTTPS URL of existing node (e.g., https://node1.dbrs.space)
|
||||
Token string // Invite token for joining (from orama invite)
|
||||
@ -57,12 +54,9 @@ func ParseFlags(args []string) (*Flags, error) {
|
||||
fs.StringVar(&flags.VpsIP, "vps-ip", "", "Public IP of this VPS (required)")
|
||||
fs.StringVar(&flags.Domain, "domain", "", "Domain name for HTTPS (optional, e.g. gateway.example.com)")
|
||||
fs.StringVar(&flags.BaseDomain, "base-domain", "", "Base domain for deployment routing (e.g., dbrs.space)")
|
||||
fs.StringVar(&flags.Branch, "branch", "main", "Git branch to use (main or nightly)")
|
||||
fs.BoolVar(&flags.NoPull, "no-pull", false, "Skip git clone/pull, use existing repository in /home/debros/src")
|
||||
fs.BoolVar(&flags.Force, "force", false, "Force reconfiguration even if already installed")
|
||||
fs.BoolVar(&flags.DryRun, "dry-run", false, "Show what would be done without making changes")
|
||||
fs.BoolVar(&flags.SkipChecks, "skip-checks", false, "Skip minimum resource checks (RAM/CPU)")
|
||||
fs.BoolVar(&flags.PreBuilt, "pre-built", false, "Skip building binaries on VPS, use pre-built binaries already in /home/debros/bin and /usr/local/bin")
|
||||
fs.BoolVar(&flags.Nameserver, "nameserver", false, "Make this node a nameserver (runs CoreDNS + Caddy)")
|
||||
|
||||
// Cluster join flags
|
||||
|
||||
@ -33,18 +33,13 @@ func NewOrchestrator(flags *Flags) (*Orchestrator, error) {
|
||||
oramaHome := "/home/debros"
|
||||
oramaDir := oramaHome + "/.orama"
|
||||
|
||||
// Prompt for base domain if not provided via flag
|
||||
if flags.BaseDomain == "" {
|
||||
flags.BaseDomain = promptForBaseDomain()
|
||||
}
|
||||
|
||||
// Normalize peers
|
||||
peers, err := utils.NormalizePeers(flags.PeersStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid peers: %w", err)
|
||||
}
|
||||
|
||||
setup := production.NewProductionSetup(oramaHome, os.Stdout, flags.Force, flags.Branch, flags.NoPull, flags.SkipChecks, flags.PreBuilt)
|
||||
setup := production.NewProductionSetup(oramaHome, os.Stdout, flags.Force, flags.SkipChecks)
|
||||
setup.SetNameserver(flags.Nameserver)
|
||||
|
||||
// Configure Anyone mode
|
||||
@ -84,18 +79,6 @@ func NewOrchestrator(flags *Flags) (*Orchestrator, error) {
|
||||
func (o *Orchestrator) Execute() error {
|
||||
fmt.Printf("🚀 Starting production installation...\n\n")
|
||||
|
||||
// Inform user if skipping git pull
|
||||
if o.flags.NoPull {
|
||||
fmt.Printf(" ⚠️ --no-pull flag enabled: Skipping git clone/pull\n")
|
||||
fmt.Printf(" Using existing repository at /home/debros/src\n")
|
||||
}
|
||||
|
||||
// Inform user if using pre-built binaries
|
||||
if o.flags.PreBuilt {
|
||||
fmt.Printf(" ⚠️ --pre-built flag enabled: Skipping all Go compilation\n")
|
||||
fmt.Printf(" Using pre-built binaries from /home/debros/bin and /usr/local/bin\n")
|
||||
}
|
||||
|
||||
// Validate DNS if domain is provided
|
||||
o.validator.ValidateDNS()
|
||||
|
||||
@ -112,7 +95,7 @@ func (o *Orchestrator) Execute() error {
|
||||
ORPort: o.flags.AnyoneORPort,
|
||||
}
|
||||
}
|
||||
utils.ShowDryRunSummaryWithRelay(o.flags.VpsIP, o.flags.Domain, o.flags.Branch, o.peers, o.flags.JoinAddress, o.validator.IsFirstNode(), o.oramaDir, relayInfo)
|
||||
utils.ShowDryRunSummaryWithRelay(o.flags.VpsIP, o.flags.Domain, "main", o.peers, o.flags.JoinAddress, o.validator.IsFirstNode(), o.oramaDir, relayInfo)
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -131,7 +114,7 @@ func (o *Orchestrator) Execute() error {
|
||||
anyoneORPort = 9001
|
||||
}
|
||||
prefs := &production.NodePreferences{
|
||||
Branch: o.flags.Branch,
|
||||
Branch: "main",
|
||||
Nameserver: o.flags.Nameserver,
|
||||
AnyoneClient: o.flags.AnyoneClient,
|
||||
AnyoneRelay: o.flags.AnyoneRelay,
|
||||
|
||||
@ -10,10 +10,7 @@ import (
|
||||
type Flags struct {
|
||||
Force bool
|
||||
RestartServices bool
|
||||
NoPull bool
|
||||
PreBuilt bool
|
||||
SkipChecks bool
|
||||
Branch string
|
||||
Nameserver *bool // Pointer so we can detect if explicitly set vs default
|
||||
|
||||
// Anyone flags
|
||||
@ -39,10 +36,7 @@ func ParseFlags(args []string) (*Flags, error) {
|
||||
|
||||
fs.BoolVar(&flags.Force, "force", false, "Reconfigure all settings")
|
||||
fs.BoolVar(&flags.RestartServices, "restart", false, "Automatically restart services after upgrade")
|
||||
fs.BoolVar(&flags.NoPull, "no-pull", false, "Skip source download, use existing /home/debros/src")
|
||||
fs.BoolVar(&flags.PreBuilt, "pre-built", false, "Skip building binaries on VPS, use pre-built binaries already in /home/debros/bin and /usr/local/bin")
|
||||
fs.BoolVar(&flags.SkipChecks, "skip-checks", false, "Skip minimum resource checks (RAM/CPU)")
|
||||
fs.StringVar(&flags.Branch, "branch", "", "Git branch to use (uses saved preference if not specified)")
|
||||
|
||||
// Nameserver flag - use pointer to detect if explicitly set
|
||||
nameserver := fs.Bool("nameserver", false, "Make this node a nameserver (uses saved preference if not specified)")
|
||||
|
||||
@ -32,19 +32,13 @@ func NewOrchestrator(flags *Flags) *Orchestrator {
|
||||
// Load existing preferences
|
||||
prefs := production.LoadPreferences(oramaDir)
|
||||
|
||||
// Use saved branch if not specified
|
||||
branch := flags.Branch
|
||||
if branch == "" {
|
||||
branch = prefs.Branch
|
||||
}
|
||||
|
||||
// Use saved nameserver preference if not explicitly specified
|
||||
isNameserver := prefs.Nameserver
|
||||
if flags.Nameserver != nil {
|
||||
isNameserver = *flags.Nameserver
|
||||
}
|
||||
|
||||
setup := production.NewProductionSetup(oramaHome, os.Stdout, flags.Force, branch, flags.NoPull, flags.SkipChecks, flags.PreBuilt)
|
||||
setup := production.NewProductionSetup(oramaHome, os.Stdout, flags.Force, flags.SkipChecks)
|
||||
setup.SetNameserver(isNameserver)
|
||||
|
||||
// Configure Anyone mode (flag > saved preference > auto-detect)
|
||||
@ -103,18 +97,6 @@ func (o *Orchestrator) Execute() error {
|
||||
fmt.Printf(" This will preserve existing configurations and data\n")
|
||||
fmt.Printf(" Configurations will be updated to latest format\n\n")
|
||||
|
||||
// Log if --no-pull is enabled
|
||||
if o.flags.NoPull {
|
||||
fmt.Printf(" ⚠️ --no-pull flag enabled: Skipping git clone/pull\n")
|
||||
fmt.Printf(" Using existing repository at %s/src\n", o.oramaHome)
|
||||
}
|
||||
|
||||
// Log if --pre-built is enabled
|
||||
if o.flags.PreBuilt {
|
||||
fmt.Printf(" ⚠️ --pre-built flag enabled: Skipping all Go compilation\n")
|
||||
fmt.Printf(" Using pre-built binaries from %s/bin and /usr/local/bin\n", o.oramaHome)
|
||||
}
|
||||
|
||||
// Handle branch preferences
|
||||
if err := o.handleBranchPreferences(); err != nil {
|
||||
return err
|
||||
@ -216,15 +198,6 @@ func (o *Orchestrator) handleBranchPreferences() error {
|
||||
prefs := production.LoadPreferences(o.oramaDir)
|
||||
prefsChanged := false
|
||||
|
||||
// If branch was explicitly provided, update it
|
||||
if o.flags.Branch != "" {
|
||||
prefs.Branch = o.flags.Branch
|
||||
prefsChanged = true
|
||||
fmt.Printf(" Using branch: %s (saved for future upgrades)\n", o.flags.Branch)
|
||||
} else {
|
||||
fmt.Printf(" Using branch: %s (from saved preference)\n", prefs.Branch)
|
||||
}
|
||||
|
||||
// If nameserver was explicitly provided, update it
|
||||
if o.flags.Nameserver != nil {
|
||||
prefs.Nameserver = *o.flags.Nameserver
|
||||
|
||||
@ -116,66 +116,84 @@ func (ad *ArchitectureDetector) Detect() (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// DependencyChecker validates external tool availability
|
||||
type DependencyChecker struct {
|
||||
skipOptional bool
|
||||
}
|
||||
// DependencyChecker validates external tool availability and auto-installs missing ones
|
||||
type DependencyChecker struct{}
|
||||
|
||||
// NewDependencyChecker creates a new checker
|
||||
func NewDependencyChecker(skipOptional bool) *DependencyChecker {
|
||||
return &DependencyChecker{
|
||||
skipOptional: skipOptional,
|
||||
}
|
||||
func NewDependencyChecker(_ bool) *DependencyChecker {
|
||||
return &DependencyChecker{}
|
||||
}
|
||||
|
||||
// Dependency represents an external binary dependency
|
||||
type Dependency struct {
|
||||
Name string
|
||||
Command string
|
||||
Optional bool
|
||||
InstallHint string
|
||||
Name string
|
||||
Command string
|
||||
AptPkg string // apt package name to install
|
||||
}
|
||||
|
||||
// CheckAll validates all required dependencies
|
||||
// CheckAll validates all required dependencies, auto-installing any that are missing.
|
||||
func (dc *DependencyChecker) CheckAll() ([]Dependency, error) {
|
||||
dependencies := []Dependency{
|
||||
{
|
||||
Name: "curl",
|
||||
Command: "curl",
|
||||
Optional: false,
|
||||
InstallHint: "Usually pre-installed; if missing: apt-get install curl",
|
||||
},
|
||||
{
|
||||
Name: "git",
|
||||
Command: "git",
|
||||
Optional: false,
|
||||
InstallHint: "Install with: apt-get install git",
|
||||
},
|
||||
{
|
||||
Name: "make",
|
||||
Command: "make",
|
||||
Optional: false,
|
||||
InstallHint: "Install with: apt-get install make",
|
||||
},
|
||||
{Name: "curl", Command: "curl", AptPkg: "curl"},
|
||||
{Name: "git", Command: "git", AptPkg: "git"},
|
||||
{Name: "make", Command: "make", AptPkg: "make"},
|
||||
{Name: "jq", Command: "jq", AptPkg: "jq"},
|
||||
{Name: "speedtest", Command: "speedtest-cli", AptPkg: "speedtest-cli"},
|
||||
}
|
||||
|
||||
var missing []Dependency
|
||||
for _, dep := range dependencies {
|
||||
if _, err := exec.LookPath(dep.Command); err != nil {
|
||||
if !dep.Optional || !dc.skipOptional {
|
||||
missing = append(missing, dep)
|
||||
}
|
||||
missing = append(missing, dep)
|
||||
}
|
||||
}
|
||||
|
||||
if len(missing) > 0 {
|
||||
errMsg := "missing required dependencies:\n"
|
||||
for _, dep := range missing {
|
||||
errMsg += fmt.Sprintf(" - %s (%s): %s\n", dep.Name, dep.Command, dep.InstallHint)
|
||||
}
|
||||
return missing, fmt.Errorf("%s", errMsg)
|
||||
if len(missing) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Auto-install missing dependencies
|
||||
var pkgs []string
|
||||
var names []string
|
||||
for _, dep := range missing {
|
||||
pkgs = append(pkgs, dep.AptPkg)
|
||||
names = append(names, dep.Name)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, " Installing missing dependencies: %s\n", strings.Join(names, ", "))
|
||||
|
||||
// apt-get update first
|
||||
update := exec.Command("apt-get", "update", "-qq")
|
||||
update.Stdout = os.Stdout
|
||||
update.Stderr = os.Stderr
|
||||
update.Run() // best-effort, don't fail on update
|
||||
|
||||
// apt-get install
|
||||
args := append([]string{"install", "-y", "-qq"}, pkgs...)
|
||||
install := exec.Command("apt-get", args...)
|
||||
install.Stdout = os.Stdout
|
||||
install.Stderr = os.Stderr
|
||||
if err := install.Run(); err != nil {
|
||||
return missing, fmt.Errorf("failed to install dependencies (%s): %w", strings.Join(names, ", "), err)
|
||||
}
|
||||
|
||||
// Verify after install
|
||||
var stillMissing []Dependency
|
||||
for _, dep := range missing {
|
||||
if _, err := exec.LookPath(dep.Command); err != nil {
|
||||
stillMissing = append(stillMissing, dep)
|
||||
}
|
||||
}
|
||||
|
||||
if len(stillMissing) > 0 {
|
||||
errMsg := "dependencies still missing after install attempt:\n"
|
||||
for _, dep := range stillMissing {
|
||||
errMsg += fmt.Sprintf(" - %s\n", dep.Name)
|
||||
}
|
||||
return stillMissing, fmt.Errorf("%s", errMsg)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, " ✓ Dependencies installed successfully\n")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@ -72,9 +72,9 @@ func (bi *BinaryInstaller) ResolveBinaryPath(binary string, extraPaths ...string
|
||||
return installers.ResolveBinaryPath(binary, extraPaths...)
|
||||
}
|
||||
|
||||
// InstallDeBrosBinaries clones and builds DeBros binaries
|
||||
func (bi *BinaryInstaller) InstallDeBrosBinaries(branch string, oramaHome string, skipRepoUpdate bool) error {
|
||||
return bi.gateway.InstallDeBrosBinaries(branch, oramaHome, skipRepoUpdate)
|
||||
// InstallDeBrosBinaries builds DeBros binaries from source
|
||||
func (bi *BinaryInstaller) InstallDeBrosBinaries(oramaHome string) error {
|
||||
return bi.gateway.InstallDeBrosBinaries(oramaHome)
|
||||
}
|
||||
|
||||
// InstallSystemDependencies installs system-level dependencies via apt
|
||||
|
||||
@ -39,78 +39,9 @@ func (gi *GatewayInstaller) Configure() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// downloadSourceZIP downloads source code as ZIP from GitHub
|
||||
// This is simpler and more reliable than git clone with shallow clones
|
||||
func (gi *GatewayInstaller) downloadSourceZIP(branch string, srcDir string) error {
|
||||
// GitHub archive URL format
|
||||
zipURL := fmt.Sprintf("https://github.com/DeBrosOfficial/network/archive/refs/heads/%s.zip", branch)
|
||||
zipPath := "/tmp/network-source.zip"
|
||||
extractDir := "/tmp/network-extract"
|
||||
|
||||
// Clean up any previous download artifacts
|
||||
os.RemoveAll(zipPath)
|
||||
os.RemoveAll(extractDir)
|
||||
|
||||
// Download ZIP
|
||||
fmt.Fprintf(gi.logWriter, " Downloading source (branch: %s)...\n", branch)
|
||||
if err := DownloadFile(zipURL, zipPath); err != nil {
|
||||
return fmt.Errorf("failed to download source from %s: %w", zipURL, err)
|
||||
}
|
||||
|
||||
// Create extraction directory
|
||||
if err := os.MkdirAll(extractDir, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create extraction directory: %w", err)
|
||||
}
|
||||
|
||||
// Extract ZIP
|
||||
fmt.Fprintf(gi.logWriter, " Extracting source...\n")
|
||||
extractCmd := exec.Command("unzip", "-q", "-o", zipPath, "-d", extractDir)
|
||||
if output, err := extractCmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to extract source: %w\n%s", err, string(output))
|
||||
}
|
||||
|
||||
// GitHub extracts to network-{branch}/ directory
|
||||
extractedDir := filepath.Join(extractDir, fmt.Sprintf("network-%s", branch))
|
||||
|
||||
// Verify extracted directory exists
|
||||
if _, err := os.Stat(extractedDir); os.IsNotExist(err) {
|
||||
// Try alternative naming (GitHub may sanitize branch names)
|
||||
entries, _ := os.ReadDir(extractDir)
|
||||
if len(entries) == 1 && entries[0].IsDir() {
|
||||
extractedDir = filepath.Join(extractDir, entries[0].Name())
|
||||
} else {
|
||||
return fmt.Errorf("extracted directory not found at %s", extractedDir)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove existing source directory
|
||||
os.RemoveAll(srcDir)
|
||||
|
||||
// Move extracted content to source directory
|
||||
if err := os.Rename(extractedDir, srcDir); err != nil {
|
||||
// Cross-filesystem fallback: copy instead of rename
|
||||
fmt.Fprintf(gi.logWriter, " Moving source (cross-filesystem copy)...\n")
|
||||
copyCmd := exec.Command("cp", "-r", extractedDir, srcDir)
|
||||
if output, err := copyCmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("failed to move source: %w\n%s", err, string(output))
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup temp files
|
||||
os.RemoveAll(zipPath)
|
||||
os.RemoveAll(extractDir)
|
||||
|
||||
// Fix ownership
|
||||
if err := exec.Command("chown", "-R", "debros:debros", srcDir).Run(); err != nil {
|
||||
fmt.Fprintf(gi.logWriter, " ⚠️ Warning: failed to chown source directory: %v\n", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(gi.logWriter, " ✓ Source downloaded\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
// InstallDeBrosBinaries downloads and builds DeBros binaries
|
||||
func (gi *GatewayInstaller) InstallDeBrosBinaries(branch string, oramaHome string, skipRepoUpdate bool) error {
|
||||
// InstallDeBrosBinaries builds DeBros binaries from source at /home/debros/src.
|
||||
// Source must already be present (uploaded via SCP archive).
|
||||
func (gi *GatewayInstaller) InstallDeBrosBinaries(oramaHome string) error {
|
||||
fmt.Fprintf(gi.logWriter, " Building DeBros binaries...\n")
|
||||
|
||||
srcDir := filepath.Join(oramaHome, "src")
|
||||
@ -124,24 +55,9 @@ func (gi *GatewayInstaller) InstallDeBrosBinaries(branch string, oramaHome strin
|
||||
return fmt.Errorf("failed to create bin directory %s: %w", binDir, err)
|
||||
}
|
||||
|
||||
// Check if source directory has content
|
||||
hasSourceContent := false
|
||||
if entries, err := os.ReadDir(srcDir); err == nil && len(entries) > 0 {
|
||||
hasSourceContent = true
|
||||
}
|
||||
|
||||
// Handle repository update/download based on skipRepoUpdate flag
|
||||
if skipRepoUpdate {
|
||||
fmt.Fprintf(gi.logWriter, " Skipping source download (--no-pull flag)\n")
|
||||
if !hasSourceContent {
|
||||
return fmt.Errorf("cannot skip download: source directory is empty at %s (need to populate it first)", srcDir)
|
||||
}
|
||||
fmt.Fprintf(gi.logWriter, " Using existing source at %s\n", srcDir)
|
||||
} else {
|
||||
// Download source as ZIP from GitHub (simpler than git, no shallow clone issues)
|
||||
if err := gi.downloadSourceZIP(branch, srcDir); err != nil {
|
||||
return err
|
||||
}
|
||||
// Verify source exists
|
||||
if entries, err := os.ReadDir(srcDir); err != nil || len(entries) == 0 {
|
||||
return fmt.Errorf("source directory is empty at %s (upload source archive first)", srcDir)
|
||||
}
|
||||
|
||||
// Build binaries
|
||||
|
||||
@ -52,9 +52,6 @@ type ProductionSetup struct {
|
||||
serviceGenerator *SystemdServiceGenerator
|
||||
serviceController *SystemdController
|
||||
binaryInstaller *BinaryInstaller
|
||||
branch string
|
||||
skipRepoUpdate bool
|
||||
skipBuild bool // Skip all Go compilation (use pre-built binaries)
|
||||
NodePeerID string // Captured during Phase3 for later display
|
||||
}
|
||||
|
||||
@ -86,24 +83,16 @@ func SaveBranchPreference(oramaDir, branch string) error {
|
||||
}
|
||||
|
||||
// NewProductionSetup creates a new production setup orchestrator
|
||||
func NewProductionSetup(oramaHome string, logWriter io.Writer, forceReconfigure bool, branch string, skipRepoUpdate bool, skipResourceChecks bool, skipBuild bool) *ProductionSetup {
|
||||
func NewProductionSetup(oramaHome string, logWriter io.Writer, forceReconfigure bool, skipResourceChecks bool) *ProductionSetup {
|
||||
oramaDir := filepath.Join(oramaHome, ".orama")
|
||||
arch, _ := (&ArchitectureDetector{}).Detect()
|
||||
|
||||
// If branch is empty, try to read from stored preference, otherwise default to main
|
||||
if branch == "" {
|
||||
branch = ReadBranchPreference(oramaDir)
|
||||
}
|
||||
|
||||
return &ProductionSetup{
|
||||
oramaHome: oramaHome,
|
||||
oramaDir: oramaDir,
|
||||
logWriter: logWriter,
|
||||
forceReconfigure: forceReconfigure,
|
||||
arch: arch,
|
||||
branch: branch,
|
||||
skipRepoUpdate: skipRepoUpdate,
|
||||
skipBuild: skipBuild,
|
||||
skipResourceChecks: skipResourceChecks,
|
||||
privChecker: &PrivilegeChecker{},
|
||||
osDetector: &OSDetector{},
|
||||
@ -201,12 +190,12 @@ func (ps *ProductionSetup) Phase1CheckPrerequisites() error {
|
||||
ps.arch = arch
|
||||
ps.logf(" ✓ Detected architecture: %s", arch)
|
||||
|
||||
// Check basic dependencies
|
||||
// Check basic dependencies (auto-installs missing ones)
|
||||
depChecker := NewDependencyChecker(ps.skipOptionalDeps)
|
||||
if missing, err := depChecker.CheckAll(); err != nil {
|
||||
ps.logf(" ❌ Missing dependencies:")
|
||||
ps.logf(" ❌ Failed to install dependencies:")
|
||||
for _, dep := range missing {
|
||||
ps.logf(" - %s: %s", dep.Name, dep.InstallHint)
|
||||
ps.logf(" - %s", dep.Name)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@ -307,86 +296,30 @@ func (ps *ProductionSetup) Phase2bInstallBinaries() error {
|
||||
ps.logf(" ⚠️ System dependencies warning: %v", err)
|
||||
}
|
||||
|
||||
if ps.skipBuild {
|
||||
// --pre-built mode: skip all Go compilation, verify binaries exist
|
||||
ps.logf(" ℹ️ --pre-built mode: skipping Go installation and all compilation")
|
||||
// Install Go toolchain (downloads from go.dev if needed)
|
||||
if err := ps.binaryInstaller.InstallGo(); err != nil {
|
||||
return fmt.Errorf("failed to install Go: %w", err)
|
||||
}
|
||||
|
||||
// Verify required DeBros binaries exist
|
||||
binDir := filepath.Join(ps.oramaHome, "bin")
|
||||
requiredBins := []string{"orama-node", "gateway", "orama", "identity"}
|
||||
for _, bin := range requiredBins {
|
||||
binPath := filepath.Join(binDir, bin)
|
||||
if _, err := os.Stat(binPath); os.IsNotExist(err) {
|
||||
return fmt.Errorf("--pre-built: required binary not found at %s (run 'make build-linux' locally and copy to VPS)", binPath)
|
||||
}
|
||||
ps.logf(" ✓ Found %s", binPath)
|
||||
if err := ps.binaryInstaller.InstallOlric(); err != nil {
|
||||
ps.logf(" ⚠️ Olric install warning: %v", err)
|
||||
}
|
||||
|
||||
// Install DeBros binaries (source must be at /home/debros/src via SCP)
|
||||
if err := ps.binaryInstaller.InstallDeBrosBinaries(ps.oramaHome); err != nil {
|
||||
return fmt.Errorf("failed to install DeBros binaries: %w", err)
|
||||
}
|
||||
|
||||
// Install CoreDNS only for nameserver nodes
|
||||
if ps.isNameserver {
|
||||
if err := ps.binaryInstaller.InstallCoreDNS(); err != nil {
|
||||
ps.logf(" ⚠️ CoreDNS install warning: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Grant CAP_NET_BIND_SERVICE to orama-node
|
||||
nodeBinary := filepath.Join(binDir, "orama-node")
|
||||
if err := exec.Command("setcap", "cap_net_bind_service=+ep", nodeBinary).Run(); err != nil {
|
||||
ps.logf(" ⚠️ Warning: failed to setcap on orama-node: %v", err)
|
||||
}
|
||||
|
||||
// Verify Olric
|
||||
if _, err := exec.LookPath("olric-server"); err != nil {
|
||||
// Check if it's in the bin dir
|
||||
olricPath := filepath.Join(binDir, "olric-server")
|
||||
if _, err := os.Stat(olricPath); os.IsNotExist(err) {
|
||||
return fmt.Errorf("--pre-built: olric-server not found in PATH or %s", binDir)
|
||||
}
|
||||
// Copy to /usr/local/bin
|
||||
if data, err := os.ReadFile(olricPath); err == nil {
|
||||
os.WriteFile("/usr/local/bin/olric-server", data, 0755)
|
||||
}
|
||||
ps.logf(" ✓ Found %s", olricPath)
|
||||
} else {
|
||||
ps.logf(" ✓ olric-server already in PATH")
|
||||
}
|
||||
|
||||
// Verify CoreDNS and Caddy if nameserver
|
||||
if ps.isNameserver {
|
||||
if _, err := os.Stat("/usr/local/bin/coredns"); os.IsNotExist(err) {
|
||||
return fmt.Errorf("--pre-built: coredns not found at /usr/local/bin/coredns")
|
||||
}
|
||||
ps.logf(" ✓ Found /usr/local/bin/coredns")
|
||||
|
||||
if _, err := os.Stat("/usr/bin/caddy"); os.IsNotExist(err) {
|
||||
return fmt.Errorf("--pre-built: caddy not found at /usr/bin/caddy")
|
||||
}
|
||||
ps.logf(" ✓ Found /usr/bin/caddy")
|
||||
|
||||
// Grant CAP_NET_BIND_SERVICE to caddy
|
||||
if err := exec.Command("setcap", "cap_net_bind_service=+ep", "/usr/bin/caddy").Run(); err != nil {
|
||||
ps.logf(" ⚠️ Warning: failed to setcap on caddy: %v", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Normal mode: install Go and build everything
|
||||
if err := ps.binaryInstaller.InstallGo(); err != nil {
|
||||
return fmt.Errorf("failed to install Go: %w", err)
|
||||
}
|
||||
|
||||
if err := ps.binaryInstaller.InstallOlric(); err != nil {
|
||||
ps.logf(" ⚠️ Olric install warning: %v", err)
|
||||
}
|
||||
|
||||
// Install DeBros binaries (must be done before CoreDNS since we need the RQLite plugin source)
|
||||
if err := ps.binaryInstaller.InstallDeBrosBinaries(ps.branch, ps.oramaHome, ps.skipRepoUpdate); err != nil {
|
||||
return fmt.Errorf("failed to install DeBros binaries: %w", err)
|
||||
}
|
||||
|
||||
// Install CoreDNS only for nameserver nodes
|
||||
if ps.isNameserver {
|
||||
if err := ps.binaryInstaller.InstallCoreDNS(); err != nil {
|
||||
ps.logf(" ⚠️ CoreDNS install warning: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Install Caddy on ALL nodes (any node may host namespaces and need TLS)
|
||||
if err := ps.binaryInstaller.InstallCaddy(); err != nil {
|
||||
ps.logf(" ⚠️ Caddy install warning: %v", err)
|
||||
}
|
||||
// Install Caddy on ALL nodes (any node may host namespaces and need TLS)
|
||||
if err := ps.binaryInstaller.InstallCaddy(); err != nil {
|
||||
ps.logf(" ⚠️ Caddy install warning: %v", err)
|
||||
}
|
||||
|
||||
// These are pre-built binary downloads (not Go compilation), always run them
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user