summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/disk.cc52
-rw-r--r--hscript/disk.hh15
-rw-r--r--hscript/script.cc27
-rw-r--r--tests/fixtures/0179-fs-basic.installfile9
-rw-r--r--tests/fixtures/0180-fs-without-fs.installfile9
-rw-r--r--tests/fixtures/0181-fs-invalid-dev.installfile9
-rw-r--r--tests/fixtures/0182-fs-invalid-type.installfile9
-rw-r--r--tests/spec/validator_spec.rb23
8 files changed, 152 insertions, 1 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc
index a54b36d..72604d9 100644
--- a/hscript/disk.cc
+++ b/hscript/disk.cc
@@ -13,6 +13,7 @@
#include <algorithm>
#include <cstring> /* strerror */
#include <fstream>
+#include <set>
#include <string>
#ifdef HAS_INSTALL_ENV
# include <assert.h> /* assert */
@@ -606,6 +607,57 @@ bool LVMVolume::execute(ScriptOptions) const {
}
+const static std::set<std::string> valid_fses = {
+ "ext2", "ext3", "ext4", "jfs", "vfat", "xfs"
+};
+
+
+Key *Filesystem::parseFromData(const std::string &data, int lineno,
+ int *errors, int *) {
+ if(std::count(data.begin(), data.end(), ' ') != 1) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "fs: expected exactly two elements",
+ "syntax is: fs [device] [fstype]");
+ return nullptr;
+ }
+
+ std::string::size_type sep = data.find(' ');
+ std::string device(data.substr(0, sep));
+ std::string fstype(data.substr(sep + 1));
+
+ if(device.size() < 6 || device.compare(0, 5, "/dev/")) {
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "fs: element 1: expected device node",
+ "'" + device + "' is not a valid device node");
+ return nullptr;
+ }
+
+ if(valid_fses.find(fstype) == valid_fses.end()) {
+ std::string fses;
+ for(auto &&fs : valid_fses) fses += fs + " ";
+
+ if(errors) *errors += 1;
+ output_error("installfile:" + std::to_string(lineno),
+ "fs: element 2: expected filesystem type",
+ "valid filesystems are: " + fses);
+ return nullptr;
+ }
+
+ return new Filesystem(lineno, device, fstype);
+}
+
+bool Filesystem::validate(ScriptOptions) const {
+ /* Validation is done during parsing. */
+ return true;
+}
+
+bool Filesystem::execute(ScriptOptions) const {
+ return false;
+}
+
+
Key *Mount::parseFromData(const std::string &data, int lineno, int *errors,
int *warnings) {
std::string dev, where, opt;
diff --git a/hscript/disk.hh b/hscript/disk.hh
index 43bb56d..53e2749 100644
--- a/hscript/disk.hh
+++ b/hscript/disk.hh
@@ -170,6 +170,21 @@ public:
};
class Filesystem : public Key {
+private:
+ const std::string _block;
+ const std::string _type;
+
+ Filesystem(int _line, const std::string &_b, const std::string &_t) :
+ Key(_line), _block(_b), _type(_t) {}
+public:
+ /*! Retrieve the block device on which to create the filesystem. */
+ const std::string device() const { return this->_block; }
+ /*! Retreive the type of filesystem to create. */
+ const std::string fstype() const { return this->_type; }
+
+ static Key *parseFromData(const std::string &, int, int*, int*);
+ bool validate(ScriptOptions) const override;
+ bool execute(ScriptOptions) const override;
};
class Mount : public Key {
diff --git a/hscript/script.cc b/hscript/script.cc
index dae014c..050bb01 100644
--- a/hscript/script.cc
+++ b/hscript/script.cc
@@ -118,6 +118,8 @@ struct Script::ScriptPrivate {
std::vector< std::unique_ptr<LVMGroup> > lvm_vgs;
/*! LVM logical volume keys */
std::vector< std::unique_ptr<LVMVolume> > lvm_lvs;
+ /*! Filesystem creation keys */
+ std::vector< std::unique_ptr<Filesystem> > fses;
/*! Target system's mountpoints. */
std::vector< std::unique_ptr<Mount> > mounts;
@@ -196,6 +198,10 @@ struct Script::ScriptPrivate {
std::unique_ptr<LVMVolume> lv(dynamic_cast<LVMVolume *>(obj));
this->lvm_lvs.push_back(std::move(lv));
return true;
+ } else if(key_name == "fs") {
+ std::unique_ptr<Filesystem> fs(dynamic_cast<Filesystem *>(obj));
+ this->fses.push_back(std::move(fs));
+ return true;
} else if(key_name == "mount") {
std::unique_ptr<Mount> mount(dynamic_cast<Mount *>(obj));
this->mounts.push_back(std::move(mount));
@@ -687,7 +693,7 @@ bool add_default_repos(std::vector<std::unique_ptr<Keys::Repository>> &repos) {
bool Script::validate() const {
int failures = 0;
std::set<std::string> seen_diskids, seen_labels, seen_parts, seen_pvs,
- seen_vg_names, seen_vg_pvs, seen_lvs, seen_mounts;
+ seen_vg_names, seen_vg_pvs, seen_lvs, seen_fses, seen_mounts;
std::map<const std::string, int> seen_iface;
/* REQ: Runner.Validate.network */
@@ -913,6 +919,7 @@ bool Script::validate() const {
continue;
}
+ /* REQ: Runner.Validate.lvm_lv.Name */
if(seen_lvs.find(lvpath) != seen_lvs.end()) {
failures++;
output_error("installfile:" + std::to_string(lv->lineno()),
@@ -921,6 +928,7 @@ bool Script::validate() const {
}
seen_lvs.insert(lvpath);
+ /* REQ: Runner.Validate.lvm_lv.VolumeGroup */
if(seen_vg_names.find(lv->vg()) == seen_vg_names.end()) {
/* Let's make sure it still exists, if we are running in the IE */
if(opts.test(InstallEnvironment)) {
@@ -936,6 +944,23 @@ bool Script::validate() const {
}
}
+ /* REQ: Runner.Validate.fs */
+ for(auto &fs : this->internal->fses) {
+ if(!fs->validate(this->opts)) {
+ failures++;
+ continue;
+ }
+
+ /* REQ: Runner.Validate.fs.Unique */
+ if(seen_fses.find(fs->device()) != seen_fses.end()) {
+ failures++;
+ output_error("installfile:" + std::to_string(fs->lineno()),
+ "fs: a filesystem is already scheduled to be "
+ "created on " + fs->device());
+ }
+ seen_fses.insert(fs->device());
+ }
+
/* REQ: Runner.Validate.mount */
for(auto &mount : this->internal->mounts) {
if(!mount->validate(this->opts)) {
diff --git a/tests/fixtures/0179-fs-basic.installfile b/tests/fixtures/0179-fs-basic.installfile
new file mode 100644
index 0000000..6990c07
--- /dev/null
+++ b/tests/fixtures/0179-fs-basic.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+fs /dev/sdb1 ext4
+mount /dev/sdb1 /
diff --git a/tests/fixtures/0180-fs-without-fs.installfile b/tests/fixtures/0180-fs-without-fs.installfile
new file mode 100644
index 0000000..f113018
--- /dev/null
+++ b/tests/fixtures/0180-fs-without-fs.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+fs /dev/sdb1
+mount /dev/sdb1 /
diff --git a/tests/fixtures/0181-fs-invalid-dev.installfile b/tests/fixtures/0181-fs-invalid-dev.installfile
new file mode 100644
index 0000000..5a3a67f
--- /dev/null
+++ b/tests/fixtures/0181-fs-invalid-dev.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+fs sdb1 ext4
+mount /dev/sdb1 /
diff --git a/tests/fixtures/0182-fs-invalid-type.installfile b/tests/fixtures/0182-fs-invalid-type.installfile
new file mode 100644
index 0000000..4a88048
--- /dev/null
+++ b/tests/fixtures/0182-fs-invalid-type.installfile
@@ -0,0 +1,9 @@
+network false
+hostname test.machine
+pkginstall adelie-base
+rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/
+diskid /dev/sdb WDBNCE2500PNC
+disklabel /dev/sdb gpt
+partition /dev/sdb 1 fill
+fs /dev/sdb1 ntfs
+mount /dev/sdb1 /
diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb
index c4e5ac2..c36e5a1 100644
--- a/tests/spec/validator_spec.rb
+++ b/tests/spec/validator_spec.rb
@@ -873,6 +873,29 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do
expect(last_command_started).to have_output(/error: .*lvm_lv.*volume group/)
end
end
+ context "for 'fs' key" do
+ it "succeeds with a simple value" do
+ use_fixture '0179-fs-basic.installfile'
+ run_validate
+ expect(last_command_started).to have_output(PARSER_SUCCESS)
+ expect(last_command_started).to have_output(VALIDATOR_SUCCESS)
+ end
+ it "requires a filesystem type" do
+ use_fixture '0180-fs-without-fs.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*fs.*expected/)
+ end
+ it "requires a valid absolute block device path" do
+ use_fixture '0181-fs-invalid-dev.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*fs.*device/)
+ end
+ it "requires a valid filesystem type" do
+ use_fixture '0182-fs-invalid-type.installfile'
+ run_validate
+ expect(last_command_started).to have_output(/error: .*fs.*type/)
+ end
+ end
context "for 'keymap' key" do
it "succeeds with a simple value" do
use_fixture '0178-keymap-basic.installfile'