aboutsummaryrefslogtreecommitdiff
path: root/bbot/agent
diff options
context:
space:
mode:
Diffstat (limited to 'bbot/agent')
-rw-r--r--bbot/agent/agent.cxx2
-rw-r--r--bbot/agent/machine-manifest.cxx355
-rw-r--r--bbot/agent/machine-manifest.hxx118
-rw-r--r--bbot/agent/machine.cxx3
4 files changed, 3 insertions, 475 deletions
diff --git a/bbot/agent/agent.cxx b/bbot/agent/agent.cxx
index 80b4fb7..c0849c6 100644
--- a/bbot/agent/agent.cxx
+++ b/bbot/agent/agent.cxx
@@ -30,11 +30,11 @@
#include <bbot/utility.hxx>
#include <bbot/diagnostics.hxx>
+#include <bbot/machine-manifest.hxx>
#include <bbot/bootstrap-manifest.hxx>
#include <bbot/agent/tftp.hxx>
#include <bbot/agent/machine.hxx>
-#include <bbot/agent/machine-manifest.hxx>
using namespace std;
using namespace butl;
diff --git a/bbot/agent/machine-manifest.cxx b/bbot/agent/machine-manifest.cxx
deleted file mode 100644
index 3312d1b..0000000
--- a/bbot/agent/machine-manifest.cxx
+++ /dev/null
@@ -1,355 +0,0 @@
-// file : bbot/agent/machine-manifest.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : TBC; see accompanying LICENSE file
-
-#include <bbot/agent/machine-manifest.hxx>
-
-#include <sstream>
-
-#include <libbutl/tab-parser.hxx>
-#include <libbutl/string-parser.hxx>
-#include <libbutl/manifest-parser.hxx>
-#include <libbutl/manifest-serializer.hxx>
-
-using namespace std;
-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)
- : machine_header_manifest (p, move (nv), unknown_name_mode::stop, &nv)
- {
- auto bad_name = [&p, &nv] (const string& d)
- {
- throw parsing (p.name (), nv.name_line, nv.name_column, d);
- };
-
- // Offsets are used to tie an error to the specific position inside a
- // manifest value (possibly a multiline one).
- //
- auto bad_value = [&p, &nv] (
- const string& d, uint64_t column_offset = 0, uint64_t line_offset = 0)
- {
- throw parsing (p.name (),
- nv.value_line + line_offset,
- (line_offset == 0 ? nv.value_column : 1) + column_offset,
- d);
- };
-
- optional<machine_type> type;
-
- for (; !nv.empty (); nv = p.next ())
- {
- string& n (nv.name);
- string& v (nv.value);
-
- 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");
-
- // @@ Should we check that the value is a valid mac?
- //
- mac = move (v);
- }
- else if (n == "options")
- {
- if (options)
- bad_name ("machine options redefinition");
-
- strings op;
-
- // Note that when reporting errors we combine the manifest value
- // position with the respective error position.
- //
- try
- {
- istringstream is (v);
- tab_parser parser (is, "");
-
- tab_fields tl;
- while (!(tl = parser.next ()).empty ())
- {
- for (auto& tf: tl)
- op.emplace_back (move (tf.value));
- }
- }
- catch (const tab_parsing& e)
- {
- bad_value ("invalid machine options: " + e.description,
- e.column - 1,
- e.line - 1);
- }
-
- if (op.empty ())
- bad_value ("empty machine options");
-
- options = move (op);
- }
- else if (!iu)
- bad_name ("unknown name '" + n + "' in machine manifest");
- }
-
- // Verify all non-optional values were 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?
- //
-
- machine_header_manifest::serialize (s, false);
-
- s.next ("type", to_string (type));
-
- if (mac)
- s.next ("mac", *mac);
-
- // Recompose options string as a space-separated option list,
- //
- if (options)
- {
- string v;
- for (auto b (options->cbegin ()), i (b), e (options->cend ()); i != e;
- ++i)
- {
- if (i != b)
- v += ' ';
-
- v += *i;
- }
-
- s.next ("options", v);
- }
-
- s.next ("", ""); // End of manifest.
- }
-
- strings machine_manifest::
- unquoted_options () const
- {
- return options
- ? string_parser::unquote (*options)
- : strings ();
- }
-
- // toolchain_manifest
- //
- toolchain_manifest::
- toolchain_manifest (parser& p, bool iu)
- : toolchain_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 toolchain manifest expected");
- }
-
- toolchain_manifest::
- toolchain_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 toolchain manifest expected");
-
- if (nv.value != "1")
- bad_value ("unsupported format version");
-
- // Parse the toolchain manifest.
- //
- 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 ("toolchain id redefinition");
-
- if (v.empty ())
- bad_value ("empty toolchain id");
-
- id = move (v);
- }
- else if (!iu)
- bad_name ("unknown name '" + n + "' in toolchain manifest");
- }
-
- // Verify all non-optional values were specified.
- //
- if (id.empty ())
- bad_value ("no toolchain id specified");
- }
-
- void toolchain_manifest::
- serialize (serializer& s) const
- {
- // @@ Should we check that all non-optional values are specified?
- //
- s.next ("", "1"); // Start of manifest.
- s.next ("id", id);
- s.next ("", ""); // End of manifest.
- }
-
- // bootstrapped_machine_manifest
- //
- bootstrapped_machine_manifest::
- bootstrapped_machine_manifest (parser& p, bool iu)
- {
- name_value nv (p.next ());
-
- 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 bootstrapped machine manifest expected");
-
- if (nv.value != "1")
- bad_value ("unsupported format version");
-
- // Parse the bootstrapped machine manifest. Currently there is no values
- // expected.
- //
- for (nv = p.next (); !nv.empty (); nv = p.next ())
- {
- if (!iu)
- bad_name ("unknown name '" + nv.name +
- "' in bootstrapped machine manifest");
- }
-
- nv = p.next ();
- if (nv.empty ())
- bad_value ("machine manifest expected");
-
- machine = machine_manifest (p, nv, iu);
-
- if (!machine.mac)
- bad_name ("mac address must be present in machine manifest");
-
- nv = p.next ();
- if (nv.empty ())
- bad_value ("toolchain manifest expected");
-
- toolchain = toolchain_manifest (p, nv, iu);
-
- nv = p.next ();
- if (nv.empty ())
- bad_value ("bootstrap manifest expected");
-
- bootstrap = bootstrap_manifest (p, nv, iu);
-
- // Make sure this is the end.
- //
- nv = p.next ();
- if (!nv.empty ())
- throw parsing (p.name (), nv.name_line, nv.name_column,
- "single bootstrapped machine manifest expected");
- }
-
- void bootstrapped_machine_manifest::
- serialize (serializer& s) const
- {
- // @@ Should we check that all non-optional values are specified?
- //
- s.next ("", "1"); // Start of manifest.
- s.next ("", ""); // End of manifest.
-
- if (!machine.mac)
- throw serialization (s.name (),
- "mac address must be present in machine manifest");
-
- machine.serialize (s);
- toolchain.serialize (s);
- bootstrap.serialize (s);
-
- s.next ("", ""); // End of stream.
- }
-}
diff --git a/bbot/agent/machine-manifest.hxx b/bbot/agent/machine-manifest.hxx
deleted file mode 100644
index 37919ba..0000000
--- a/bbot/agent/machine-manifest.hxx
+++ /dev/null
@@ -1,118 +0,0 @@
-// file : bbot/agent/machine-manifest.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : TBC; see accompanying LICENSE file
-
-#ifndef BBOT_AGENT_MACHINE_MANIFEST_HXX
-#define BBOT_AGENT_MACHINE_MANIFEST_HXX
-
-#include <map>
-
-#include <libbutl/manifest-forward.hxx>
-
-#include <libbbot/manifest.hxx> // machine_header
-
-#include <bbot/types.hxx>
-#include <bbot/utility.hxx>
-
-#include <bbot/bootstrap-manifest.hxx>
-
-namespace bbot
-{
- // Machine type.
- //
- enum class machine_type {kvm, nspawn};
-
- string
- to_string (machine_type);
-
- machine_type
- to_machine_type (const string&); // Throws invalid_argument.
-
- // Machine.
- //
- class machine_manifest: public machine_header_manifest
- {
- public:
- machine_type type;
- optional<string> mac; // Required in bootstrapped machine manifest.
- optional<strings> options; // Note: could be quoted.
-
- strings
- unquoted_options () const; // Return empty if absent.
-
- machine_manifest (std::string i,
- std::string n,
- std::string s,
- machine_type t,
- optional<string> m,
- optional<strings> o)
- : machine_header_manifest (std::move (i),
- std::move (n),
- std::move (s)),
- type (t),
- mac (std::move (m)),
- options (std::move (o)) {}
-
- public:
- machine_manifest () = default; // VC export.
- machine_manifest (butl::manifest_parser&, bool ignore_unknown = false);
- machine_manifest (butl::manifest_parser&,
- butl::manifest_name_value start,
- bool ignore_unknown = false);
-
- void
- serialize (butl::manifest_serializer&) const;
- };
-
- // Toolchain.
- //
- class toolchain_manifest
- {
- public:
-
- // Toolchain id (SHAXXX).
- //
- string id;
-
- explicit
- toolchain_manifest (string i): id (i) {}
-
- public:
- toolchain_manifest () = default; // VC export.
- toolchain_manifest (butl::manifest_parser&, bool ignore_unknown = false);
- toolchain_manifest (butl::manifest_parser&,
- butl::manifest_name_value start,
- bool ignore_unknown = false);
-
- void
- serialize (butl::manifest_serializer&) const;
- };
-
- // The manifest stored in <name>-<toolchain>/ consists of the machine
- // manifest (original), toolchain manifest, and bootstrap manifest.
- //
- class bootstrapped_machine_manifest
- {
- public:
- machine_manifest machine;
- toolchain_manifest toolchain;
- bootstrap_manifest bootstrap;
-
- bootstrapped_machine_manifest (machine_manifest m,
- toolchain_manifest t,
- bootstrap_manifest b)
- : machine (move (m)), toolchain (move (t)), bootstrap (move (b)) {}
-
- public:
- bootstrapped_machine_manifest () = default; // VC export.
- bootstrapped_machine_manifest (butl::manifest_parser&,
- bool ignore_unknown = false);
-
- void
- serialize (butl::manifest_serializer&) const;
- };
-
- using bootstrapped_machine_manifests = vector<bootstrapped_machine_manifest>;
-}
-
-#endif // BBOT_AGENT_MACHINE_MANIFEST_HXX
diff --git a/bbot/agent/machine.cxx b/bbot/agent/machine.cxx
index 422c623..f3c9874 100644
--- a/bbot/agent/machine.cxx
+++ b/bbot/agent/machine.cxx
@@ -12,8 +12,9 @@
#include <cstdio> // snprintf()
#include <cstring> // strcpy()
+#include <bbot/machine-manifest.hxx>
+
#include <bbot/agent/agent.hxx>
-#include <bbot/agent/machine-manifest.hxx>
using namespace std;
using namespace butl;