diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-10-31 18:03:00 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-10-31 18:03:00 -0500 |
commit | f97ac86dc0dadc20b53d66dade311e4b4e50b7fc (patch) | |
tree | a40a77feec79df0169a8e322e3f93febaba89bbc | |
parent | cce8d9ba1541ef977260472d54461019e0e415ae (diff) | |
download | horizon-f97ac86dc0dadc20b53d66dade311e4b4e50b7fc.tar.gz horizon-f97ac86dc0dadc20b53d66dade311e4b4e50b7fc.tar.bz2 horizon-f97ac86dc0dadc20b53d66dade311e4b4e50b7fc.tar.xz horizon-f97ac86dc0dadc20b53d66dade311e4b4e50b7fc.zip |
hscript: Implement fs, add tests
-rw-r--r-- | hscript/disk.cc | 52 | ||||
-rw-r--r-- | hscript/disk.hh | 15 | ||||
-rw-r--r-- | hscript/script.cc | 27 | ||||
-rw-r--r-- | tests/fixtures/0179-fs-basic.installfile | 9 | ||||
-rw-r--r-- | tests/fixtures/0180-fs-without-fs.installfile | 9 | ||||
-rw-r--r-- | tests/fixtures/0181-fs-invalid-dev.installfile | 9 | ||||
-rw-r--r-- | tests/fixtures/0182-fs-invalid-type.installfile | 9 | ||||
-rw-r--r-- | tests/spec/validator_spec.rb | 23 |
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' |