@@ -22,6 +22,9 @@ import (
2222 "encoding/binary"
2323 "errors"
2424 "fmt"
25+ "io"
26+ "net/http"
27+ "net/url"
2528 "os"
2629 "os/exec"
2730 "path"
@@ -86,6 +89,12 @@ type Registry struct {
8689 Insecure bool `json:"insecure"`
8790}
8891
92+ type ExperimentalConfig struct {
93+ Enabled bool `json:"enabled"`
94+ PreAuth bool `json:"preAuth"`
95+ OverlaybdApiServer string `json:"overlaybdApiServer"`
96+ }
97+
8998type BootConfig struct {
9099 AsyncRemove bool `json:"asyncRemove"`
91100 Address string `json:"address"`
@@ -102,6 +111,7 @@ type BootConfig struct {
102111 Tenant int `json:"tenant"` // do not set this if only a single snapshotter service in the host
103112 TurboFsType []string `json:"turboFsType"`
104113 RuntimeType string `json:"runtimeType"` // "containerd" (default) or "docker"
114+ Experimental ExperimentalConfig `json:"experimental"`
105115}
106116
107117func DefaultBootConfig () * BootConfig {
@@ -126,6 +136,11 @@ func DefaultBootConfig() *BootConfig {
126136 "ext4" ,
127137 },
128138 RuntimeType : "containerd" ,
139+ Experimental : ExperimentalConfig {
140+ Enabled : false ,
141+ PreAuth : true ,
142+ OverlaybdApiServer : "http://127.0.0.1:9862" ,
143+ },
129144 }
130145}
131146
@@ -206,6 +221,7 @@ type snapshotter struct {
206221 turboFsType []string
207222 asyncRemove bool
208223 runtimeType string
224+ experimental ExperimentalConfig
209225
210226 quotaDriver * diskquota.PrjQuotaDriver
211227 quotaSize string
@@ -270,6 +286,7 @@ func NewSnapshotter(bootConfig *BootConfig, opts ...Opt) (snapshots.Snapshotter,
270286 turboFsType : bootConfig .TurboFsType ,
271287 tenant : bootConfig .Tenant ,
272288 quotaSize : bootConfig .RootfsQuota ,
289+ experimental : bootConfig .Experimental ,
273290 quotaDriver : & diskquota.PrjQuotaDriver {
274291 QuotaIDs : make (map [uint32 ]struct {}),
275292 },
@@ -423,7 +440,78 @@ func (o *snapshotter) isPrepareRootfs(info snapshots.Info) bool {
423440 return true
424441}
425442
443+ func (o * snapshotter ) preAuthEnabled () bool {
444+ return o .experimental .Enabled && o .experimental .PreAuth
445+ }
446+
447+ func (o * snapshotter ) notifyOverlaybdAPIServer (configPath string ) {
448+ if ! o .preAuthEnabled () || configPath == "" {
449+ return
450+ }
451+
452+ go func () {
453+ address := strings .TrimSpace (o .experimental .OverlaybdApiServer )
454+ if address == "" {
455+ log .L .Warn ("overlaybd api server address is empty" )
456+ return
457+ }
458+
459+ authBase , err := url .Parse (address )
460+ if err != nil {
461+ log .L .WithError (err ).Warnf ("failed to parse overlaybd api server address %q" , address )
462+ return
463+ }
464+
465+ authURL := authBase .ResolveReference (& url.URL {Path : "/auth" })
466+ query := authURL .Query ()
467+ query .Set ("config" , configPath )
468+ authURL .RawQuery = query .Encode ()
469+
470+ log .L .Infof ("overlaybd api request: %s" , authURL .String ())
471+
472+ reqCtx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
473+ defer cancel ()
474+
475+ req , err := http .NewRequestWithContext (reqCtx , http .MethodGet , authURL .String (), nil )
476+ if err != nil {
477+ log .L .WithError (err ).Warnf ("failed to create overlaybd api request for %s" , authURL .String ())
478+ return
479+ }
480+
481+ resp , err := http .DefaultClient .Do (req )
482+ if err != nil {
483+ log .L .WithError (err ).Warnf ("overlaybd api request failed: %s" , authURL .String ())
484+ return
485+ }
486+ defer resp .Body .Close ()
487+
488+ body , err := io .ReadAll (resp .Body )
489+ if err != nil {
490+ log .L .WithError (err ).Warnf ("failed to read overlaybd api response from %s" , authURL .String ())
491+ return
492+ }
493+
494+ log .L .Infof ("overlaybd api response: url=%s status=%s body=%s" , authURL .String (), resp .Status , strings .TrimSpace (string (body )))
495+ }()
496+ }
497+
426498func (o * snapshotter ) createMountPoint (ctx context.Context , kind snapshots.Kind , key string , parent string , opts ... snapshots.Opt ) (_ []mount.Mount , retErr error ) {
499+ if parent != "" && o .preAuthEnabled () {
500+ readCtx , readTxn , err := o .ms .TransactionContext (ctx , false )
501+ if err != nil {
502+ return nil , err
503+ }
504+
505+ parentID , _ , _ , err := storage .GetInfo (readCtx , parent )
506+ if rerr := readTxn .Rollback (); rerr != nil {
507+ log .G (ctx ).WithError (rerr ).Warn ("failed to rollback read transaction" )
508+ }
509+ if err != nil {
510+ return nil , fmt .Errorf ("failed to get info of parent snapshot %s: %w" , parent , err )
511+ }
512+
513+ o .notifyOverlaybdAPIServer (o .overlaybdConfPath (parentID ))
514+ }
427515
428516 ctx , t , err := o .ms .TransactionContext (ctx , true )
429517 if err != nil {
@@ -631,6 +719,7 @@ func (o *snapshotter) createMountPoint(ctx context.Context, kind snapshots.Kind,
631719 }
632720 log .G (ctx ).Debugf ("attachAndMountBlockDevice (obdID: %s, writeType: %s, fsType %s, targetPath: %s)" ,
633721 obdID , writeType , fsType , overlaybdTargetPath (obdHbaNum (o .tenant ), obdID ))
722+ o .notifyOverlaybdAPIServer (o .overlaybdConfPath (obdID ))
634723 if err = o .attachAndMountBlockDevice (ctx , obdID , writeType , fsType , parent == "" ); err != nil {
635724 log .G (ctx ).Errorf ("%v" , err )
636725 return nil , fmt .Errorf ("failed to attach and mount for snapshot %v: %w" , obdID , err )
0 commit comments