Add 'dis' component
This commit adds a new 'dis' component to the distillery that serves a list of all known instances for the moment.
This commit is contained in:
parent
35bb95c5ca
commit
4b357476a3
43 changed files with 434 additions and 167 deletions
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/env"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/targz"
|
"github.com/FAU-CDI/wisski-distillery/internal/targz"
|
||||||
|
|
@ -24,7 +25,7 @@ type backup struct {
|
||||||
|
|
||||||
func (backup) Description() wisski_distillery.Description {
|
func (backup) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "backup",
|
Command: "backup",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/execx"
|
"github.com/FAU-CDI/wisski-distillery/internal/execx"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
)
|
)
|
||||||
|
|
@ -19,7 +19,7 @@ type blindUpdate struct {
|
||||||
|
|
||||||
func (blindUpdate) Description() wisski_distillery.Description {
|
func (blindUpdate) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "blind_update",
|
Command: "blind_update",
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/distillery"
|
"github.com/FAU-CDI/wisski-distillery/distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
|
||||||
cfg "github.com/FAU-CDI/wisski-distillery/internal/config"
|
cfg "github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/hostname"
|
"github.com/FAU-CDI/wisski-distillery/internal/hostname"
|
||||||
|
|
@ -26,7 +26,7 @@ type bootstrap struct {
|
||||||
|
|
||||||
func (bootstrap) Description() wisski_distillery.Description {
|
func (bootstrap) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: false,
|
NeedsDistillery: false,
|
||||||
},
|
},
|
||||||
Command: "bootstrap",
|
Command: "bootstrap",
|
||||||
|
|
@ -74,7 +74,7 @@ func (bs bootstrap) Run(context wisski_distillery.Context) error {
|
||||||
|
|
||||||
// check that we didn't get a different base directory
|
// check that we didn't get a different base directory
|
||||||
{
|
{
|
||||||
got, err := env.ReadBaseDirectory()
|
got, err := core.ReadBaseDirectory()
|
||||||
if err == nil && got != "" && got != root {
|
if err == nil && got != "" && got != root {
|
||||||
return errBootstrapDifferent.WithMessageF(got)
|
return errBootstrapDifferent.WithMessageF(got)
|
||||||
}
|
}
|
||||||
|
|
@ -85,15 +85,15 @@ func (bs bootstrap) Run(context wisski_distillery.Context) error {
|
||||||
if err := os.MkdirAll(root, fs.ModeDir); err != nil {
|
if err := os.MkdirAll(root, fs.ModeDir); err != nil {
|
||||||
return errBootstrapFailedToCreateDirectory.WithMessageF(root)
|
return errBootstrapFailedToCreateDirectory.WithMessageF(root)
|
||||||
}
|
}
|
||||||
if err := env.WriteBaseDirectory(root); err != nil {
|
if err := core.WriteBaseDirectory(root); err != nil {
|
||||||
return errBootstrapFailedToSaveDirectory.WithMessageF(root)
|
return errBootstrapFailedToSaveDirectory.WithMessageF(root)
|
||||||
}
|
}
|
||||||
context.Println(root)
|
context.Println(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Read these from the command line?
|
// TODO: Should we read an existing configuration file?
|
||||||
wdcliPath := filepath.Join(root, env.Executable)
|
wdcliPath := filepath.Join(root, core.Executable)
|
||||||
envPath := filepath.Join(root, env.ConfigFile)
|
envPath := filepath.Join(root, core.ConfigFile)
|
||||||
domain := bs.Hostname
|
domain := bs.Hostname
|
||||||
if domain == "" {
|
if domain == "" {
|
||||||
domain = hostname.FQDN()
|
domain = hostname.FQDN()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is the configuration command
|
// Config is the configuration command
|
||||||
|
|
@ -13,7 +13,7 @@ type config struct {
|
||||||
|
|
||||||
func (s config) Description() wisski_distillery.Description {
|
func (s config) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "config",
|
Command: "config",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
)
|
)
|
||||||
|
|
@ -18,7 +18,7 @@ type cron struct {
|
||||||
|
|
||||||
func (cron) Description() wisski_distillery.Description {
|
func (cron) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "cron",
|
Command: "cron",
|
||||||
|
|
|
||||||
43
cmd/dis_server.go
Normal file
43
cmd/dis_server.go
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DisServer is the 'dis_server' command
|
||||||
|
var DisServer wisski_distillery.Command = disServer{}
|
||||||
|
|
||||||
|
type disServer struct {
|
||||||
|
Prefix string `short:"p" long:"prefix" description:"prefix to listen under"`
|
||||||
|
Bind string `short:"b" long:"bind" description:"address to listen on" default:"127.0.0.1:8888"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (disServer) Description() wisski_distillery.Description {
|
||||||
|
return wisski_distillery.Description{
|
||||||
|
Requirements: core.Requirements{
|
||||||
|
NeedsDistillery: true,
|
||||||
|
},
|
||||||
|
Command: "dis_server",
|
||||||
|
Description: "Starts a server with information about this distillery",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var errServerListen = exit.Error{
|
||||||
|
ExitCode: exit.ExitGeneric,
|
||||||
|
Message: "Unable to listen",
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s disServer) Run(context wisski_distillery.Context) error {
|
||||||
|
server := context.Environment.Server()
|
||||||
|
|
||||||
|
context.Printf("Listening on %s\n", s.Bind)
|
||||||
|
err := http.ListenAndServe(s.Bind, http.StripPrefix(s.Prefix, server))
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errServerListen.Wrap(err)
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Info is then 'info' command
|
// Info is then 'info' command
|
||||||
|
|
@ -16,7 +16,7 @@ type info struct {
|
||||||
|
|
||||||
func (info) Description() wisski_distillery.Description {
|
func (info) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "info",
|
Command: "info",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/legal"
|
"github.com/FAU-CDI/wisski-distillery/internal/legal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -15,7 +15,7 @@ type license struct{}
|
||||||
|
|
||||||
func (license) Description() wisski_distillery.Description {
|
func (license) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: false,
|
NeedsDistillery: false,
|
||||||
},
|
},
|
||||||
Command: "license",
|
Command: "license",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ls is the 'ls' command
|
// Ls is the 'ls' command
|
||||||
|
|
@ -16,7 +16,7 @@ type ls struct {
|
||||||
|
|
||||||
func (ls) Description() wisski_distillery.Description {
|
func (ls) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "ls",
|
Command: "ls",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/sqle"
|
"github.com/FAU-CDI/wisski-distillery/internal/sqle"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/parser"
|
"github.com/tkw1536/goprogram/parser"
|
||||||
|
|
@ -17,7 +17,7 @@ type makeMysqlAccount struct{}
|
||||||
|
|
||||||
func (makeMysqlAccount) Description() wisski_distillery.Description {
|
func (makeMysqlAccount) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
ParserConfig: parser.Config{
|
ParserConfig: parser.Config{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ type monday struct {
|
||||||
|
|
||||||
func (monday) Description() wisski_distillery.Description {
|
func (monday) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "monday",
|
Command: "monday",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/parser"
|
"github.com/tkw1536/goprogram/parser"
|
||||||
)
|
)
|
||||||
|
|
@ -20,7 +20,7 @@ type mysql struct {
|
||||||
|
|
||||||
func (mysql) Description() wisski_distillery.Description {
|
func (mysql) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
ParserConfig: parser.Config{
|
ParserConfig: parser.Config{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
|
@ -19,7 +19,7 @@ type provision struct {
|
||||||
|
|
||||||
func (provision) Description() wisski_distillery.Description {
|
func (provision) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "provision",
|
Command: "provision",
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/env"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
|
@ -21,7 +22,7 @@ type purge struct {
|
||||||
|
|
||||||
func (purge) Description() wisski_distillery.Description {
|
func (purge) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "purge",
|
Command: "purge",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
|
@ -19,7 +19,7 @@ type rebuild struct {
|
||||||
|
|
||||||
func (rebuild) Description() wisski_distillery.Description {
|
func (rebuild) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "rebuild",
|
Command: "rebuild",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
||||||
|
|
@ -20,7 +20,7 @@ type reserve struct {
|
||||||
|
|
||||||
func (reserve) Description() wisski_distillery.Description {
|
func (reserve) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "reserve",
|
Command: "reserve",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/parser"
|
"github.com/tkw1536/goprogram/parser"
|
||||||
)
|
)
|
||||||
|
|
@ -21,7 +21,7 @@ type shell struct {
|
||||||
|
|
||||||
func (shell) Description() wisski_distillery.Description {
|
func (shell) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
ParserConfig: parser.Config{
|
ParserConfig: parser.Config{
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/env"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/targz"
|
"github.com/FAU-CDI/wisski-distillery/internal/targz"
|
||||||
|
|
@ -26,7 +27,7 @@ type snapshot struct {
|
||||||
|
|
||||||
func (snapshot) Description() wisski_distillery.Description {
|
func (snapshot) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "snapshot",
|
Command: "snapshot",
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/distillery"
|
"github.com/FAU-CDI/wisski-distillery/distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/execx"
|
"github.com/FAU-CDI/wisski-distillery/internal/execx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
||||||
|
|
@ -26,7 +26,7 @@ type systemupdate struct {
|
||||||
|
|
||||||
func (systemupdate) Description() wisski_distillery.Description {
|
func (systemupdate) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
ParserConfig: parser.Config{
|
ParserConfig: parser.Config{
|
||||||
|
|
@ -124,6 +124,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error {
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
for _, component := range dis.Components() {
|
for _, component := range dis.Components() {
|
||||||
stack := component.Stack()
|
stack := component.Stack()
|
||||||
|
ctx := component.Context(ctx)
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
return stack.Install(context.IOStream, ctx)
|
return stack.Install(context.IOStream, ctx)
|
||||||
}, context.IOStream, "Installing docker stack %q", component.Name()); err != nil {
|
}, context.IOStream, "Installing docker stack %q", component.Name()); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
"github.com/FAU-CDI/wisski-distillery/internal/logging"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
)
|
)
|
||||||
|
|
@ -17,7 +17,7 @@ type updateprefixconfig struct{}
|
||||||
|
|
||||||
func (updateprefixconfig) Description() wisski_distillery.Description {
|
func (updateprefixconfig) Description() wisski_distillery.Description {
|
||||||
return wisski_distillery.Description{
|
return wisski_distillery.Description{
|
||||||
Requirements: env.Requirements{
|
Requirements: core.Requirements{
|
||||||
NeedsDistillery: true,
|
NeedsDistillery: true,
|
||||||
},
|
},
|
||||||
Command: "update_prefix_config",
|
Command: "update_prefix_config",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/cmd"
|
"github.com/FAU-CDI/wisski-distillery/cmd"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
)
|
)
|
||||||
|
|
@ -48,6 +48,9 @@ func init() {
|
||||||
wdcli.Register(cmd.Backup)
|
wdcli.Register(cmd.Backup)
|
||||||
wdcli.Register(cmd.Cron)
|
wdcli.Register(cmd.Cron)
|
||||||
wdcli.Register(cmd.Monday)
|
wdcli.Register(cmd.Monday)
|
||||||
|
|
||||||
|
// servers
|
||||||
|
wdcli.Register(cmd.DisServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// an error when no arguments are provided.
|
// an error when no arguments are provided.
|
||||||
|
|
@ -83,7 +86,7 @@ func main() {
|
||||||
// creat a new set of parameters
|
// creat a new set of parameters
|
||||||
// and then use them to execute the main command
|
// and then use them to execute the main command
|
||||||
err := func() error {
|
err := func() error {
|
||||||
params, err := env.ParamsFromEnv()
|
params, err := core.ParamsFromEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return streams.Die(err)
|
return streams.Die(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
core/core.go
Normal file
14
core/core.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Package core implements the core of the WissKI Distillery and the wdcli executable.
|
||||||
|
// It does not depend on any other packages.
|
||||||
|
package core
|
||||||
|
|
||||||
|
// BaseDirectoryDefault is the default deploy directory to load the distillery from.
|
||||||
|
const BaseDirectoryDefault = "/var/www/deploy"
|
||||||
|
|
||||||
|
// Executable is the name of the 'wdcli' executable.
|
||||||
|
// It should be located inside the deployment directory.
|
||||||
|
const Executable = "wdcli"
|
||||||
|
|
||||||
|
// Config file is the name of the config file.
|
||||||
|
// It should be located inside the deployment directory.
|
||||||
|
const ConfigFile = ".env"
|
||||||
8
core/flags.go
Normal file
8
core/flags.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
// Flags are global flags for the wdcli executable
|
||||||
|
type Flags struct {
|
||||||
|
ConfigPath string `short:"c" long:"config" description:"Path to distillery configuration file"`
|
||||||
|
|
||||||
|
InternalInDocker bool `long:"internal-in-docker" description:"Internal Flag to signal the shell that it is running inside a docker stack belonging to the distillery"`
|
||||||
|
}
|
||||||
71
core/meta.go
Normal file
71
core/meta.go
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MetaConfigFile is the path to a configuration file that contains the path to the last used wdcli executable.
|
||||||
|
// It is expected to be in the current user's home directory.
|
||||||
|
//
|
||||||
|
// You probably want to use [MetaConfigPath] instead.
|
||||||
|
//
|
||||||
|
// It should contain the path to a deployment directory.
|
||||||
|
const MetaConfigFile = "." + Executable
|
||||||
|
|
||||||
|
// MetaConfigPath returns the full path to the MetaConfigPath()
|
||||||
|
func MetaConfigPath() (string, error) {
|
||||||
|
// find the current user
|
||||||
|
usr, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(usr.HomeDir, MetaConfigFile), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var errReadBaseDirectoryEmpty = errors.New("ReadBaseDirectory: Directory is empty")
|
||||||
|
|
||||||
|
// ReadBaseDirectory reads the base deployment directory from the environment.
|
||||||
|
// Use [ParamsFromEnv] to initialize parameters completely.
|
||||||
|
//
|
||||||
|
// It does not perform any reading of files.
|
||||||
|
func ReadBaseDirectory() (value string, err error) {
|
||||||
|
// get the path!
|
||||||
|
path, err := MetaConfigPath()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the meta config file!
|
||||||
|
contents, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// and trim the spaces!
|
||||||
|
value = strings.TrimSpace(string(contents))
|
||||||
|
|
||||||
|
// check that it is actually set!
|
||||||
|
if len(value) == 0 {
|
||||||
|
return "", errReadBaseDirectoryEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
// and return it!
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteBaseDirectory writes the base directory to the environment, or returns an error
|
||||||
|
func WriteBaseDirectory(dir string) error {
|
||||||
|
// get the path!
|
||||||
|
path, err := MetaConfigPath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// just put the directory inside it!
|
||||||
|
return os.WriteFile(path, []byte(dir), fs.ModePerm)
|
||||||
|
}
|
||||||
31
core/params.go
Normal file
31
core/params.go
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Params are used to initialize the excutable.
|
||||||
|
type Params struct {
|
||||||
|
ConfigPath string // ConfigPath is the path to the configuration file for the distillery
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamsFromEnv creates a new set of parameters from the environment.
|
||||||
|
// Uses [ReadBaseDirectory] or falls back to [BaseDirectoryDefault].
|
||||||
|
func ParamsFromEnv() (params Params, err error) {
|
||||||
|
|
||||||
|
// try to read the base directory!
|
||||||
|
value, err := ReadBaseDirectory()
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
params.ConfigPath = BaseDirectoryDefault
|
||||||
|
case err == nil:
|
||||||
|
params.ConfigPath = value
|
||||||
|
default:
|
||||||
|
return params, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// and add the configuration file name to it!
|
||||||
|
params.ConfigPath = filepath.Join(params.ConfigPath, ConfigFile)
|
||||||
|
return params, nil
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
package env
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tkw1536/goprogram"
|
"github.com/tkw1536/goprogram"
|
||||||
"github.com/tkw1536/goprogram/meta"
|
"github.com/tkw1536/goprogram/meta"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Requirements are requirements for the WissKI Distillery
|
||||||
type Requirements struct {
|
type Requirements struct {
|
||||||
// Do we need an installed distillery?
|
// Do we need an installed distillery?
|
||||||
NeedsDistillery bool
|
NeedsDistillery bool
|
||||||
|
|
@ -13,13 +14,13 @@ type Requirements struct {
|
||||||
// AllowsFlag checks if the provided flag may be passed to fullfill this requirement
|
// AllowsFlag checks if the provided flag may be passed to fullfill this requirement
|
||||||
// By default it is used only for help page generation, and may be inaccurate.
|
// By default it is used only for help page generation, and may be inaccurate.
|
||||||
func (r Requirements) AllowsFlag(flag meta.Flag) bool {
|
func (r Requirements) AllowsFlag(flag meta.Flag) bool {
|
||||||
return true
|
return r.NeedsDistillery
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates if this requirement is fullfilled for the provided global flags.
|
// Validate validates if this requirement is fullfilled for the provided global flags.
|
||||||
// It should return either nil, or an error of type exit.Error.
|
// It should return either nil, or an error of type exit.Error.
|
||||||
//
|
//
|
||||||
// Validate does not take into account AllowsOption, see ValidateAllowedOptions.
|
// Validate does not take into account AllowsOption, see ValidateAllowedOptions.
|
||||||
func (r Requirements) Validate(arguments goprogram.Arguments[struct{}]) error {
|
func (r Requirements) Validate(arguments goprogram.Arguments[Flags]) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
5
distillery/resources/compose/dis/Dockerfile
Normal file
5
distillery/resources/compose/dis/Dockerfile
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
FROM docker.io/library/alpine
|
||||||
|
|
||||||
|
COPY wdcli /wdcli
|
||||||
|
EXPOSE 8888
|
||||||
|
CMD ["/wdcli","--internal-in-docker","--config","${CONFIG_PATH}","dis_server","--bind","0.0.0.0:8888"]
|
||||||
28
distillery/resources/compose/dis/docker-compose.yml
Normal file
28
distillery/resources/compose/dis/docker-compose.yml
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
version: "3.7"
|
||||||
|
|
||||||
|
services:
|
||||||
|
wdresolve:
|
||||||
|
build: .
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
# port and hostname for this image to use
|
||||||
|
VIRTUAL_HOST: ${VIRTUAL_HOST}
|
||||||
|
VIRTUAL_PORT: 8888
|
||||||
|
VIRTUAL_PATH: /dis/
|
||||||
|
|
||||||
|
CONFIG_PATH: ${CONFIG_PATH}
|
||||||
|
|
||||||
|
# optional letsencrypt email
|
||||||
|
LETSENCRYPT_HOST: ${LETSENCRYPT_HOST}
|
||||||
|
LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- "${CONFIG_PATH}:${CONFIG_PATH}:ro"
|
||||||
|
- "${DEPLOY_ROOT}:${DEPLOY_ROOT}:ro"
|
||||||
|
- "${GLOBAL_AUTHORIZED_KEYS_FILE}:${GLOBAL_AUTHORIZED_KEYS_FILE}:ro"
|
||||||
|
- "${SELF_OVERRIDES_FILE}:${SELF_OVERRIDES_FILE}:ro"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
name: distillery
|
||||||
|
external: true
|
||||||
9
distillery/resources/templates/docker-env/dis
Normal file
9
distillery/resources/templates/docker-env/dis
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
VIRTUAL_HOST=${VIRTUAL_HOST}
|
||||||
|
|
||||||
|
LETSENCRYPT_HOST=${LETSENCRYPT_HOST}
|
||||||
|
LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
|
||||||
|
|
||||||
|
CONFIG_PATH=${CONFIG_PATH}
|
||||||
|
DEPLOY_ROOT=${DEPLOY_ROOT}
|
||||||
|
GLOBAL_AUTHORIZED_KEYS_FILE=${GLOBAL_AUTHORIZED_KEYS_FILE}
|
||||||
|
SELF_OVERRIDES_FILE=${SELF_OVERRIDES_FILE}
|
||||||
6
env/component.go
vendored
6
env/component.go
vendored
|
|
@ -10,11 +10,12 @@ import (
|
||||||
|
|
||||||
// Stacks returns the Stacks of this distillery
|
// Stacks returns the Stacks of this distillery
|
||||||
func (dis *Distillery) Components() []Component {
|
func (dis *Distillery) Components() []Component {
|
||||||
// TODO: Do we want to cache these stacks?
|
// TODO: Do we want to cache these components?
|
||||||
return []Component{
|
return []Component{
|
||||||
dis.Web(),
|
dis.Web(),
|
||||||
dis.Self(),
|
dis.Self(),
|
||||||
dis.Resolver(),
|
dis.Resolver(),
|
||||||
|
dis.Dis(),
|
||||||
dis.SSH(),
|
dis.SSH(),
|
||||||
dis.Triplestore(),
|
dis.Triplestore(),
|
||||||
dis.SQL(),
|
dis.SQL(),
|
||||||
|
|
@ -25,7 +26,8 @@ func (dis *Distillery) Components() []Component {
|
||||||
type Component interface {
|
type Component interface {
|
||||||
Name() string // Name is the name of this component
|
Name() string // Name is the name of this component
|
||||||
|
|
||||||
Stack() stack.Installable // Stack returns the installable stack representing this component
|
Stack() stack.Installable // Stack returns the installable stack representing this component
|
||||||
|
Context(parent stack.InstallationContext) stack.InstallationContext // context for installation
|
||||||
|
|
||||||
Path() string // Path returns the path to this component
|
Path() string // Path returns the path to this component
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
env/component_dis.go
vendored
Normal file
47
env/component_dis.go
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
package env
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/internal/stack"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DisComponent represents the 'dis' layer belonging to a distillery
|
||||||
|
type DisComponent struct {
|
||||||
|
dis *Distillery
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dis returns the DisComponent belonging to this distillery
|
||||||
|
func (dis *Distillery) Dis() DisComponent {
|
||||||
|
return DisComponent{dis: dis}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (DisComponent) Name() string {
|
||||||
|
return "dis"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dis DisComponent) Stack() stack.Installable {
|
||||||
|
return dis.dis.makeComponentStack(dis, stack.Installable{
|
||||||
|
EnvFileContext: map[string]string{
|
||||||
|
"VIRTUAL_HOST": dis.dis.DefaultVirtualHost(),
|
||||||
|
"LETSENCRYPT_HOST": dis.dis.DefaultLetsencryptHost(),
|
||||||
|
"LETSENCRYPT_EMAIL": dis.dis.Config.CertbotEmail,
|
||||||
|
|
||||||
|
"CONFIG_PATH": dis.dis.Config.ConfigPath,
|
||||||
|
"DEPLOY_ROOT": dis.dis.Config.DeployRoot,
|
||||||
|
|
||||||
|
"GLOBAL_AUTHORIZED_KEYS_FILE": dis.dis.Config.GlobalAuthorizedKeysFile,
|
||||||
|
"SELF_OVERRIDES_FILE": dis.dis.Config.SelfOverridesFile,
|
||||||
|
},
|
||||||
|
CopyContextFiles: []string{core.Executable},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dis DisComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return stack.InstallationContext{
|
||||||
|
core.Executable: dis.dis.CurrentExecutable(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dis DisComponent) Path() string {
|
||||||
|
return dis.Stack().Dir
|
||||||
|
}
|
||||||
4
env/component_resolver.go
vendored
4
env/component_resolver.go
vendored
|
|
@ -44,6 +44,10 @@ func (resolver ResolverComponent) Stack() stack.Installable {
|
||||||
return stack
|
return stack
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ResolverComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
func (resolver ResolverComponent) Path() string {
|
func (resolver ResolverComponent) Path() string {
|
||||||
return resolver.Stack().Dir
|
return resolver.Stack().Dir
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
env/component_self.go
vendored
4
env/component_self.go
vendored
|
|
@ -16,6 +16,10 @@ func (SelfComponent) Name() string {
|
||||||
return "self"
|
return "self"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (SelfComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
func (sc SelfComponent) Stack() stack.Installable {
|
func (sc SelfComponent) Stack() stack.Installable {
|
||||||
TARGET := "https://github.com/FAU-CDI/wisski-distillery"
|
TARGET := "https://github.com/FAU-CDI/wisski-distillery"
|
||||||
if sc.dis.Config.SelfRedirect != nil {
|
if sc.dis.Config.SelfRedirect != nil {
|
||||||
|
|
|
||||||
9
env/component_sql.go
vendored
9
env/component_sql.go
vendored
|
|
@ -20,6 +20,8 @@ import (
|
||||||
|
|
||||||
// SQLComponent represents the 'sql' layer belonging to a distillery
|
// SQLComponent represents the 'sql' layer belonging to a distillery
|
||||||
type SQLComponent struct {
|
type SQLComponent struct {
|
||||||
|
ServerURL string
|
||||||
|
|
||||||
PollInterval time.Duration // Duration to wait for during wait
|
PollInterval time.Duration // Duration to wait for during wait
|
||||||
|
|
||||||
dis *Distillery
|
dis *Distillery
|
||||||
|
|
@ -28,6 +30,7 @@ type SQLComponent struct {
|
||||||
// SSH returns the SSHComponent belonging to this distillery
|
// SSH returns the SSHComponent belonging to this distillery
|
||||||
func (dis *Distillery) SQL() SQLComponent {
|
func (dis *Distillery) SQL() SQLComponent {
|
||||||
return SQLComponent{
|
return SQLComponent{
|
||||||
|
ServerURL: dis.Upstream.SQL,
|
||||||
PollInterval: time.Second,
|
PollInterval: time.Second,
|
||||||
|
|
||||||
dis: dis,
|
dis: dis,
|
||||||
|
|
@ -38,6 +41,10 @@ func (SQLComponent) Name() string {
|
||||||
return "sql"
|
return "sql"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (SQLComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
// Stack returns the docker stack that handles the sql database.
|
// Stack returns the docker stack that handles the sql database.
|
||||||
func (sql SQLComponent) Stack() stack.Installable {
|
func (sql SQLComponent) Stack() stack.Installable {
|
||||||
return sql.dis.makeComponentStack(sql, stack.Installable{
|
return sql.dis.makeComponentStack(sql, stack.Installable{
|
||||||
|
|
@ -56,7 +63,7 @@ func (sql SQLComponent) Path() string {
|
||||||
// sqlOpen opens a new sql connection to the provided database using the administrative credentials
|
// sqlOpen opens a new sql connection to the provided database using the administrative credentials
|
||||||
func (sql SQLComponent) openDatabase(database string, config *gorm.Config) (*gorm.DB, error) {
|
func (sql SQLComponent) openDatabase(database string, config *gorm.Config) (*gorm.DB, error) {
|
||||||
cfg := mysql.Config{
|
cfg := mysql.Config{
|
||||||
DSN: fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local", sql.dis.Config.MysqlAdminUser, sql.dis.Config.MysqlAdminPassword, "127.0.0.1:3306", database),
|
DSN: fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local", sql.dis.Config.MysqlAdminUser, sql.dis.Config.MysqlAdminPassword, sql.ServerURL, database),
|
||||||
DefaultStringSize: 256,
|
DefaultStringSize: 256,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
4
env/component_ssh.go
vendored
4
env/component_ssh.go
vendored
|
|
@ -20,6 +20,10 @@ func (ssh SSHComponent) Stack() stack.Installable {
|
||||||
return ssh.dis.makeComponentStack(ssh, stack.Installable{})
|
return ssh.dis.makeComponentStack(ssh, stack.Installable{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (SSHComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
func (ssh SSHComponent) Path() string {
|
func (ssh SSHComponent) Path() string {
|
||||||
return ssh.Stack().Dir
|
return ssh.Stack().Dir
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
env/component_triplestore.go
vendored
6
env/component_triplestore.go
vendored
|
|
@ -32,7 +32,7 @@ type TriplestoreComponent struct {
|
||||||
// Triplestore returns the TriplestoreComponent belonging to this distillery
|
// Triplestore returns the TriplestoreComponent belonging to this distillery
|
||||||
func (dis *Distillery) Triplestore() TriplestoreComponent {
|
func (dis *Distillery) Triplestore() TriplestoreComponent {
|
||||||
return TriplestoreComponent{
|
return TriplestoreComponent{
|
||||||
BaseURL: "http://127.0.0.1:7200",
|
BaseURL: "http://" + dis.Upstream.Triplestore,
|
||||||
PollInterval: time.Second,
|
PollInterval: time.Second,
|
||||||
|
|
||||||
dis: dis,
|
dis: dis,
|
||||||
|
|
@ -43,6 +43,10 @@ func (TriplestoreComponent) Name() string {
|
||||||
return "triplestore"
|
return "triplestore"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (TriplestoreComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
// Stack returns the installable Triplestore stack
|
// Stack returns the installable Triplestore stack
|
||||||
func (ts TriplestoreComponent) Stack() stack.Installable {
|
func (ts TriplestoreComponent) Stack() stack.Installable {
|
||||||
return ts.dis.makeComponentStack(ts, stack.Installable{
|
return ts.dis.makeComponentStack(ts, stack.Installable{
|
||||||
|
|
|
||||||
4
env/component_web.go
vendored
4
env/component_web.go
vendored
|
|
@ -24,6 +24,10 @@ func (web WebComponent) Stack() stack.Installable {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (WebComponent) Context(parent stack.InstallationContext) stack.InstallationContext {
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
|
||||||
func (web WebComponent) Path() string {
|
func (web WebComponent) Path() string {
|
||||||
return web.Stack().Dir
|
return web.Stack().Dir
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
env/constants.go
vendored
23
env/constants.go
vendored
|
|
@ -4,16 +4,13 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
"github.com/FAU-CDI/wisski-distillery/internal/fsx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Executable is the name of the 'wdcli' executable.
|
|
||||||
// It should be located inside the deployment directory.
|
|
||||||
const Executable = "wdcli"
|
|
||||||
|
|
||||||
// ExecutablePath returns the path to the executable of this distillery.
|
// ExecutablePath returns the path to the executable of this distillery.
|
||||||
func (dis *Distillery) ExecutablePath() string {
|
func (dis *Distillery) ExecutablePath() string {
|
||||||
return filepath.Join(dis.Config.DeployRoot, Executable)
|
return filepath.Join(dis.Config.DeployRoot, core.Executable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsingDistilleryExecutable checks if the current process
|
// UsingDistilleryExecutable checks if the current process
|
||||||
|
|
@ -25,12 +22,12 @@ func (dis *Distillery) UsingDistilleryExecutable() bool {
|
||||||
return fsx.SameFile(exe, dis.ExecutablePath())
|
return fsx.SameFile(exe, dis.ExecutablePath())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config file is the name of the config file.
|
// CurrentExecutable returns the path to the current executable being used.
|
||||||
// It should be located inside the deployment directory.
|
// When it does not exist, falls back to the default executable.
|
||||||
const ConfigFile = ".env"
|
func (dis *Distillery) CurrentExecutable() string {
|
||||||
|
exe, err := os.Executable()
|
||||||
// ConfigFilePath returns the path to the configuration file of this distillery.
|
if err != nil || !fsx.IsFile(exe) {
|
||||||
// TODO: This should be moved to the Config struct.
|
return dis.ExecutablePath()
|
||||||
func (dis *Distillery) ConfigFilePath() string {
|
}
|
||||||
return filepath.Join(dis.Config.DeployRoot, ConfigFile)
|
return exe
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
env/distillery.go
vendored
38
env/distillery.go
vendored
|
|
@ -5,13 +5,21 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Distillery represents a running instance for the distillery
|
// Distillery represents a running instance for the distillery
|
||||||
type Distillery struct {
|
type Distillery struct {
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
|
Upstream Upstream
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upstream are the upstream urls connecting to the various external components.
|
||||||
|
type Upstream struct {
|
||||||
|
SQL string
|
||||||
|
Triplestore string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dis Distillery) HTTPSEnabled() bool {
|
func (dis Distillery) HTTPSEnabled() bool {
|
||||||
|
|
@ -50,28 +58,44 @@ var errOpenConfig = exit.Error{
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDistillery creates a new distillery object from a set of parameters and requirements
|
// NewDistillery creates a new distillery object from a set of parameters and requirements
|
||||||
func NewDistillery(params Params, req Requirements) (env *Distillery, err error) {
|
func NewDistillery(params core.Params, flags core.Flags, req core.Requirements) (env *Distillery, err error) {
|
||||||
env = &Distillery{}
|
env = &Distillery{
|
||||||
|
Upstream: Upstream{
|
||||||
|
SQL: "127.0.0.1:3306",
|
||||||
|
Triplestore: "127.0.0.1:7200",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if flags.InternalInDocker {
|
||||||
|
env.Upstream.SQL = "sql:3306"
|
||||||
|
env.Upstream.Triplestore = "triplestore:7200"
|
||||||
|
}
|
||||||
|
|
||||||
// if we don't need to load the config, there is nothing to do
|
// if we don't need to load the config, there is nothing to do
|
||||||
if !req.NeedsDistillery {
|
if !req.NeedsDistillery {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is no no config file, return
|
// try to find the configuration file
|
||||||
cfg := params.ConfigFilePath()
|
cfg := flags.ConfigPath // command line flags first
|
||||||
|
if cfg == "" {
|
||||||
|
cfg = params.ConfigPath // then globally provided files
|
||||||
|
}
|
||||||
if cfg == "" {
|
if cfg == "" {
|
||||||
return nil, errNoConfigFile
|
return nil, errNoConfigFile
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Open(params.ConfigFilePath())
|
// open the config file!
|
||||||
|
f, err := os.Open(params.ConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errOpenConfig.WithMessageF(err)
|
return nil, errOpenConfig.WithMessageF(err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
// unmarshal the config
|
// unmarshal the config
|
||||||
env.Config = &config.Config{}
|
env.Config = &config.Config{
|
||||||
|
ConfigPath: cfg,
|
||||||
|
}
|
||||||
err = env.Config.Unmarshal(f)
|
err = env.Config.Unmarshal(f)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
92
env/params.go
vendored
92
env/params.go
vendored
|
|
@ -1,92 +0,0 @@
|
||||||
package env
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"os"
|
|
||||||
"os/user"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/tkw1536/goprogram/exit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Params are parameters used for initialization of the environment
|
|
||||||
type Params struct {
|
|
||||||
BaseDirectory string
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigFilePath returns the path to the configuration file
|
|
||||||
func (params Params) ConfigFilePath() string {
|
|
||||||
if params.BaseDirectory == "" {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return filepath.Join(params.BaseDirectory, ConfigFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
var errUnableToLoadParams = exit.Error{
|
|
||||||
ExitCode: exit.ExitGeneralArguments,
|
|
||||||
Message: "Unable to configure wdcli environment: %s",
|
|
||||||
}
|
|
||||||
|
|
||||||
const BaseDirectoryDefault = "/var/www/deploy"
|
|
||||||
|
|
||||||
// ParamsFromEnv creates a new set of parameters from the environment.
|
|
||||||
// There is no guarantee that the parameters are valid.
|
|
||||||
func ParamsFromEnv() (params Params, err error) {
|
|
||||||
// try to read the base directory
|
|
||||||
value, err := ReadBaseDirectory()
|
|
||||||
switch {
|
|
||||||
case os.IsNotExist(err):
|
|
||||||
params.BaseDirectory = BaseDirectoryDefault
|
|
||||||
case err == nil:
|
|
||||||
params.BaseDirectory = value
|
|
||||||
default:
|
|
||||||
return params, errUnableToLoadParams.WithMessageF(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return params, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var baseConfigFile = ".wdcli"
|
|
||||||
|
|
||||||
// ReadBaseDirectory reads the base directory from the environment, or an empty string
|
|
||||||
func ReadBaseDirectory() (value string, err error) {
|
|
||||||
// find the current user
|
|
||||||
usr, err := user.Current()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the base config file!
|
|
||||||
contents, err := os.ReadFile(filepath.Join(usr.HomeDir, baseConfigFile))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// and trim the spaces!
|
|
||||||
value = strings.TrimSpace(string(contents))
|
|
||||||
|
|
||||||
// check that it is actually set!
|
|
||||||
if len(value) == 0 {
|
|
||||||
return "", errors.New("ReadBaseDirectory: Directory is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
// and return it!
|
|
||||||
return value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteBaseDirectory writes the base directory to the environment, or returns an error
|
|
||||||
func WriteBaseDirectory(dir string) error {
|
|
||||||
// find the current user
|
|
||||||
usr, err := user.Current()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// read the base config file!
|
|
||||||
return os.WriteFile(
|
|
||||||
filepath.Join(usr.HomeDir, baseConfigFile),
|
|
||||||
[]byte(dir),
|
|
||||||
os.ModePerm,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
31
env/server.go
vendored
Normal file
31
env/server.go
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
package env
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Server represents a server for this distillery
|
||||||
|
type Server struct {
|
||||||
|
dis *Distillery
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dis *Distillery) Server() *Server {
|
||||||
|
return &Server{
|
||||||
|
dis: dis,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
instances, err := s.dis.AllInstances()
|
||||||
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
io.WriteString(w, "Something went wrong")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
for _, instance := range instances {
|
||||||
|
io.WriteString(w, instance.Slug+"\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -73,6 +73,9 @@ type Config struct {
|
||||||
// admin credentials for the Mysql database
|
// admin credentials for the Mysql database
|
||||||
MysqlAdminUser string `env:"MYSQL_ADMIN_USER" default:"admin" validator:"is_nonempty"`
|
MysqlAdminUser string `env:"MYSQL_ADMIN_USER" default:"admin" validator:"is_nonempty"`
|
||||||
MysqlAdminPassword string `env:"MYSQL_ADMIN_PASSWORD" default:"admin" validator:"is_nonempty"`
|
MysqlAdminPassword string `env:"MYSQL_ADMIN_PASSWORD" default:"admin" validator:"is_nonempty"`
|
||||||
|
|
||||||
|
// ConfigPath is the path this configuration was loaded from (if any)
|
||||||
|
ConfigPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config Config) String() string {
|
func (config Config) String() string {
|
||||||
|
|
@ -87,7 +90,12 @@ func (config Config) String() string {
|
||||||
tField := tConfig.Field(i)
|
tField := tConfig.Field(i)
|
||||||
vField := vConfig.FieldByName(tField.Name)
|
vField := vConfig.FieldByName(tField.Name)
|
||||||
|
|
||||||
fmt.Fprintf(values, "%s=%v\n", tField.Tag.Get("env"), vField.Interface())
|
env := tField.Tag.Get("env")
|
||||||
|
if env == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(values, "%s=%v\n", env, vField.Interface())
|
||||||
}
|
}
|
||||||
|
|
||||||
return values.String()
|
return values.String()
|
||||||
|
|
@ -113,6 +121,11 @@ func (config *Config) Unmarshal(src io.Reader) error {
|
||||||
dflt := tField.Tag.Get("default")
|
dflt := tField.Tag.Get("default")
|
||||||
validator := tField.Tag.Get("validator")
|
validator := tField.Tag.Get("validator")
|
||||||
|
|
||||||
|
// skip it if it isn't loaded!
|
||||||
|
if env == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// read the value with a default
|
// read the value with a default
|
||||||
value, ok := values[env]
|
value, ok := values[env]
|
||||||
if !ok || value == "" {
|
if !ok || value == "" {
|
||||||
|
|
|
||||||
11
program.go
11
program.go
|
|
@ -3,6 +3,7 @@ package wisski_distillery
|
||||||
import (
|
import (
|
||||||
"os/user"
|
"os/user"
|
||||||
|
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/core"
|
||||||
"github.com/FAU-CDI/wisski-distillery/env"
|
"github.com/FAU-CDI/wisski-distillery/env"
|
||||||
"github.com/tkw1536/goprogram"
|
"github.com/tkw1536/goprogram"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
|
|
@ -11,9 +12,9 @@ import (
|
||||||
// these define the ggman-specific program types
|
// these define the ggman-specific program types
|
||||||
// none of these are strictly needed, they're just around for convenience
|
// none of these are strictly needed, they're just around for convenience
|
||||||
type wdcliEnv = *env.Distillery
|
type wdcliEnv = *env.Distillery
|
||||||
type wdcliParameters = env.Params
|
type wdcliParameters = core.Params
|
||||||
type wdcliRequirements = env.Requirements
|
type wdcliRequirements = core.Requirements
|
||||||
type wdCliFlags = struct{}
|
type wdCliFlags = core.Flags
|
||||||
|
|
||||||
type Program = goprogram.Program[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements]
|
type Program = goprogram.Program[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements]
|
||||||
type Command = goprogram.Command[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements]
|
type Command = goprogram.Command[wdcliEnv, wdcliParameters, wdCliFlags, wdcliRequirements]
|
||||||
|
|
@ -42,7 +43,7 @@ func NewProgram() Program {
|
||||||
if context.Description.Requirements.NeedsDistillery {
|
if context.Description.Requirements.NeedsDistillery {
|
||||||
dis := context.Environment
|
dis := context.Environment
|
||||||
if !dis.UsingDistilleryExecutable() {
|
if !dis.UsingDistilleryExecutable() {
|
||||||
context.EPrintf(warnNoDeployWdcli, env.Executable, dis.ExecutablePath())
|
context.EPrintf(warnNoDeployWdcli, core.Executable, dis.ExecutablePath())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,7 +51,7 @@ func NewProgram() Program {
|
||||||
},
|
},
|
||||||
|
|
||||||
NewEnvironment: func(params wdcliParameters, context Context) (e wdcliEnv, err error) {
|
NewEnvironment: func(params wdcliParameters, context Context) (e wdcliEnv, err error) {
|
||||||
return env.NewDistillery(params, context.Description.Requirements)
|
return env.NewDistillery(params, context.Args.Flags, context.Description.Requirements)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue