diff --git a/cmd/cc-backend/main.go b/cmd/cc-backend/main.go index af0ce33..8164792 100644 --- a/cmd/cc-backend/main.go +++ b/cmd/cc-backend/main.go @@ -35,6 +35,7 @@ import ( "github.com/ClusterCockpit/cc-backend/internal/repository" "github.com/ClusterCockpit/cc-backend/internal/routerConfig" "github.com/ClusterCockpit/cc-backend/internal/runtimeEnv" + "github.com/ClusterCockpit/cc-backend/internal/util" "github.com/ClusterCockpit/cc-backend/pkg/archive" "github.com/ClusterCockpit/cc-backend/pkg/log" "github.com/ClusterCockpit/cc-backend/pkg/schema" @@ -58,15 +59,84 @@ const logoString = ` |_| ` +const envString = ` +# Base64 encoded Ed25519 keys (DO NOT USE THESE TWO IN PRODUCTION!) +# You can generate your own keypair using the gen-keypair tool +JWT_PUBLIC_KEY="kzfYrYy+TzpanWZHJ5qSdMj5uKUWgq74BWhQG6copP0=" +JWT_PRIVATE_KEY="dtPC/6dWJFKZK7KZ78CvWuynylOmjBFyMsUWArwmodOTN9itjL5POlqdZkcnmpJ0yPm4pRaCrvgFaFAbpyik/Q==" + +# Some random bytes used as secret for cookie-based sessions (DO NOT USE THIS ONE IN PRODUCTION) +SESSION_KEY="67d829bf61dc5f87a73fd814e2c9f629" +` + +const configString = ` +{ + "addr": "127.0.0.1:8080", + "archive": { + "kind": "file", + "path": "./var/job-archive" + }, + "clusters": [ + { + "name": "name", + "metricDataRepository": { + "kind": "cc-metric-store", + "url": "http://localhost:8082", + "token": "" + }, + "filterRanges": { + "numNodes": { + "from": 1, + "to": 64 + }, + "duration": { + "from": 0, + "to": 86400 + }, + "startTime": { + "from": "2023-01-01T00:00:00Z", + "to": null + } + } + } + ] +} +` + var ( date string commit string version string ) +func initEnv() { + if util.CheckFileExists("var") { + fmt.Print("Directory ./var already exists. Exiting!\n") + os.Exit(0) + } + + if err := os.WriteFile("config.json", []byte(configString), 0666); err != nil { + log.Fatalf("Writing config.json failed: %s", err.Error()) + } + + if err := os.WriteFile(".env", []byte(envString), 0666); err != nil { + log.Fatalf("Writing .env failed: %s", err.Error()) + } + + if err := os.Mkdir("var", 0777); err != nil { + log.Fatalf("Mkdir var failed: %s", err.Error()) + } + + err := repository.MigrateDB("sqlite3", "./var/job.db") + if err != nil { + log.Fatalf("Initialize job.db failed: %s", err.Error()) + } +} + func main() { - var flagReinitDB, flagServer, flagSyncLDAP, flagGops, flagMigrateDB, flagDev, flagVersion, flagLogDateTime bool + var flagReinitDB, flagInit, flagServer, flagSyncLDAP, flagGops, flagMigrateDB, flagDev, flagVersion, flagLogDateTime bool var flagNewUser, flagDelUser, flagGenJWT, flagConfigFile, flagImportJob, flagLogLevel string + flag.BoolVar(&flagInit, "init", false, "Setup var directory, initialize swlite database file, config.json and .env") flag.BoolVar(&flagReinitDB, "init-db", false, "Go through job-archive and re-initialize the 'job', 'tag', and 'jobtag' tables (all running jobs will be lost!)") flag.BoolVar(&flagSyncLDAP, "sync-ldap", false, "Sync the 'user' table with ldap") flag.BoolVar(&flagServer, "server", false, "Start a server, continues listening on port after initialization and argument handling") @@ -96,6 +166,14 @@ func main() { // Apply config flags for pkg/log log.Init(flagLogLevel, flagLogDateTime) + if flagInit { + initEnv() + fmt.Print("Succesfully setup environment!\n") + fmt.Print("Please review config.json and .env and adjust it to your needs.\n") + fmt.Print("Add your job-archive at ./var/job-archive.\n") + os.Exit(0) + } + // See https://github.com/google/gops (Runtime overhead is almost zero) if flagGops { if err := agent.Listen(agent.Options{}); err != nil { diff --git a/configs/env-template.txt b/configs/env-template.txt index 35a4634..e62a1fa 100644 --- a/configs/env-template.txt +++ b/configs/env-template.txt @@ -1,10 +1,10 @@ # Base64 encoded Ed25519 keys (DO NOT USE THESE TWO IN PRODUCTION!) -# You can generate your own keypair using `go run utils/gen-keypair.go` +# You can generate your own keypair using `go run tools/gen-keypair/main.go` JWT_PUBLIC_KEY="kzfYrYy+TzpanWZHJ5qSdMj5uKUWgq74BWhQG6copP0=" JWT_PRIVATE_KEY="dtPC/6dWJFKZK7KZ78CvWuynylOmjBFyMsUWArwmodOTN9itjL5POlqdZkcnmpJ0yPm4pRaCrvgFaFAbpyik/Q==" # Base64 encoded Ed25519 public key for accepting externally generated JWTs -# Keys in PEM format can be converted, see `tools/convert-pem-pubkey-for-cc/Readme.md` +# Keys in PEM format can be converted, see `tools/convert-pem-pubkey/Readme.md` CROSS_LOGIN_JWT_PUBLIC_KEY="" # Some random bytes used as secret for cookie-based sessions (DO NOT USE THIS ONE IN PRODUCTION) diff --git a/internal/repository/migration.go b/internal/repository/migration.go index b92a68b..a5605c6 100644 --- a/internal/repository/migration.go +++ b/internal/repository/migration.go @@ -53,6 +53,8 @@ func checkDBVersion(backend string, db *sql.DB) error { if err != nil { return err } + default: + log.Fatalf("unsupported database backend: %s", backend) } v, _, err := m.Version() @@ -99,6 +101,8 @@ func MigrateDB(backend string, db string) error { if err != nil { return err } + default: + log.Fatalf("unsupported database backend: %s", backend) } if err := m.Up(); err != nil { diff --git a/internal/util/util_test.go b/internal/util/util_test.go index a318649..dff0a25 100644 --- a/internal/util/util_test.go +++ b/internal/util/util_test.go @@ -15,6 +15,10 @@ import ( func TestCheckFileExists(t *testing.T) { tmpdir := t.TempDir() + if !util.CheckFileExists(tmpdir) { + t.Fatal("expected true, got false") + } + filePath := filepath.Join(tmpdir, "version.txt") if err := os.WriteFile(filePath, []byte(fmt.Sprintf("%d", 1)), 0666); err != nil {