Skip to content

Commit

Permalink
Merge pull request #8 from nodetec/pterm-list
Browse files Browse the repository at this point in the history
feat: implement strfry relay
  • Loading branch information
jchiarulli authored Sep 12, 2024
2 parents ce80449 + ac3201b commit 498da9e
Show file tree
Hide file tree
Showing 15 changed files with 677 additions and 122 deletions.
52 changes: 44 additions & 8 deletions cmd/install.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package cmd

import (
"github.com/pterm/pterm"

"github.com/nodetec/relaywiz/pkg/manager"
"github.com/nodetec/relaywiz/pkg/network"
"github.com/nodetec/relaywiz/pkg/relay"
"github.com/nodetec/relaywiz/pkg/relays/khatru_pyramid"
"github.com/nodetec/relaywiz/pkg/relays/strfry"
"github.com/nodetec/relaywiz/pkg/ui"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
)

Expand All @@ -23,7 +23,23 @@ var installCmd = &cobra.Command{
pterm.Println(pterm.Yellow("Leave email empty if you don't want to receive notifications from Let's Encrypt about your SSL cert."))
pterm.Println()
ssl_email, _ := pterm.DefaultInteractiveTextInput.Show("Email address")
pubkey, _ := pterm.DefaultInteractiveTextInput.Show("Public key (hex not npub)")

pterm.Println()
// Supported relay options
options := []string{"Khatru Pyramid", "strfry"}

// Use PTerm's interactive select feature to present the options to the user and capture their selection
// The Show() method displays the options and waits for the user's input
selectedRelayOption, _ := pterm.DefaultInteractiveSelect.WithOptions(options).Show()

// Display the selected option to the user with a green color for emphasis
pterm.Info.Printfln("Selected option: %s", pterm.Green(selectedRelayOption))

var pubkey string
if selectedRelayOption == "Khatru Pyramid" {
pterm.Println()
pubkey, _ = pterm.DefaultInteractiveTextInput.Show("Public key (hex not npub)")
}

pterm.Println()
pterm.Println(pterm.Yellow("If you make a mistake, you can always re-run this installer."))
Expand All @@ -32,11 +48,19 @@ var installCmd = &cobra.Command{
// Step 1: Install necessary packages using APT
manager.AptInstallPackages()

if selectedRelayOption == "strfry" {
strfry.AptInstallDependencies()
}

// Step 2: Configure the firewall
network.ConfigureFirewall()

// Step 3: Configure Nginx for HTTP
network.ConfigureNginxHttp(relayDomain)
if selectedRelayOption == "Khatru Pyramid" {
khatru_pyramid.ConfigureNginxHttp(relayDomain)
} else if selectedRelayOption == "strfry" {
strfry.ConfigureNginxHttp(relayDomain)
}

// Step 4: Get SSL certificates
var shouldContinue = network.GetCertificates(relayDomain, ssl_email)
Expand All @@ -46,13 +70,25 @@ var installCmd = &cobra.Command{
}

// Step 5: Configure Nginx for HTTPS
network.ConfigureNginxHttps(relayDomain)
if selectedRelayOption == "Khatru Pyramid" {
khatru_pyramid.ConfigureNginxHttps(relayDomain)
} else if selectedRelayOption == "strfry" {
strfry.ConfigureNginxHttps(relayDomain)
}

// Step 6: Download and install the relay binary
relay.InstallRelayBinary()
if selectedRelayOption == "Khatru Pyramid" {
khatru_pyramid.InstallRelayBinary()
} else if selectedRelayOption == "strfry" {
strfry.InstallRelayBinary()
}

// Step 7: Set up the relay service
relay.SetupRelayService(relayDomain, pubkey)
if selectedRelayOption == "Khatru Pyramid" {
khatru_pyramid.SetupRelayService(relayDomain, pubkey)
} else if selectedRelayOption == "strfry" {
strfry.SetupRelayService(relayDomain)
}

pterm.Println()
pterm.Println(pterm.Magenta("The installation is complete."))
Expand Down
3 changes: 1 addition & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package cmd

import (
"os"

"github.com/spf13/cobra"
"os"
)

var rootCmd = &cobra.Command{
Expand Down
72 changes: 38 additions & 34 deletions pkg/manager/apt.go
Original file line number Diff line number Diff line change
@@ -1,52 +1,56 @@
package manager

import (
"os/exec"

"fmt"
"github.com/pterm/pterm"
"log"
"os/exec"
)

// Function to check if a command exists
func commandExists(command string) bool {
_, err := exec.LookPath(command)
return err == nil
// Function to check if a package is installed
func IsPackageInstalled(packageName string) bool {
out, err := exec.Command("dpkg-query", "-W", "-f='${Status}'", packageName).Output()

if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
errorCode := exitError.ExitCode()
// Package not found
if errorCode == 1 {
return false
} else {
log.Fatalf("Error checking if package is installed: %v", err)
}
}
}

status := string(out)

if status == "'unknown ok not-installed'" {
return false
} else if status == "'install ok installed'" {
return true
}

return false
}

// Function to install necessary packages
func AptInstallPackages() {
spinner, _ := pterm.DefaultSpinner.Start("Updating and installing packages...")
exec.Command("apt", "update", "-qq").Run()

// Check if nginx is installed, install if not
if commandExists("nginx") {
spinner.UpdateText("nginx is already installed.")
} else {
spinner.UpdateText("Installing nginx...")
exec.Command("apt", "install", "-y", "-qq", "nginx").Run()
}
exec.Command("apt", "update", "-qq").Run()

// Check if Certbot is installed, install if not
if commandExists("certbot") {
spinner.UpdateText("Certbot is already installed.")
} else {
spinner.UpdateText("Installing Certbot...")
exec.Command("apt", "install", "-y", "-qq", "certbot", "python3-certbot-nginx").Run()
}
packages := []string{"nginx", "certbot", "python3-certbot-nginx", "ufw", "fail2ban"}

// Check if ufw is installed, install if not
if commandExists("ufw") {
spinner.UpdateText("ufw is already installed.")
} else {
spinner.UpdateText("Installing ufw...")
exec.Command("apt", "install", "-y", "-qq", "ufw").Run()
// Check if package is installed, install if not
for _, p := range packages {
if IsPackageInstalled(p) {
spinner.UpdateText(fmt.Sprintf("%s is already installed.", p))
} else {
spinner.UpdateText(fmt.Sprintf("Installing %s...", p))
exec.Command("apt", "install", "-y", "-qq", p).Run()
}
}

spinner.Success("Packages updated and installed successfully.")
}

// Function to check if a package is installed
func isPackageInstalled(packageName string) bool {
cmd := exec.Command("dpkg", "-l", packageName)
err := cmd.Run()
return err == nil
}
11 changes: 4 additions & 7 deletions pkg/network/certbot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package network
import (
"fmt"
"github.com/nodetec/relaywiz/pkg/utils"
"github.com/pterm/pterm"
"log"
"os"
"os/exec"

"github.com/pterm/pterm"
)

// Function to get SSL certificates using Certbot
Expand All @@ -33,29 +32,27 @@ func GetCertificates(domainName, email string) bool {

spinner, _ := pterm.DefaultSpinner.Start("Checking SSL certificates...")

dirName := utils.GetDirectoryName(domainName)

// Check if certificates already exist
if utils.FileExists(fmt.Sprintf("/etc/letsencrypt/live/%s/fullchain.pem", domainName)) &&
utils.FileExists(fmt.Sprintf("/etc/letsencrypt/live/%s/privkey.pem", domainName)) {
spinner.Info("SSL certificates already exist.")
return true
}

err := os.MkdirAll(fmt.Sprintf("/var/www/%s/.well-known/acme-challenge/", dirName), 0755)
err := os.MkdirAll(fmt.Sprintf("/var/www/%s/.well-known/acme-challenge/", domainName), 0755)
if err != nil {
log.Fatalf("Error creating directories for Certbot: %v", err)
}

spinner.UpdateText("Obtaining SSL certificates...")
if email == "" {
cmd := exec.Command("certbot", "certonly", "--webroot", "-w", fmt.Sprintf("/var/www/%s", dirName), "-d", domainName, "--agree-tos", "--no-eff-email", "-q", "--register-unsafely-without-email")
cmd := exec.Command("certbot", "certonly", "--webroot", "-w", fmt.Sprintf("/var/www/%s", domainName), "-d", domainName, "--agree-tos", "--no-eff-email", "-q", "--register-unsafely-without-email")
err = cmd.Run()
if err != nil {
log.Fatalf("Certbot failed to obtain the certificate for %s: %v", domainName, err)
}
} else {
cmd := exec.Command("certbot", "certonly", "--webroot", "-w", fmt.Sprintf("/var/www/%s", dirName), "-d", domainName, "--email", email, "--agree-tos", "--no-eff-email", "-q")
cmd := exec.Command("certbot", "certonly", "--webroot", "-w", fmt.Sprintf("/var/www/%s", domainName), "-d", domainName, "--email", email, "--agree-tos", "--no-eff-email", "-q")
err = cmd.Run()
if err != nil {
log.Fatalf("Certbot failed to obtain the certificate for %s: %v", domainName, err)
Expand Down
3 changes: 1 addition & 2 deletions pkg/network/firewall.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package network

import (
"github.com/pterm/pterm"
"log"
"os/exec"

"github.com/pterm/pterm"
)

// Function to configure the firewall
Expand Down
31 changes: 14 additions & 17 deletions pkg/relay/install.go → pkg/relays/khatru_pyramid/install.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
package relay
package khatru_pyramid

import (
"github.com/pterm/pterm"
"io"
"log"
"net/http"
"os"
"path/filepath"

"github.com/pterm/pterm"
)

// URL of the binary to download
const downloadURL = "https://github.com/github-tijlxyz/khatru-pyramid/releases/download/v0.0.5/khatru-pyramid-v0.0.5-linux-amd64"

// Name of the binary after downloading
const binaryName = "nostr-relay-pyramid"
// Function to download and make the binary executable
func InstallRelayBinary() {
// URL of the binary to download
const downloadURL = "https://github.com/github-tijlxyz/khatru-pyramid/releases/download/v0.0.5/khatru-pyramid-v0.0.5-linux-amd64"

// Destination directory for the binary
const destDir = "/usr/local/bin"
// Name of the binary after downloading
const binaryName = "nostr-relay-khatru-pyramid"

// Data directory for the relay
const dataDir = "/var/lib/nostr-relay-pyramid"
// Destination directory for the binary
const destDir = "/usr/local/bin"

// Function to download and make the binary executable
func InstallRelayBinary() {
// Data directory for the relay
const dataDir = "/var/lib/nostr-relay-khatru-pyramid"

spinner, _ := pterm.DefaultSpinner.Start("Installing relay...")
spinner, _ := pterm.DefaultSpinner.Start("Installing Khatru Pyramid relay...")
// Ensure the data directory exists
err := os.MkdirAll(dataDir, 0755)
if err != nil {
Expand Down Expand Up @@ -75,6 +73,5 @@ func InstallRelayBinary() {
log.Fatalf("Error making file executable: %v", err)
}

spinner.Success("Relay installed successfully.")
spinner.Success("Khatru Pyramid relay installed successfully.")
}

Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
package network
package khatru_pyramid

import (
"fmt"
"github.com/nodetec/relaywiz/pkg/utils"
// "github.com/nodetec/relaywiz/pkg/utils"
"github.com/pterm/pterm"
"log"
"os"
"os/exec"

"github.com/pterm/pterm"
)

// Function to configure nginx for HTTP
func ConfigureNginxHttp(domainName string) {

spinner, _ := pterm.DefaultSpinner.Start("Configuring nginx for HTTP...")
dirName := utils.GetDirectoryName(domainName)

err := os.MkdirAll(fmt.Sprintf("/var/www/%s/.well-known/acme-challenge/", dirName), 0755)
err := os.MkdirAll(fmt.Sprintf("/var/www/%s/.well-known/acme-challenge/", domainName), 0755)
if err != nil {
log.Fatalf("Error creating directories: %v", err)
}

err = os.Remove("/etc/nginx/conf.d/nostr_relay.conf")
const configFile = "nostr_relay_khatru_pyramid.conf"

err = os.Remove(fmt.Sprintf("/etc/nginx/conf.d/%s", configFile))
if err != nil && !os.IsNotExist(err) {
log.Fatalf("Error removing existing nginx configuration: %v", err)
}

configContent := fmt.Sprintf(`map $http_upgrade $connection_upgrade {
var configContent string

configContent = fmt.Sprintf(`map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Expand Down Expand Up @@ -55,9 +56,9 @@ server {
proxy_set_header X-Forwarded-For $remote_addr;
}
}
`, domainName, domainName, dirName)
`, domainName, domainName, domainName)

err = os.WriteFile("/etc/nginx/conf.d/nostr_relay.conf", []byte(configContent), 0644)
err = os.WriteFile(fmt.Sprintf("/etc/nginx/conf.d/%s", configFile), []byte(configContent), 0644)
if err != nil {
log.Fatalf("Error writing nginx configuration: %v", err)
}
Expand All @@ -68,5 +69,4 @@ server {
}

spinner.Success("Nginx configured for HTTP")

}
Loading

0 comments on commit 498da9e

Please sign in to comment.