summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-08 19:55:53 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2019-10-08 19:55:53 -0500
commit5b0d0916b27f271fc12a8c0c6b595e11673d306d (patch)
treed8d2f3413caac49c1410c539b43be4630924666b
parent57307442c5d707591dfc4d5e7671364fa564fa5c (diff)
downloadhorizon-5b0d0916b27f271fc12a8c0c6b595e11673d306d.tar.gz
horizon-5b0d0916b27f271fc12a8c0c6b595e11673d306d.tar.bz2
horizon-5b0d0916b27f271fc12a8c0c6b595e11673d306d.tar.xz
horizon-5b0d0916b27f271fc12a8c0c6b595e11673d306d.zip
hscript: Implement 'hostname' parsing; add rest of existing manual tests
-rw-r--r--hscript/CMakeLists.txt1
-rw-r--r--hscript/meta.cc41
-rw-r--r--hscript/meta.hh11
-rw-r--r--hscript/script.cc34
-rw-r--r--tests/spec/validator.rb32
5 files changed, 108 insertions, 11 deletions
diff --git a/hscript/CMakeLists.txt b/hscript/CMakeLists.txt
index 65126e4..02ef574 100644
--- a/hscript/CMakeLists.txt
+++ b/hscript/CMakeLists.txt
@@ -1,6 +1,7 @@
set(HSCRIPT_SOURCE
script.cc
key.cc
+ meta.cc
network.cc
)
diff --git a/hscript/meta.cc b/hscript/meta.cc
new file mode 100644
index 0000000..83c6269
--- /dev/null
+++ b/hscript/meta.cc
@@ -0,0 +1,41 @@
+/*
+ * metadata.cc - Implementation of the Key classes for system metadata
+ * libhscript, the HorizonScript library for
+ * Project Horizon
+ *
+ * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved.
+ * This code is licensed under the AGPL 3.0 license, as noted in the
+ * LICENSE-code file in the root directory of this repository.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+#include <regex>
+#include "meta.hh"
+#include "util/output.hh"
+
+using namespace Horizon::Keys;
+
+Key *Hostname::parseFromData(const std::string data, int lineno, int *errors,
+ int *warnings) {
+ std::regex valid_re("[A-Za-z0-9.]*");
+ bool valid = std::regex_match(data, valid_re);
+ if(!valid) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "hostname: expected machine or DNS name",
+ "'" + data + "' is not a valid hostname");
+ return nullptr;
+ }
+ return new Hostname(lineno, data);
+}
+
+bool Hostname::validate() const {
+ /* Validate that the name is a valid machine or DNS name */
+ return false;
+}
+
+bool Hostname::execute() const {
+ /* Write the hostname to /etc/hostname in the target environment. */
+ return false;
+}
diff --git a/hscript/meta.hh b/hscript/meta.hh
index 9491aac..626ce91 100644
--- a/hscript/meta.hh
+++ b/hscript/meta.hh
@@ -13,12 +13,23 @@
#ifndef __HSCRIPT_META_HH_
#define __HSCRIPT_META_HH_
+#include <string>
#include "key.hh"
namespace Horizon {
namespace Keys {
class Hostname : public Key {
+private:
+ const std::string _name;
+ Hostname(int _line, const std::string my_name) : Key(_line),
+ _name(my_name) {}
+public:
+ static Key *parseFromData(const std::string data, int lineno, int *errors,
+ int *warnings);
+ const std::string name() const { return this->_name; }
+ bool validate() const override;
+ bool execute() const override;
};
class PkgInstall : public Key {
diff --git a/hscript/script.cc b/hscript/script.cc
index a8101dc..8c0c380 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -85,24 +85,36 @@ struct Script::ScriptPrivate {
*/
bool store_key(const std::string key_name, Keys::Key *key_obj, int lineno,
int *errors, int *warnings) {
+#define DUPLICATE_ERROR(OBJ, KEY, OLD_VAL) \
+ std::string err_str("previous value was ");\
+ err_str += OLD_VAL;\
+ err_str += " at installfile:" + std::to_string(OBJ->lineno());\
+ if(errors) *errors += 1;\
+ output_error("installfile:" + std::to_string(lineno),\
+ "duplicate value for key '" + KEY + "'", err_str);
+
if(key_name == "network") {
if(this->network) {
- std::string err_str("previous value was ");
- err_str += this->network->test() ? "true" : "false";
- err_str += " at installfile:";
- err_str += std::to_string(this->network->lineno());
- if(errors) *errors += 1;
- output_error("installfile:" + std::to_string(lineno),
- "duplicate value for key 'network'",
- err_str);
+ DUPLICATE_ERROR(this->network, std::string("network"),
+ this->network->test() ? "true" : "false")
return false;
}
- std::unique_ptr<Keys::Network> net(dynamic_cast<Keys::Network *>(key_obj));
+ std::unique_ptr<Keys::Network> net(
+ dynamic_cast<Keys::Network *>(key_obj)
+ );
this->network = std::move(net);
return true;
} else if(key_name == "hostname") {
- /*! TODO: implement */
- return false;
+ if(this->hostname) {
+ DUPLICATE_ERROR(this->hostname, std::string("hostname"),
+ this->hostname->name())
+ return false;
+ }
+ std::unique_ptr<Keys::Hostname> name(
+ dynamic_cast<Keys::Hostname *>(key_obj)
+ );
+ this->hostname = std::move(name);
+ return true;
} else if(key_name == "pkginstall") {
/*! TODO: implement */
return false;
diff --git a/tests/spec/validator.rb b/tests/spec/validator.rb
index bd53853..e54d40e 100644
--- a/tests/spec/validator.rb
+++ b/tests/spec/validator.rb
@@ -50,6 +50,16 @@ RSpec.describe 'HorizonScript Validation Utility', :type => :aruba do
run_validate
expect(last_command_started).to have_output(SUCCESS_OUTPUT)
end
+ it "requires keys to have values" do
+ use_fixture '0015-keys-without-values.installfile'
+ run_validate ' --keep-going'
+ expect(last_command_started).to have_output(/5 error(s)/)
+ end
+ it "fails on lines over maximum line length" do
+ use_fixture '0017-line-too-long.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*length/)
+ end
context "required keys" do
it "fails without a 'network' key" do
use_fixture '0006-no-network.installfile'
@@ -77,6 +87,28 @@ RSpec.describe 'HorizonScript Validation Utility', :type => :aruba do
expect(last_command_started).to have_output(/error: .*mount.*/)
end
end
+ context "values" do
+ it "fails with an invalid 'network' value" do
+ use_fixture '0011-invalid-network.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*network.*/)
+ end
+ it "fails with an invalid 'hostname' value" do
+ use_fixture '0012-invalid-hostname.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*hostname.*/)
+ end
+ it "fails with an invalid 'rootpw' value" do
+ use_fixture '0013-invalid-rootpw.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*rootpw.*/)
+ end
+ it "fails with an invalid 'mount' value" do
+ use_fixture '0014-invalid-mount.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*mount.*/)
+ end
+ end
context "unique keys" do
it "fails with a duplicate 'network' key" do
use_fixture '0018-duplicate-network.installfile'