@@ -24,10 +24,16 @@ import (
2424 "google.golang.org/protobuf/types/known/emptypb"
2525 "google.golang.org/protobuf/types/known/timestamppb"
2626
27+ grpcmetadata "google.golang.org/grpc/metadata"
28+
2729 "github.com/e2b-dev/infra/packages/orchestrator/pkg/sandbox"
30+ "github.com/e2b-dev/infra/packages/orchestrator/pkg/sandbox/block"
2831 "github.com/e2b-dev/infra/packages/orchestrator/pkg/sandbox/fc"
2932 sbxtemplate "github.com/e2b-dev/infra/packages/orchestrator/pkg/sandbox/template"
33+ configpkg "github.com/e2b-dev/infra/packages/orchestrator/pkg/template/build/config"
34+ "github.com/e2b-dev/infra/packages/orchestrator/pkg/template/constants"
3035 "github.com/e2b-dev/infra/packages/orchestrator/pkg/template/metadata"
36+ "github.com/e2b-dev/infra/packages/orchestrator/pkg/units"
3137 "github.com/e2b-dev/infra/packages/shared/pkg/events"
3238 "github.com/e2b-dev/infra/packages/shared/pkg/featureflags"
3339 "github.com/e2b-dev/infra/packages/shared/pkg/grpc/orchestrator"
@@ -58,6 +64,66 @@ const (
5864 killReasonUnknown = "unknown"
5965)
6066
67+ func rebootFromRootfsEnabled (ctx context.Context ) bool {
68+ values := grpcmetadata .ValueFromIncomingContext (ctx , orchestrator .SandboxRebootFromRootfsGRPCMetadataKey )
69+ return len (values ) > 0 && values [0 ] == "true"
70+ }
71+
72+ func (s * Server ) createSandboxFromRootfs (
73+ ctx context.Context ,
74+ template sbxtemplate.Template ,
75+ config * sandbox.Config ,
76+ runtime sandbox.RuntimeMetadata ,
77+ req * orchestrator.SandboxCreateRequest ,
78+ ) (* sandbox.Sandbox , error ) {
79+ memfile , err := block .NewEmpty (
80+ units .MBToBytes (config .RamMB ),
81+ configpkg .MemfilePageSize (config .HugePages ),
82+ uuid .MustParse (template .Files ().BuildID ),
83+ )
84+ if err != nil {
85+ return nil , fmt .Errorf ("create empty memfile: %w" , err )
86+ }
87+ defer memfile .Close ()
88+
89+ maskedTemplate := sbxtemplate .NewMaskTemplate (template , sbxtemplate .WithMemfile (memfile ))
90+
91+ kvmClock , err := utils .IsGTEVersion (config .Envd .Version , "0.2.11" )
92+ if err != nil {
93+ return nil , fmt .Errorf ("compare envd version: %w" , err )
94+ }
95+
96+ timeout := req .GetEndTime ().AsTime ().Sub (req .GetStartTime ().AsTime ())
97+ if timeout <= 0 {
98+ timeout = s .config .EnvdTimeout
99+ }
100+
101+ sbx , err := s .sandboxFactory .CreateSandbox (
102+ ctx ,
103+ config ,
104+ runtime ,
105+ maskedTemplate ,
106+ timeout ,
107+ "" ,
108+ fc.ProcessOptions {
109+ InitScriptPath : constants .SystemdInitPath ,
110+ KvmClock : kvmClock ,
111+ },
112+ req .GetSandbox (),
113+ nil ,
114+ )
115+ if err != nil {
116+ return nil , err
117+ }
118+
119+ if err := sbx .WaitForEnvd (ctx , timeout ); err != nil {
120+ closeErr := sbx .Close (context .WithoutCancel (ctx ))
121+ return nil , errors .Join (fmt .Errorf ("wait for envd after rootfs reboot: %w" , err ), closeErr )
122+ }
123+
124+ return sbx , nil
125+ }
126+
61127func (s * Server ) Create (ctx context.Context , req * orchestrator.SandboxCreateRequest ) (_ * orchestrator.SandboxCreateResponse , createErr error ) {
62128 // set max request timeout for this request
63129 ctx , cancel := context .WithTimeoutCause (ctx , requestTimeout , errors .New ("request timed out" ))
@@ -187,18 +253,22 @@ func (s *Server) Create(ctx context.Context, req *orchestrator.SandboxCreateRequ
187253 SandboxType : sandbox .SandboxTypeSandbox ,
188254 }
189255
190- sbx , err := s .sandboxFactory .ResumeSandbox (
191- ctx ,
192- template ,
193- config ,
194- runtime ,
195- req .GetStartTime ().AsTime (),
196- req .GetEndTime ().AsTime (),
197- req .GetSandbox (),
198- )
256+ var sbx * sandbox.Sandbox
257+ if rebootFromRootfsEnabled (ctx ) {
258+ sbx , err = s .createSandboxFromRootfs (ctx , template , config , runtime , req )
259+ } else {
260+ sbx , err = s .sandboxFactory .ResumeSandbox (
261+ ctx ,
262+ template ,
263+ config ,
264+ runtime ,
265+ req .GetStartTime ().AsTime (),
266+ req .GetEndTime ().AsTime (),
267+ req .GetSandbox (),
268+ )
269+ }
199270 if err != nil {
200271 if errors .Is (err , storage .ErrObjectNotExist ) {
201- // Snapshot data not found, let the API know the data aren't probably upload yet
202272 telemetry .ReportError (ctx , "sandbox files not found" , err , telemetry .WithSandboxID (req .GetSandbox ().GetSandboxId ()))
203273
204274 return nil , status .Errorf (codes .FailedPrecondition , "sandbox files for '%s' not found" , req .GetSandbox ().GetSandboxId ())
0 commit comments