1010
1111#include < kj/filesystem.h>
1212
13- #include < cmath>
14-
1513namespace workerd ::api {
1614
1715namespace {
@@ -99,14 +97,16 @@ void Container::start(jsg::Lock& js, jsg::Optional<StartupOptions> maybeOptions)
9997 }
10098
10199 if (!flags.getWorkerdExperimental ()) {
102- JSG_REQUIRE (options.snapshots == kj::none, Error,
100+ JSG_REQUIRE (options.directorySnapshots == kj::none, Error,
103101 " Container snapshot restore requires the 'experimental' compatibility flag." );
102+ JSG_REQUIRE (options.containerSnapshot == kj::none, Error,
103+ " Container full snapshot restore requires the 'experimental' compatibility flag." );
104104 } else {
105- KJ_IF_SOME (snapshots , options.snapshots ) {
106- auto list = req.initSnapshots (snapshots .size ());
107- for (auto i: kj::indices (snapshots )) {
105+ KJ_IF_SOME (directorySnapshots , options.directorySnapshots ) {
106+ auto list = req.initDirectorySnapshots (directorySnapshots .size ());
107+ for (auto i: kj::indices (directorySnapshots )) {
108108 auto entry = list[i];
109- auto & restore = snapshots [i];
109+ auto & restore = directorySnapshots [i];
110110 auto & snap = restore.snapshot ;
111111 auto effectiveRestoreDir = snap.dir .asPtr ();
112112 KJ_IF_SOME (mp, restore.mountPoint ) {
@@ -116,13 +116,8 @@ void Container::start(jsg::Lock& js, jsg::Optional<StartupOptions> maybeOptions)
116116 JSG_REQUIRE_NONNULL (parseRestorePath (effectiveRestoreDir), Error,
117117 " Directory snapshot cannot be restored to root directory." );
118118
119- double size = snap.size ;
120- JSG_REQUIRE (std::isfinite (size) && size >= 0 &&
121- size <= static_cast <double >(jsg::MAX_SAFE_INTEGER) && std::floor (size) == size,
122- RangeError, " Snapshot size must be a non-negative integer <= Number.MAX_SAFE_INTEGER" );
123119 auto snapshotBuilder = entry.initSnapshot ();
124120 snapshotBuilder.setId (snap.id );
125- snapshotBuilder.setSize (static_cast <uint64_t >(size));
126121 snapshotBuilder.setDir (snap.dir );
127122 KJ_IF_SOME (name, snap.name ) {
128123 snapshotBuilder.setName (name);
@@ -132,6 +127,14 @@ void Container::start(jsg::Lock& js, jsg::Optional<StartupOptions> maybeOptions)
132127 }
133128 }
134129 }
130+
131+ KJ_IF_SOME (containerSnapshot, options.containerSnapshot ) {
132+ auto builder = req.initContainerSnapshot ();
133+ builder.setId (containerSnapshot.id );
134+ KJ_IF_SOME (name, containerSnapshot.name ) {
135+ builder.setName (name);
136+ }
137+ }
135138 }
136139
137140 req.setCompatibilityFlags (flags);
@@ -160,17 +163,45 @@ jsg::Promise<Container::DirectorySnapshot> Container::snapshotDirectory(
160163 .then (
161164 js, [](jsg::Lock& js, capnp::Response<rpc::Container::SnapshotDirectoryResults> results) {
162165 auto snapshot = results.getSnapshot ();
166+ JSG_REQUIRE (snapshot.getSize () <= jsg::MAX_SAFE_INTEGER, RangeError,
167+ " Snapshot size exceeds Number.MAX_SAFE_INTEGER" );
168+
163169 jsg::Optional<kj::String> name = kj::none;
164- auto snapshotName = snapshot.getName ();
165- if (snapshotName.size () > 0 ) {
166- name = kj::str (snapshotName);
170+ if (snapshot.getName ().size () > 0 ) {
171+ name = kj::str (snapshot.getName ());
167172 }
168173
174+ return Container::DirectorySnapshot{kj::str (snapshot.getId ()),
175+ static_cast <double >(snapshot.getSize ()), kj::str (snapshot.getDir ()), kj::mv (name)};
176+ });
177+ }
178+
179+ jsg::Promise<Container::Snapshot> Container::snapshotContainer (
180+ jsg::Lock& js, SnapshotOptions options) {
181+ JSG_REQUIRE (
182+ running, Error, " snapshotContainer() cannot be called on a container that is not running." );
183+
184+ auto req = rpcClient->snapshotContainerRequest ();
185+
186+ KJ_IF_SOME (name, options.name ) {
187+ req.setName (name);
188+ }
189+
190+ return IoContext::current ()
191+ .awaitIo (js, req.send ())
192+ .then (
193+ js, [](jsg::Lock& js, capnp::Response<rpc::Container::SnapshotContainerResults> results) {
194+ auto snapshot = results.getSnapshot ();
169195 JSG_REQUIRE (snapshot.getSize () <= jsg::MAX_SAFE_INTEGER, RangeError,
170196 " Snapshot size exceeds Number.MAX_SAFE_INTEGER" );
171197
172- return Container::DirectorySnapshot{kj::str (snapshot.getId ()),
173- static_cast <double >(snapshot.getSize ()), kj::str (snapshot.getDir ()), kj::mv (name)};
198+ jsg::Optional<kj::String> name = kj::none;
199+ if (snapshot.getName ().size () > 0 ) {
200+ name = kj::str (snapshot.getName ());
201+ }
202+
203+ return Container::Snapshot{
204+ kj::str (snapshot.getId ()), static_cast <double >(snapshot.getSize ()), kj::mv (name)};
174205 });
175206}
176207
0 commit comments