Skip to content

Commit

Permalink
improve errors for missing directories (#1765)
Browse files Browse the repository at this point in the history
* improve errors for missing directories

Fixes #1761
Updates #1760

Signed-off-by: Kristoffer Dalby <[email protected]>

* update container docs

Signed-off-by: Kristoffer Dalby <[email protected]>

* update changelog with /var changes

Signed-off-by: Kristoffer Dalby <[email protected]>

---------

Signed-off-by: Kristoffer Dalby <[email protected]>
  • Loading branch information
kradalby authored Feb 17, 2024
1 parent c73e847 commit b60ee9d
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ after improving the test harness as part of adopting [#1460](https://github.com/
- Add a filepath entry to [`derp.server.private_key_path`](https://github.com/juanfont/headscale/blob/b35993981297e18393706b2c963d6db882bba6aa/config-example.yaml#L95)
- Docker images are now built with goreleaser (ko) [#1716](https://github.com/juanfont/headscale/pull/1716) [#1763](https://github.com/juanfont/headscale/pull/1763)
- Entrypoint of container image has changed from shell to headscale, require change from `headscale serve` to `serve`
- `/var/lib/headscale` and `/var/run/headscale` is no longer created automatically, see [container docs](./docs/running-headscale-container.md)

### Changes

Expand Down
11 changes: 9 additions & 2 deletions docs/running-headscale-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,22 @@ server_url: http://your-host-name:8080
# Listen to 0.0.0.0 so it's accessible outside the container
metrics_listen_addr: 0.0.0.0:9090
# The default /var/lib/headscale path is not writable in the container
private_key_path: /etc/headscale/private.key
# The default /var/lib/headscale path is not writable in the container
noise:
private_key_path: /etc/headscale/noise_private.key
# The default /var/lib/headscale path is not writable in the container
derp:
private_key_path: /etc/headscale/private.key
# The default /var/run/headscale path is not writable in the container
unix_socket: /etc/headscale/headscale.sock
# The default /var/lib/headscale path is not writable in the container
database.type: sqlite3
database.sqlite.path: /etc/headscale/db.sqlite
```
Alternatively, you can mount `/var/lib` and `/var/run` from your host system by adding
`--volume $(pwd)/lib:/var/lib/headscale` and `--volume $(pwd)/run:/var/run/headscale`
in the next step.

4. Start the headscale server while working in the host headscale directory:

```shell
Expand Down
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 @@ -69,6 +70,7 @@ const (
AuthPrefix = "Bearer "
updateInterval = 5000
privateKeyFileMode = 0o600
headscaleDirPerm = 0o700

registerCacheExpiration = time.Minute * 15
registerCacheCleanup = time.Minute * 20
Expand Down Expand Up @@ -552,6 +554,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 @@ -919,6 +927,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 b60ee9d

Please sign in to comment.