aboutsummaryrefslogtreecommitdiff
path: root/bbot/machine-manifest.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-04-10 13:16:11 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-04-10 13:16:11 +0200
commit810df40a0625835ad17a0a5bf3232a8d1a68e680 (patch)
tree1dc320fd821ce30a0a037b7fae151e1f027d0bbd /bbot/machine-manifest.cxx
parent36e0c88e7a3912c8a2e6594841172adb9c14525b (diff)
Implement vm startup and shutdown
Diffstat (limited to 'bbot/machine-manifest.cxx')
-rw-r--r--bbot/machine-manifest.cxx175
1 files changed, 175 insertions, 0 deletions
diff --git a/bbot/machine-manifest.cxx b/bbot/machine-manifest.cxx
new file mode 100644
index 0000000..9145ed4
--- /dev/null
+++ b/bbot/machine-manifest.cxx
@@ -0,0 +1,175 @@
+// file : bbot/machine-manifest.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <bbot/machine-manifest>
+
+#include <butl/manifest-parser>
+#include <butl/manifest-serializer>
+
+using namespace butl;
+
+namespace bbot
+{
+ using parser = manifest_parser;
+ using parsing = manifest_parsing;
+ using serializer = manifest_serializer;
+ using serialization = manifest_serialization;
+ using name_value = manifest_name_value;
+
+ // machine_type
+ //
+ string
+ to_string (machine_type t)
+ {
+ switch (t)
+ {
+ case machine_type::kvm: return "kvm";
+ case machine_type::nspawn: return "nspawn";
+ }
+
+ assert (false);
+ return string ();
+ }
+
+ machine_type
+ to_machine_type (const string& t)
+ {
+ if (t == "kvm") return machine_type::kvm;
+ else if (t == "nspawn") return machine_type::nspawn;
+ else throw invalid_argument ("invalid machine type '" + t + "'");
+ }
+
+ // machine_manifest
+ //
+ machine_manifest::
+ machine_manifest (parser& p, bool iu)
+ : machine_manifest (p, p.next (), iu)
+ {
+ // Make sure this is the end.
+ //
+ name_value nv (p.next ());
+ if (!nv.empty ())
+ throw parsing (p.name (), nv.name_line, nv.name_column,
+ "single machine manifest expected");
+ }
+
+ machine_manifest::
+ machine_manifest (parser& p, name_value nv, bool iu)
+ {
+ auto bad_name = [&p, &nv] (const string& d)
+ {
+ throw parsing (p.name (), nv.name_line, nv.name_column, d);
+ };
+
+ auto bad_value = [&p, &nv] (const string& d)
+ {
+ throw parsing (p.name (), nv.value_line, nv.value_column, d);
+ };
+
+ // Make sure this is the start and we support the version.
+ //
+ if (!nv.name.empty ())
+ bad_name ("start of machine manifest expected");
+
+ if (nv.value != "1")
+ bad_value ("unsupported format version");
+
+ optional<machine_type> type;
+
+ for (nv = p.next (); !nv.empty (); nv = p.next ())
+ {
+ string& n (nv.name);
+ string& v (nv.value);
+
+ if (n == "id")
+ {
+ if (!id.empty ())
+ bad_name ("machine id redefinition");
+
+ if (v.empty ())
+ bad_value ("empty machine id");
+
+ id = move (v);
+ }
+ else if (n == "name")
+ {
+ if (!name.empty ())
+ bad_name ("machine name redefinition");
+
+ if (v.empty ())
+ bad_value ("empty machine name");
+
+ name = move (v);
+ }
+ else if (n == "summary")
+ {
+ if (!summary.empty ())
+ bad_name ("machine summary redefinition");
+
+ if (v.empty ())
+ bad_value ("empty machine summary");
+
+ summary = move (v);
+ }
+ else if (n == "type")
+ {
+ if (type)
+ bad_name ("machine type redefinition");
+
+ try
+ {
+ type = to_machine_type (v);
+ }
+ catch (const invalid_argument&)
+ {
+ bad_value ("invalid machine type");
+ }
+ }
+ else if (n == "mac")
+ {
+ if (mac)
+ bad_name ("machine mac redefinition");
+
+ mac = move (v);
+ }
+ else if (!iu)
+ bad_name ("unknown name '" + n + "' in machine manifest");
+ }
+
+ // Verify all non-optional values were specified.
+ //
+ if (id.empty ())
+ bad_value ("no machine id specified");
+
+ if (name.empty ())
+ bad_value ("no machine name specified");
+
+ if (summary.empty ())
+ bad_value ("no machine summary specified");
+
+ if (!type)
+ bad_value ("no machine type specified");
+
+ this->type = *type;
+ }
+
+ void machine_manifest::
+ serialize (serializer& s) const
+ {
+ // @@ Should we check that all non-optional values are specified and all
+ // values are valid?
+ //
+ s.next ("", "1"); // Start of manifest.
+ s.next ("id", id);
+ s.next ("name", name);
+ s.next ("summary", summary);
+ s.next ("type", to_string (type));
+
+ if (mac)
+ s.next ("mac", *mac);
+
+ s.next ("", ""); // End of manifest.
+ }
+
+}