Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion docs/BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ sudo mkdir /etc/overlaybd-snapshotter
sudo cat <<-EOF | sudo tee /etc/overlaybd-snapshotter/config.json
{
"root": "/var/lib/overlaybd/",
"address": "/run/overlaybd-snapshotter/overlaybd.sock"
"address": "/run/overlaybd-snapshotter/overlaybd.sock",
"experimental": {
"enabled": false,
"preAuth": true,
"overlaybdApiServer": "http://127.0.0.1:9862"
}
}
EOF
```
Expand Down
7 changes: 6 additions & 1 deletion docs/DOCKER.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ Edit `/etc/overlaybd-snapshotter/config.json`:
"verbose": "info",
"logReportCaller": false,
"autoRemoveDev": true,
"mirrorRegistry": []
"mirrorRegistry": [],
"experimental": {
"enabled": false,
"preAuth": true,
"overlaybdApiServer": "http://127.0.0.1:9862"
}
}
```

Expand Down
10 changes: 9 additions & 1 deletion docs/QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ The config file is `/etc/overlaybd-snapshotter/config.json`. Please create the f
"host": "registry-1.docker.io",
"insecure": false
}
]
],
"experimental": {
"enabled": false,
"preAuth": true,
"overlaybdApiServer": "http://127.0.0.1:9862"
}
}
```
| Field | Description |
Expand All @@ -93,6 +98,9 @@ The config file is `/etc/overlaybd-snapshotter/config.json`. Please create the f
| `exporterConfig.enable` | whether or not create a server to show Prometheus metrics |
| `exporterConfig.uriPrefix` | URI prefix for export metrics, default `/metrics` |
| `exporterConfig.port` | port for http server to show metrics, default `9863` |
| `experimental.enabled` | enable experimental features |
| `experimental.preAuth` | enable overlaybd API server pre-auth notification |
| `experimental.overlaybdApiServer` | overlaybd API server address, default `http://127.0.0.1:9862` |
| `mirrorRegistry` | an arrary of mirror registries |
| `mirrorRegistry.host` | host address, eg. `registry-1.docker.io`` |
| `mirrorRegistry.insecure` | `true` or `false` |
Expand Down
89 changes: 89 additions & 0 deletions pkg/snapshot/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import (
"encoding/binary"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"os"
"os/exec"
"path"
Expand Down Expand Up @@ -86,6 +89,12 @@ type Registry struct {
Insecure bool `json:"insecure"`
}

type ExperimentalConfig struct {
Enabled bool `json:"enabled"`
PreAuth bool `json:"preAuth"`
OverlaybdApiServer string `json:"overlaybdApiServer"`
}

type BootConfig struct {
AsyncRemove bool `json:"asyncRemove"`
Address string `json:"address"`
Expand All @@ -102,6 +111,7 @@ type BootConfig struct {
Tenant int `json:"tenant"` // do not set this if only a single snapshotter service in the host
TurboFsType []string `json:"turboFsType"`
RuntimeType string `json:"runtimeType"` // "containerd" (default) or "docker"
Experimental ExperimentalConfig `json:"experimental"`
}

func DefaultBootConfig() *BootConfig {
Expand All @@ -126,6 +136,11 @@ func DefaultBootConfig() *BootConfig {
"ext4",
},
RuntimeType: "containerd",
Experimental: ExperimentalConfig{
Enabled: false,
PreAuth: true,
OverlaybdApiServer: "http://127.0.0.1:9862",
},
}
}

Expand Down Expand Up @@ -206,6 +221,7 @@ type snapshotter struct {
turboFsType []string
asyncRemove bool
runtimeType string
experimental ExperimentalConfig

quotaDriver *diskquota.PrjQuotaDriver
quotaSize string
Expand Down Expand Up @@ -270,6 +286,7 @@ func NewSnapshotter(bootConfig *BootConfig, opts ...Opt) (snapshots.Snapshotter,
turboFsType: bootConfig.TurboFsType,
tenant: bootConfig.Tenant,
quotaSize: bootConfig.RootfsQuota,
experimental: bootConfig.Experimental,
quotaDriver: &diskquota.PrjQuotaDriver{
QuotaIDs: make(map[uint32]struct{}),
},
Expand Down Expand Up @@ -423,7 +440,78 @@ func (o *snapshotter) isPrepareRootfs(info snapshots.Info) bool {
return true
}

func (o *snapshotter) preAuthEnabled() bool {
return o.experimental.Enabled && o.experimental.PreAuth
}

func (o *snapshotter) notifyOverlaybdAPIServer(configPath string) {
if !o.preAuthEnabled() || configPath == "" {
return
}

go func() {
address := strings.TrimSpace(o.experimental.OverlaybdApiServer)
if address == "" {
log.L.Warn("overlaybd api server address is empty")
return
}

authBase, err := url.Parse(address)
if err != nil {
log.L.WithError(err).Warnf("failed to parse overlaybd api server address %q", address)
return
}

authURL := authBase.ResolveReference(&url.URL{Path: "/auth"})
query := authURL.Query()
query.Set("config", configPath)
authURL.RawQuery = query.Encode()

log.L.Infof("overlaybd api request: %s", authURL.String())

reqCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

req, err := http.NewRequestWithContext(reqCtx, http.MethodGet, authURL.String(), nil)
if err != nil {
log.L.WithError(err).Warnf("failed to create overlaybd api request for %s", authURL.String())
return
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
log.L.WithError(err).Warnf("overlaybd api request failed: %s", authURL.String())
return
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
log.L.WithError(err).Warnf("failed to read overlaybd api response from %s", authURL.String())
return
}

log.L.Infof("overlaybd api response: url=%s status=%s body=%s", authURL.String(), resp.Status, strings.TrimSpace(string(body)))
}()
}

func (o *snapshotter) createMountPoint(ctx context.Context, kind snapshots.Kind, key string, parent string, opts ...snapshots.Opt) (_ []mount.Mount, retErr error) {
if parent != "" && o.preAuthEnabled() {
readCtx, readTxn, err := o.ms.TransactionContext(ctx, false)
if err != nil {
return nil, err
}

parentID, _, _, err := storage.GetInfo(readCtx, parent)
if rerr := readTxn.Rollback(); rerr != nil {
log.G(ctx).WithError(rerr).Warn("failed to rollback read transaction")
}
if err != nil {
return nil, fmt.Errorf("failed to get info of parent snapshot %s: %w", parent, err)
}

o.notifyOverlaybdAPIServer(o.overlaybdConfPath(parentID))
}

ctx, t, err := o.ms.TransactionContext(ctx, true)
if err != nil {
Expand Down Expand Up @@ -631,6 +719,7 @@ func (o *snapshotter) createMountPoint(ctx context.Context, kind snapshots.Kind,
}
log.G(ctx).Debugf("attachAndMountBlockDevice (obdID: %s, writeType: %s, fsType %s, targetPath: %s)",
obdID, writeType, fsType, overlaybdTargetPath(obdHbaNum(o.tenant), obdID))
o.notifyOverlaybdAPIServer(o.overlaybdConfPath(obdID))
if err = o.attachAndMountBlockDevice(ctx, obdID, writeType, fsType, parent == ""); err != nil {
log.G(ctx).Errorf("%v", err)
return nil, fmt.Errorf("failed to attach and mount for snapshot %v: %w", obdID, err)
Expand Down
56 changes: 56 additions & 0 deletions pkg/snapshot/overlay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,62 @@ func newSnapshotterWithOpts(opts ...Opt) testsuite.SnapshotterFunc {
}
}

func TestDefaultBootConfigExperimental(t *testing.T) {
cfg := DefaultBootConfig()

if cfg.Experimental.Enabled {
t.Fatal("expected experimental to be disabled by default")
}
if !cfg.Experimental.PreAuth {
t.Fatal("expected preAuth to be enabled by default")
}
if cfg.Experimental.OverlaybdApiServer != "http://127.0.0.1:9862" {
t.Fatalf("unexpected overlaybd api server address %q", cfg.Experimental.OverlaybdApiServer)
}
}

func TestPreAuthEnabled(t *testing.T) {
tests := []struct {
name string
experimental ExperimentalConfig
want bool
}{
{
name: "experimental disabled",
experimental: ExperimentalConfig{
Enabled: false,
PreAuth: true,
},
want: false,
},
{
name: "preAuth disabled",
experimental: ExperimentalConfig{
Enabled: true,
PreAuth: false,
},
want: false,
},
{
name: "experimental and preAuth enabled",
experimental: ExperimentalConfig{
Enabled: true,
PreAuth: true,
},
want: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sn := &snapshotter{experimental: tt.experimental}
if got := sn.preAuthEnabled(); got != tt.want {
t.Fatalf("preAuthEnabled() = %v, want %v", got, tt.want)
}
})
}
}

func TestBasicSnapshotterOnOverlayFS(t *testing.T) {
testutil.RequiresRoot(t)
testsuite.SnapshotterSuite(t, "overlaybd-on-overlayFS", newSnapshotterWithOpts())
Expand Down
7 changes: 6 additions & 1 deletion script/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@
"runtimeType": "containerd",
"logReportCaller": false,
"autoRemoveDev": false,
"mirrorRegistry": []
"mirrorRegistry": [],
"experimental": {
"enabled": false,
"preAuth": true,
"overlaybdApiServer": "http://127.0.0.1:9862"
}
}
Loading