Move proc locking into entrypoint
This completely cleans up all logic that used to be in crypticnet.
This commit is contained in:
parent
28159608c8
commit
b26f4bdd6a
@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
crypticnet "cryptic-net"
|
||||
"cryptic-net/admin"
|
||||
"cryptic-net/bootstrap"
|
||||
"cryptic-net/daemon"
|
||||
@ -103,29 +102,11 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
return fmt.Errorf("invalid hostname %q: %w", *hostName, err)
|
||||
}
|
||||
|
||||
adminCreationParams := admin.CreationParams{
|
||||
ID: randStr(32),
|
||||
Domain: *domain,
|
||||
}
|
||||
|
||||
{
|
||||
runtimeDirPath := envRuntimeDirPath
|
||||
|
||||
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath)
|
||||
|
||||
if err := os.MkdirAll(runtimeDirPath, 0700); err != nil {
|
||||
return fmt.Errorf("creating directory %q: %w", runtimeDirPath, err)
|
||||
} else if err := crypticnet.NewProcLock(runtimeDirPath).WriteLock(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
fmt.Fprintf(os.Stderr, "cleaning up runtime directory %q\n", runtimeDirPath)
|
||||
if err := os.RemoveAll(runtimeDirPath); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error removing temporary directory %q: %v", runtimeDirPath, err)
|
||||
}
|
||||
}()
|
||||
runtimeDirCleanup, err := setupAndLockRuntimeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up runtime directory: %w", err)
|
||||
}
|
||||
defer runtimeDirCleanup()
|
||||
|
||||
daemonConfig, err := daemon.LoadConfig(envAppDirPath, *daemonConfigPath)
|
||||
if err != nil {
|
||||
@ -146,6 +127,11 @@ var subCmdAdminCreateNetwork = subCmd{
|
||||
return fmt.Errorf("creating nebula cert for host: %w", err)
|
||||
}
|
||||
|
||||
adminCreationParams := admin.CreationParams{
|
||||
ID: randStr(32),
|
||||
Domain: *domain,
|
||||
}
|
||||
|
||||
hostBootstrap := bootstrap.Bootstrap{
|
||||
AdminCreationParams: adminCreationParams,
|
||||
Hosts: map[string]bootstrap.Host{
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
crypticnet "cryptic-net"
|
||||
"cryptic-net/bootstrap"
|
||||
"cryptic-net/daemon"
|
||||
"cryptic-net/garage"
|
||||
@ -236,26 +235,11 @@ var subCmdDaemon = subCmd{
|
||||
return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
|
||||
}
|
||||
|
||||
runtimeDirPath := envRuntimeDirPath
|
||||
|
||||
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath)
|
||||
|
||||
if err := os.MkdirAll(runtimeDirPath, 0700); err != nil {
|
||||
return fmt.Errorf("creating directory %q: %w", runtimeDirPath, err)
|
||||
|
||||
} else if err := crypticnet.NewProcLock(runtimeDirPath).WriteLock(); err != nil {
|
||||
return err
|
||||
runtimeDirCleanup, err := setupAndLockRuntimeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting up runtime directory: %w", err)
|
||||
}
|
||||
|
||||
// do not defer the cleaning of the runtime directory until the lock has
|
||||
// been obtained, otherwise we might delete the directory out from under
|
||||
// the feet of an already running daemon
|
||||
defer func() {
|
||||
fmt.Fprintf(os.Stderr, "cleaning up runtime directory %q\n", runtimeDirPath)
|
||||
if err := os.RemoveAll(runtimeDirPath); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error removing temporary directory %q: %v", runtimeDirPath, err)
|
||||
}
|
||||
}()
|
||||
defer runtimeDirCleanup()
|
||||
|
||||
var (
|
||||
bootstrapDataDirPath = bootstrap.DataDirPath(envDataDirPath)
|
||||
@ -264,8 +248,6 @@ var subCmdDaemon = subCmd{
|
||||
hostBootstrapPath string
|
||||
hostBootstrap bootstrap.Bootstrap
|
||||
foundHostBootstrap bool
|
||||
|
||||
err error
|
||||
)
|
||||
|
||||
tryLoadBootstrap := func(path string) bool {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package crypticnet
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@ -12,33 +12,13 @@ import (
|
||||
|
||||
var errDaemonNotRunning = errors.New("no cryptic-net daemon process running")
|
||||
|
||||
// ProcLock is used to lock a process.
|
||||
type ProcLock interface {
|
||||
|
||||
// WriteLock creates a new lock, or errors if the lock is alread held.
|
||||
WriteLock() error
|
||||
|
||||
// AssertLock returns an error if the lock already exists.
|
||||
AssertLock() error
|
||||
func lockFilePath() string {
|
||||
return filepath.Join(envRuntimeDirPath, "lock")
|
||||
}
|
||||
|
||||
type procLock struct {
|
||||
dir string
|
||||
}
|
||||
func writeLock() error {
|
||||
|
||||
// NewProcLock returns a ProcLock which will use a file in the given directory
|
||||
// to lock the process.
|
||||
func NewProcLock(dir string) ProcLock {
|
||||
return &procLock{dir: dir}
|
||||
}
|
||||
|
||||
func (pl *procLock) path() string {
|
||||
return filepath.Join(pl.dir, "lock")
|
||||
}
|
||||
|
||||
func (pl *procLock) WriteLock() error {
|
||||
|
||||
lockFilePath := pl.path()
|
||||
lockFilePath := lockFilePath()
|
||||
|
||||
lockFile, err := os.OpenFile(
|
||||
lockFilePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0400,
|
||||
@ -63,11 +43,31 @@ func (pl *procLock) WriteLock() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// returns a cleanup function which will clean up the created runtime directory.
|
||||
func setupAndLockRuntimeDir() (func(), error) {
|
||||
|
||||
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", envRuntimeDirPath)
|
||||
|
||||
if err := os.MkdirAll(envRuntimeDirPath, 0700); err != nil {
|
||||
return nil, fmt.Errorf("creating directory %q: %w", envRuntimeDirPath, err)
|
||||
|
||||
} else if err := writeLock(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return func() {
|
||||
fmt.Fprintf(os.Stderr, "cleaning up runtime directory %q\n", envRuntimeDirPath)
|
||||
if err := os.RemoveAll(envRuntimeDirPath); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error removing temporary directory %q: %v", envRuntimeDirPath, err)
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// checks that the lock file exists and that the process which created it also
|
||||
// still exists.
|
||||
func (pl *procLock) AssertLock() error {
|
||||
func assertLock() error {
|
||||
|
||||
lockFilePath := pl.path()
|
||||
lockFilePath := lockFilePath()
|
||||
|
||||
lockFile, err := os.Open(lockFilePath)
|
||||
|
@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
crypticnet "cryptic-net"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@ -101,9 +100,7 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
|
||||
|
||||
if subCmd.checkLock {
|
||||
|
||||
err := crypticnet.NewProcLock(envRuntimeDirPath).AssertLock()
|
||||
|
||||
if err != nil {
|
||||
if err := assertLock(); err != nil {
|
||||
return fmt.Errorf("checking lock file: %w", err)
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
// Package globals defines global constants and variables which are valid
|
||||
// across all cryptic-net processes and sub-processes.
|
||||
package crypticnet
|
Loading…
Reference in New Issue
Block a user