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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
crypticnet "cryptic-net"
|
|
||||||
"cryptic-net/admin"
|
"cryptic-net/admin"
|
||||||
"cryptic-net/bootstrap"
|
"cryptic-net/bootstrap"
|
||||||
"cryptic-net/daemon"
|
"cryptic-net/daemon"
|
||||||
@ -103,29 +102,11 @@ var subCmdAdminCreateNetwork = subCmd{
|
|||||||
return fmt.Errorf("invalid hostname %q: %w", *hostName, err)
|
return fmt.Errorf("invalid hostname %q: %w", *hostName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
adminCreationParams := admin.CreationParams{
|
runtimeDirCleanup, err := setupAndLockRuntimeDir()
|
||||||
ID: randStr(32),
|
if err != nil {
|
||||||
Domain: *domain,
|
return fmt.Errorf("setting up runtime directory: %w", err)
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
defer runtimeDirCleanup()
|
||||||
|
|
||||||
daemonConfig, err := daemon.LoadConfig(envAppDirPath, *daemonConfigPath)
|
daemonConfig, err := daemon.LoadConfig(envAppDirPath, *daemonConfigPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -146,6 +127,11 @@ var subCmdAdminCreateNetwork = subCmd{
|
|||||||
return fmt.Errorf("creating nebula cert for host: %w", err)
|
return fmt.Errorf("creating nebula cert for host: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adminCreationParams := admin.CreationParams{
|
||||||
|
ID: randStr(32),
|
||||||
|
Domain: *domain,
|
||||||
|
}
|
||||||
|
|
||||||
hostBootstrap := bootstrap.Bootstrap{
|
hostBootstrap := bootstrap.Bootstrap{
|
||||||
AdminCreationParams: adminCreationParams,
|
AdminCreationParams: adminCreationParams,
|
||||||
Hosts: map[string]bootstrap.Host{
|
Hosts: map[string]bootstrap.Host{
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
crypticnet "cryptic-net"
|
|
||||||
"cryptic-net/bootstrap"
|
"cryptic-net/bootstrap"
|
||||||
"cryptic-net/daemon"
|
"cryptic-net/daemon"
|
||||||
"cryptic-net/garage"
|
"cryptic-net/garage"
|
||||||
@ -236,26 +235,11 @@ var subCmdDaemon = subCmd{
|
|||||||
return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
|
return daemon.CopyDefaultConfig(os.Stdout, envAppDirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeDirPath := envRuntimeDirPath
|
runtimeDirCleanup, err := setupAndLockRuntimeDir()
|
||||||
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "will use runtime directory %q for temporary state\n", runtimeDirPath)
|
return fmt.Errorf("setting up runtime directory: %w", err)
|
||||||
|
|
||||||
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 runtimeDirCleanup()
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
bootstrapDataDirPath = bootstrap.DataDirPath(envDataDirPath)
|
bootstrapDataDirPath = bootstrap.DataDirPath(envDataDirPath)
|
||||||
@ -264,8 +248,6 @@ var subCmdDaemon = subCmd{
|
|||||||
hostBootstrapPath string
|
hostBootstrapPath string
|
||||||
hostBootstrap bootstrap.Bootstrap
|
hostBootstrap bootstrap.Bootstrap
|
||||||
foundHostBootstrap bool
|
foundHostBootstrap bool
|
||||||
|
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
|
|
||||||
tryLoadBootstrap := func(path string) bool {
|
tryLoadBootstrap := func(path string) bool {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package crypticnet
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -12,33 +12,13 @@ import (
|
|||||||
|
|
||||||
var errDaemonNotRunning = errors.New("no cryptic-net daemon process running")
|
var errDaemonNotRunning = errors.New("no cryptic-net daemon process running")
|
||||||
|
|
||||||
// ProcLock is used to lock a process.
|
func lockFilePath() string {
|
||||||
type ProcLock interface {
|
return filepath.Join(envRuntimeDirPath, "lock")
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type procLock struct {
|
func writeLock() error {
|
||||||
dir string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProcLock returns a ProcLock which will use a file in the given directory
|
lockFilePath := lockFilePath()
|
||||||
// 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()
|
|
||||||
|
|
||||||
lockFile, err := os.OpenFile(
|
lockFile, err := os.OpenFile(
|
||||||
lockFilePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0400,
|
lockFilePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0400,
|
||||||
@ -63,11 +43,31 @@ func (pl *procLock) WriteLock() error {
|
|||||||
return nil
|
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
|
// checks that the lock file exists and that the process which created it also
|
||||||
// still exists.
|
// still exists.
|
||||||
func (pl *procLock) AssertLock() error {
|
func assertLock() error {
|
||||||
|
|
||||||
lockFilePath := pl.path()
|
lockFilePath := lockFilePath()
|
||||||
|
|
||||||
lockFile, err := os.Open(lockFilePath)
|
lockFile, err := os.Open(lockFilePath)
|
||||||
|
|
@ -2,7 +2,6 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
crypticnet "cryptic-net"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -101,9 +100,7 @@ func (ctx subCmdCtx) doSubCmd(subCmds ...subCmd) error {
|
|||||||
|
|
||||||
if subCmd.checkLock {
|
if subCmd.checkLock {
|
||||||
|
|
||||||
err := crypticnet.NewProcLock(envRuntimeDirPath).AssertLock()
|
if err := assertLock(); err != nil {
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("checking lock file: %w", err)
|
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