Skip to content

Commit

Permalink
improve errors for missing directories
Browse files Browse the repository at this point in the history
Fixes juanfont#1761
Updates juanfont#1760

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
  • Loading branch information
kradalby committed Feb 16, 2024
1 parent d4256ae commit 32fc3e8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
14 changes: 14 additions & 0 deletions hscontrol/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
_ "net/http/pprof" //nolint
"os"
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync"
Expand Down Expand Up @@ -70,6 +71,7 @@ const (
AuthPrefix = "Bearer "
updateInterval = 5000
privateKeyFileMode = 0o600
headscaleDirPerm = 0o700

registerCacheExpiration = time.Minute * 15
registerCacheCleanup = time.Minute * 20
Expand Down Expand Up @@ -556,6 +558,12 @@ func (h *Headscale) Serve() error {
return fmt.Errorf("unable to remove old socket file: %w", err)
}

socketDir := filepath.Dir(h.cfg.UnixSocket)
err = util.EnsureDir(socketDir)
if err != nil {
return fmt.Errorf("setting up unix socket: %w", err)
}

socketListener, err := net.Listen("unix", h.cfg.UnixSocket)
if err != nil {
return fmt.Errorf("failed to set up gRPC socket: %w", err)
Expand Down Expand Up @@ -923,6 +931,12 @@ func notFoundHandler(
}

func readOrCreatePrivateKey(path string) (*key.MachinePrivate, error) {
dir := filepath.Dir(path)
err := util.EnsureDir(dir)
if err != nil {
return nil, fmt.Errorf("ensuring private key directory: %w", err)
}

privateKey, err := os.ReadFile(path)
if errors.Is(err, os.ErrNotExist) {
log.Info().Str("path", path).Msg("No private key file at path, creating...")
Expand Down
7 changes: 7 additions & 0 deletions hscontrol/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net/netip"
"path/filepath"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -344,6 +345,12 @@ func openDB(cfg types.DatabaseConfig) (*gorm.DB, error) {

switch cfg.Type {
case types.DatabaseSqlite:
dir := filepath.Dir(cfg.Sqlite.Path)
err := util.EnsureDir(dir)
if err != nil {
return nil, fmt.Errorf("creating directory for sqlite: %w", err)
}

db, err := gorm.Open(
sqlite.Open(cfg.Sqlite.Path+"?_synchronous=1&_journal_mode=WAL"),
&gorm.Config{
Expand Down
20 changes: 20 additions & 0 deletions hscontrol/util/file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package util

import (
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
Expand Down Expand Up @@ -42,3 +44,21 @@ func GetFileMode(key string) fs.FileMode {

return fs.FileMode(mode)
}

func EnsureDir(dir string) error {
if _, err := os.Stat(dir); os.IsNotExist(err) {
err := os.MkdirAll(dir, PermissionFallback)
if err != nil {
if errors.Is(err, os.ErrPermission) {
return fmt.Errorf(
"creating directory %s, failed with permission error, is it located somewhere Headscale can write?",
dir,
)
}

return fmt.Errorf("creating directory %s: %w", dir, err)
}
}

return nil
}

0 comments on commit 32fc3e8

Please sign in to comment.