From c0be5086ef926ac8e756660d87756a7f8b8208e2 Mon Sep 17 00:00:00 2001 From: sharder996 Date: Tue, 13 Jun 2023 14:16:02 -0700 Subject: [PATCH 1/7] [snapshot] add creation timestamp field to snapshot metadata --- include/multipass/snapshot.h | 2 ++ src/platform/backends/qemu/qemu_snapshot.cpp | 2 +- .../backends/shared/base_snapshot.cpp | 21 +++++++++------ src/platform/backends/shared/base_snapshot.h | 26 +++++++++++++++---- tests/stub_snapshot.h | 9 +++++++ 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/include/multipass/snapshot.h b/include/multipass/snapshot.h index 7a280f9f9d..dd5428d7c7 100644 --- a/include/multipass/snapshot.h +++ b/include/multipass/snapshot.h @@ -40,6 +40,7 @@ class Snapshot : private DisabledCopyMove virtual std::string get_name() const = 0; virtual std::string get_comment() const = 0; virtual std::string get_parent_name() const = 0; + virtual QDateTime get_creation_timestamp() const = 0; virtual std::shared_ptr get_parent() const = 0; virtual std::shared_ptr get_parent() = 0; @@ -56,6 +57,7 @@ class Snapshot : private DisabledCopyMove virtual void set_name(const std::string&) = 0; // TODO@snapshots don't forget to rename json file virtual void set_comment(const std::string&) = 0; + virtual void set_creation_timestamp(const QDateTime&) = 0; virtual void set_parent(std::shared_ptr) = 0; virtual void capture() = 0; // not using the constructor, we need snapshot objects for existing snapshots too diff --git a/src/platform/backends/qemu/qemu_snapshot.cpp b/src/platform/backends/qemu/qemu_snapshot.cpp index 53222eb8e4..c2a64dd067 100644 --- a/src/platform/backends/qemu/qemu_snapshot.cpp +++ b/src/platform/backends/qemu/qemu_snapshot.cpp @@ -65,7 +65,7 @@ void checked_exec_qemu_img(std::unique_ptr spec) mp::QemuSnapshot::QemuSnapshot(const std::string& name, const std::string& comment, const VMSpecs& specs, const QString& image_path, std::shared_ptr parent) - : BaseSnapshot(name, comment, specs, std::move(parent)), image_path{image_path} + : BaseSnapshot(name, comment, QDateTime::currentDateTimeUtc(), specs, std::move(parent)), image_path{image_path} { } diff --git a/src/platform/backends/shared/base_snapshot.cpp b/src/platform/backends/shared/base_snapshot.cpp index cd4874e9e6..e35198710f 100644 --- a/src/platform/backends/shared/base_snapshot.cpp +++ b/src/platform/backends/shared/base_snapshot.cpp @@ -78,12 +78,14 @@ std::shared_ptr find_parent(const QJsonObject& json, mp::VirtualMa } } // namespace -mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, int num_cores, MemorySize mem_size, - MemorySize disk_space, VirtualMachine::State state, +mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, + const QDateTime& creation_timestamp, // NOLINT(modernize-pass-by-value) + int num_cores, MemorySize mem_size, MemorySize disk_space, VirtualMachine::State state, std::unordered_map mounts, QJsonObject metadata, std::shared_ptr parent) : name{name}, comment{comment}, + creation_timestamp{creation_timestamp}, num_cores{num_cores}, mem_size{mem_size}, disk_space{disk_space}, @@ -102,10 +104,10 @@ mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comme throw std::runtime_error{fmt::format("Invalid disk size for snapshot: {}", disk_bytes)}; } -mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, const VMSpecs& specs, - std::shared_ptr parent) - : BaseSnapshot{name, comment, specs.num_cores, specs.mem_size, specs.disk_space, - specs.state, specs.mounts, specs.metadata, std::move(parent)} +mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, + const VMSpecs& specs, std::shared_ptr parent) + : BaseSnapshot{name, comment, creation_timestamp, specs.num_cores, specs.mem_size, specs.disk_space, + specs.state, specs.mounts, specs.metadata, std::move(parent)} { } @@ -115,8 +117,10 @@ mp::BaseSnapshot::BaseSnapshot(const QJsonObject& json, VirtualMachine& vm) } mp::BaseSnapshot::BaseSnapshot(InnerJsonTag, const QJsonObject& json, VirtualMachine& vm) - : BaseSnapshot{json["name"].toString().toStdString(), // name - json["comment"].toString().toStdString(), // comment + : BaseSnapshot{json["name"].toString().toStdString(), // name + json["comment"].toString().toStdString(), // comment + QDateTime::fromString(json["creation_timestamp"].toString(), + "yyyy-MM-ddTHH:mm:ss.zzzZ"), // creation_timestamp json["num_cores"].toInt(), // num_cores MemorySize{json["mem_size"].toString().toStdString()}, // mem_size MemorySize{json["disk_space"].toString().toStdString()}, // disk_space @@ -134,6 +138,7 @@ QJsonObject multipass::BaseSnapshot::serialize() const snapshot.insert("name", QString::fromStdString(name)); snapshot.insert("comment", QString::fromStdString(comment)); + snapshot.insert("creation_timestamp", creation_timestamp.toString("yyyy-MM-ddTHH:mm:ss.zzzZ")); snapshot.insert("num_cores", num_cores); snapshot.insert("mem_size", QString::number(mem_size.in_bytes())); snapshot.insert("disk_space", QString::number(disk_space.in_bytes())); diff --git a/src/platform/backends/shared/base_snapshot.h b/src/platform/backends/shared/base_snapshot.h index 09ecd5aece..83dd7464fa 100644 --- a/src/platform/backends/shared/base_snapshot.h +++ b/src/platform/backends/shared/base_snapshot.h @@ -34,13 +34,14 @@ struct VMSpecs; class BaseSnapshot : public Snapshot { public: - BaseSnapshot(const std::string& name, const std::string& comment, const VMSpecs& specs, - std::shared_ptr parent); + BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, + const VMSpecs& specs, std::shared_ptr parent); BaseSnapshot(const QJsonObject& json, VirtualMachine& vm); std::string get_name() const override; std::string get_comment() const override; std::string get_parent_name() const override; + QDateTime get_creation_timestamp() const override; std::shared_ptr get_parent() const override; std::shared_ptr get_parent() override; @@ -57,6 +58,7 @@ class BaseSnapshot : public Snapshot void set_name(const std::string& n) override; void set_comment(const std::string& c) override; + void set_creation_timestamp(const QDateTime& t) override; void set_parent(std::shared_ptr p) override; void capture() final; @@ -73,13 +75,15 @@ class BaseSnapshot : public Snapshot { }; BaseSnapshot(InnerJsonTag, const QJsonObject& json, VirtualMachine& vm); - BaseSnapshot(const std::string& name, const std::string& comment, int num_cores, MemorySize mem_size, - MemorySize disk_space, VirtualMachine::State state, std::unordered_map mounts, - QJsonObject metadata, std::shared_ptr parent); + BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, + int num_cores, MemorySize mem_size, MemorySize disk_space, VirtualMachine::State state, + std::unordered_map mounts, QJsonObject metadata, + std::shared_ptr parent); private: std::string name; std::string comment; + QDateTime creation_timestamp; // This class is non-copyable and having these const simplifies thread safety const int num_cores; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) @@ -107,6 +111,12 @@ inline std::string multipass::BaseSnapshot::get_comment() const return comment; } +inline QDateTime multipass::BaseSnapshot::get_creation_timestamp() const +{ + const std::unique_lock lock{mutex}; + return creation_timestamp; +} + inline std::string multipass::BaseSnapshot::get_parent_name() const { std::unique_lock lock{mutex}; @@ -169,6 +179,12 @@ inline void multipass::BaseSnapshot::set_comment(const std::string& c) comment = c; } +inline void multipass::BaseSnapshot::set_creation_timestamp(const QDateTime& t) +{ + const std::unique_lock lock{mutex}; + creation_timestamp = t; +} + inline void multipass::BaseSnapshot::set_parent(std::shared_ptr p) { const std::unique_lock lock{mutex}; diff --git a/tests/stub_snapshot.h b/tests/stub_snapshot.h index 759785970c..11ac707766 100644 --- a/tests/stub_snapshot.h +++ b/tests/stub_snapshot.h @@ -37,6 +37,11 @@ struct StubSnapshot : public Snapshot return {}; } + QDateTime get_creation_timestamp() const noexcept override + { + return QDateTime{}; + } + std::string get_parent_name() const override { return {}; @@ -95,6 +100,10 @@ struct StubSnapshot : public Snapshot { } + void set_creation_timestamp(const QDateTime&) override + { + } + void set_parent(std::shared_ptr) override { } From 3eef4148d29fb57f1a8b4a75e224a37f0d5e12b6 Mon Sep 17 00:00:00 2001 From: sharder996 Date: Tue, 13 Jun 2023 14:16:40 -0700 Subject: [PATCH 2/7] [daemon] populate info reply with snapshot creation time --- src/daemon/daemon.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index d8cbdf598a..eec4d1d232 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -1761,7 +1761,10 @@ try // clang-format on fundamentals->set_snapshot_name(snapshot->get_name()); fundamentals->set_parent(snapshot->get_parent_name()); fundamentals->set_comment(snapshot->get_comment()); - // TODO@snapshots populate snapshot creation time once available + + auto timestamp = fundamentals->mutable_creation_timestamp(); + timestamp->set_seconds(snapshot->get_creation_timestamp().toSecsSinceEpoch()); + timestamp->set_nanos(snapshot->get_creation_timestamp().time().msec() * 1000000); }; if (const auto& it = instance_snapshots_map.find(name); From 661ac5c172de326805457d23ccb4edf40ee24257 Mon Sep 17 00:00:00 2001 From: sharder996 Date: Fri, 23 Jun 2023 10:07:10 -0700 Subject: [PATCH 3/7] [snapshot] remove unneeded setter and set member variable to const --- include/multipass/snapshot.h | 1 - src/platform/backends/shared/base_snapshot.h | 10 +--------- tests/stub_snapshot.h | 4 ---- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/include/multipass/snapshot.h b/include/multipass/snapshot.h index dd5428d7c7..9f79c78486 100644 --- a/include/multipass/snapshot.h +++ b/include/multipass/snapshot.h @@ -57,7 +57,6 @@ class Snapshot : private DisabledCopyMove virtual void set_name(const std::string&) = 0; // TODO@snapshots don't forget to rename json file virtual void set_comment(const std::string&) = 0; - virtual void set_creation_timestamp(const QDateTime&) = 0; virtual void set_parent(std::shared_ptr) = 0; virtual void capture() = 0; // not using the constructor, we need snapshot objects for existing snapshots too diff --git a/src/platform/backends/shared/base_snapshot.h b/src/platform/backends/shared/base_snapshot.h index 83dd7464fa..f563340fcd 100644 --- a/src/platform/backends/shared/base_snapshot.h +++ b/src/platform/backends/shared/base_snapshot.h @@ -58,7 +58,6 @@ class BaseSnapshot : public Snapshot void set_name(const std::string& n) override; void set_comment(const std::string& c) override; - void set_creation_timestamp(const QDateTime& t) override; void set_parent(std::shared_ptr p) override; void capture() final; @@ -83,7 +82,7 @@ class BaseSnapshot : public Snapshot private: std::string name; std::string comment; - QDateTime creation_timestamp; + const QDateTime creation_timestamp; // This class is non-copyable and having these const simplifies thread safety const int num_cores; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) @@ -113,7 +112,6 @@ inline std::string multipass::BaseSnapshot::get_comment() const inline QDateTime multipass::BaseSnapshot::get_creation_timestamp() const { - const std::unique_lock lock{mutex}; return creation_timestamp; } @@ -179,12 +177,6 @@ inline void multipass::BaseSnapshot::set_comment(const std::string& c) comment = c; } -inline void multipass::BaseSnapshot::set_creation_timestamp(const QDateTime& t) -{ - const std::unique_lock lock{mutex}; - creation_timestamp = t; -} - inline void multipass::BaseSnapshot::set_parent(std::shared_ptr p) { const std::unique_lock lock{mutex}; diff --git a/tests/stub_snapshot.h b/tests/stub_snapshot.h index 11ac707766..015c7da8e2 100644 --- a/tests/stub_snapshot.h +++ b/tests/stub_snapshot.h @@ -100,10 +100,6 @@ struct StubSnapshot : public Snapshot { } - void set_creation_timestamp(const QDateTime&) override - { - } - void set_parent(std::shared_ptr) override { } From a46ae7457052b313b5d66e403dfed9449b6f870f Mon Sep 17 00:00:00 2001 From: sharder996 Date: Fri, 23 Jun 2023 10:08:15 -0700 Subject: [PATCH 4/7] [snapshot] move creation timestamp to base class --- src/platform/backends/qemu/qemu_snapshot.cpp | 2 +- .../backends/shared/base_snapshot.cpp | 23 ++++++++++++------- src/platform/backends/shared/base_snapshot.h | 4 ++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/platform/backends/qemu/qemu_snapshot.cpp b/src/platform/backends/qemu/qemu_snapshot.cpp index c2a64dd067..53222eb8e4 100644 --- a/src/platform/backends/qemu/qemu_snapshot.cpp +++ b/src/platform/backends/qemu/qemu_snapshot.cpp @@ -65,7 +65,7 @@ void checked_exec_qemu_img(std::unique_ptr spec) mp::QemuSnapshot::QemuSnapshot(const std::string& name, const std::string& comment, const VMSpecs& specs, const QString& image_path, std::shared_ptr parent) - : BaseSnapshot(name, comment, QDateTime::currentDateTimeUtc(), specs, std::move(parent)), image_path{image_path} + : BaseSnapshot(name, comment, specs, std::move(parent)), image_path{image_path} { } diff --git a/src/platform/backends/shared/base_snapshot.cpp b/src/platform/backends/shared/base_snapshot.cpp index e35198710f..c90eb105a0 100644 --- a/src/platform/backends/shared/base_snapshot.cpp +++ b/src/platform/backends/shared/base_snapshot.cpp @@ -78,8 +78,7 @@ std::shared_ptr find_parent(const QJsonObject& json, mp::VirtualMa } } // namespace -mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, - const QDateTime& creation_timestamp, // NOLINT(modernize-pass-by-value) +mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, int num_cores, MemorySize mem_size, MemorySize disk_space, VirtualMachine::State state, std::unordered_map mounts, QJsonObject metadata, std::shared_ptr parent) @@ -104,10 +103,18 @@ mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comme throw std::runtime_error{fmt::format("Invalid disk size for snapshot: {}", disk_bytes)}; } -mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, - const VMSpecs& specs, std::shared_ptr parent) - : BaseSnapshot{name, comment, creation_timestamp, specs.num_cores, specs.mem_size, specs.disk_space, - specs.state, specs.mounts, specs.metadata, std::move(parent)} +mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, const VMSpecs& specs, + std::shared_ptr parent) + : BaseSnapshot{name, + comment, + QDateTime::currentDateTimeUtc(), + specs.num_cores, + specs.mem_size, + specs.disk_space, + specs.state, + specs.mounts, + specs.metadata, + std::move(parent)} { } @@ -120,7 +127,7 @@ mp::BaseSnapshot::BaseSnapshot(InnerJsonTag, const QJsonObject& json, VirtualMac : BaseSnapshot{json["name"].toString().toStdString(), // name json["comment"].toString().toStdString(), // comment QDateTime::fromString(json["creation_timestamp"].toString(), - "yyyy-MM-ddTHH:mm:ss.zzzZ"), // creation_timestamp + Qt::ISODate), // creation_timestamp json["num_cores"].toInt(), // num_cores MemorySize{json["mem_size"].toString().toStdString()}, // mem_size MemorySize{json["disk_space"].toString().toStdString()}, // disk_space @@ -138,7 +145,7 @@ QJsonObject multipass::BaseSnapshot::serialize() const snapshot.insert("name", QString::fromStdString(name)); snapshot.insert("comment", QString::fromStdString(comment)); - snapshot.insert("creation_timestamp", creation_timestamp.toString("yyyy-MM-ddTHH:mm:ss.zzzZ")); + snapshot.insert("creation_timestamp", creation_timestamp.toString(Qt::ISODate)); snapshot.insert("num_cores", num_cores); snapshot.insert("mem_size", QString::number(mem_size.in_bytes())); snapshot.insert("disk_space", QString::number(disk_space.in_bytes())); diff --git a/src/platform/backends/shared/base_snapshot.h b/src/platform/backends/shared/base_snapshot.h index f563340fcd..35af856012 100644 --- a/src/platform/backends/shared/base_snapshot.h +++ b/src/platform/backends/shared/base_snapshot.h @@ -34,8 +34,8 @@ struct VMSpecs; class BaseSnapshot : public Snapshot { public: - BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, - const VMSpecs& specs, std::shared_ptr parent); + BaseSnapshot(const std::string& name, const std::string& comment, const VMSpecs& specs, + std::shared_ptr parent); BaseSnapshot(const QJsonObject& json, VirtualMachine& vm); std::string get_name() const override; From 987b7d1e09dccd29ef4049154b5821620244b7af Mon Sep 17 00:00:00 2001 From: sharder996 Date: Fri, 23 Jun 2023 10:08:32 -0700 Subject: [PATCH 5/7] [review] formatting changes --- include/multipass/snapshot.h | 1 + src/daemon/daemon.cpp | 2 +- src/platform/backends/shared/base_snapshot.cpp | 5 +++-- src/platform/backends/shared/base_snapshot.h | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/multipass/snapshot.h b/include/multipass/snapshot.h index 9f79c78486..4e764d7772 100644 --- a/include/multipass/snapshot.h +++ b/include/multipass/snapshot.h @@ -26,6 +26,7 @@ #include class QJsonObject; +class QDateTime; namespace multipass { diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index eec4d1d232..d9c7601c29 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -1764,7 +1764,7 @@ try // clang-format on auto timestamp = fundamentals->mutable_creation_timestamp(); timestamp->set_seconds(snapshot->get_creation_timestamp().toSecsSinceEpoch()); - timestamp->set_nanos(snapshot->get_creation_timestamp().time().msec() * 1000000); + timestamp->set_nanos(snapshot->get_creation_timestamp().time().msec() * 1'000'000); }; if (const auto& it = instance_snapshots_map.find(name); diff --git a/src/platform/backends/shared/base_snapshot.cpp b/src/platform/backends/shared/base_snapshot.cpp index c90eb105a0..0c4b7868dc 100644 --- a/src/platform/backends/shared/base_snapshot.cpp +++ b/src/platform/backends/shared/base_snapshot.cpp @@ -78,8 +78,9 @@ std::shared_ptr find_parent(const QJsonObject& json, mp::VirtualMa } } // namespace -mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, - int num_cores, MemorySize mem_size, MemorySize disk_space, VirtualMachine::State state, +mp::BaseSnapshot::BaseSnapshot(const std::string& name, const std::string& comment, // NOLINT(modernize-pass-by-value) + const QDateTime& creation_timestamp, int num_cores, MemorySize mem_size, + MemorySize disk_space, VirtualMachine::State state, std::unordered_map mounts, QJsonObject metadata, std::shared_ptr parent) : name{name}, diff --git a/src/platform/backends/shared/base_snapshot.h b/src/platform/backends/shared/base_snapshot.h index 35af856012..6b6b4a7d23 100644 --- a/src/platform/backends/shared/base_snapshot.h +++ b/src/platform/backends/shared/base_snapshot.h @@ -40,8 +40,8 @@ class BaseSnapshot : public Snapshot std::string get_name() const override; std::string get_comment() const override; - std::string get_parent_name() const override; QDateTime get_creation_timestamp() const override; + std::string get_parent_name() const override; std::shared_ptr get_parent() const override; std::shared_ptr get_parent() override; From b495ba32fb90bdf53b406e02b03ee1f1a3c2eb8b Mon Sep 17 00:00:00 2001 From: sharder996 Date: Tue, 27 Jun 2023 23:07:33 -0700 Subject: [PATCH 6/7] [snapshot] move const members together --- src/platform/backends/shared/base_snapshot.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/backends/shared/base_snapshot.h b/src/platform/backends/shared/base_snapshot.h index 6b6b4a7d23..852e5aa655 100644 --- a/src/platform/backends/shared/base_snapshot.h +++ b/src/platform/backends/shared/base_snapshot.h @@ -74,7 +74,7 @@ class BaseSnapshot : public Snapshot { }; BaseSnapshot(InnerJsonTag, const QJsonObject& json, VirtualMachine& vm); - BaseSnapshot(const std::string& name, const std::string& comment, const QDateTime& creation_timestamp, + BaseSnapshot(const std::string& name, const std::string& get_comment, const QDateTime& creation_timestamp, int num_cores, MemorySize mem_size, MemorySize disk_space, VirtualMachine::State state, std::unordered_map mounts, QJsonObject metadata, std::shared_ptr parent); @@ -82,9 +82,9 @@ class BaseSnapshot : public Snapshot private: std::string name; std::string comment; - const QDateTime creation_timestamp; // This class is non-copyable and having these const simplifies thread safety + const QDateTime creation_timestamp; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) const int num_cores; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) const MemorySize mem_size; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) const MemorySize disk_space; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) From 976eb07963494f373956371a124721e5174a2aa5 Mon Sep 17 00:00:00 2001 From: sharder996 Date: Wed, 28 Jun 2023 09:56:47 -0700 Subject: [PATCH 7/7] [snapshot] include ms in recorded snapshot time --- src/platform/backends/shared/base_snapshot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/backends/shared/base_snapshot.cpp b/src/platform/backends/shared/base_snapshot.cpp index 0c4b7868dc..4bc5872484 100644 --- a/src/platform/backends/shared/base_snapshot.cpp +++ b/src/platform/backends/shared/base_snapshot.cpp @@ -128,7 +128,7 @@ mp::BaseSnapshot::BaseSnapshot(InnerJsonTag, const QJsonObject& json, VirtualMac : BaseSnapshot{json["name"].toString().toStdString(), // name json["comment"].toString().toStdString(), // comment QDateTime::fromString(json["creation_timestamp"].toString(), - Qt::ISODate), // creation_timestamp + Qt::ISODateWithMs), // creation_timestamp json["num_cores"].toInt(), // num_cores MemorySize{json["mem_size"].toString().toStdString()}, // mem_size MemorySize{json["disk_space"].toString().toStdString()}, // disk_space @@ -146,7 +146,7 @@ QJsonObject multipass::BaseSnapshot::serialize() const snapshot.insert("name", QString::fromStdString(name)); snapshot.insert("comment", QString::fromStdString(comment)); - snapshot.insert("creation_timestamp", creation_timestamp.toString(Qt::ISODate)); + snapshot.insert("creation_timestamp", creation_timestamp.toString(Qt::ISODateWithMs)); snapshot.insert("num_cores", num_cores); snapshot.insert("mem_size", QString::number(mem_size.in_bytes())); snapshot.insert("disk_space", QString::number(disk_space.in_bytes()));