Move proc locking into entrypoint

This completely cleans up all logic that used to be in crypticnet.
This commit is contained in:
Brian Picciano 2022-10-27 00:45:40 +02:00
parent 28159608c8
commit b26f4bdd6a
5 changed files with 41 additions and 79 deletions

View File

@ -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{

View File

@ -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 {

View File

@ -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)

View File

@ -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)
}
}

View File

@ -1,3 +0,0 @@
// Package globals defines global constants and variables which are valid
// across all cryptic-net processes and sub-processes.
package crypticnet