diff options
-rw-r--r-- | hscript/disk.cc | 23 | ||||
-rw-r--r-- | hscript/disk.hh | 7 | ||||
-rw-r--r-- | hscript/script.cc | 38 | ||||
-rw-r--r-- | tests/fixtures/0163-lvmpv-basic.installfile | 10 | ||||
-rw-r--r-- | tests/fixtures/0164-lvmpv-invalid.installfile | 10 | ||||
-rw-r--r-- | tests/fixtures/0165-lvmpv-duplicate.installfile | 11 | ||||
-rw-r--r-- | tests/spec/validator_spec.rb | 18 |
7 files changed, 115 insertions, 2 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc index c41e6d0..3423928 100644 --- a/hscript/disk.cc +++ b/hscript/disk.cc @@ -381,6 +381,29 @@ bool Partition::execute(ScriptOptions) const { } +Key *LVMPhysical::parseFromData(const std::string &data, int lineno, + int *errors, int *warnings) { + if(data.size() < 6 || data.substr(0, 5) != "/dev/") { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "lvm_pv: expected an absolute path to a block device"); + return nullptr; + } + + /*if(access(data.c_str(), F_OK) != 0) { + if(warnings) *warnings += 1; + output_warning("installfile:" + std::to_string(lineno), + "lvm_pv: device may not exist"); + }*/ + + return new LVMPhysical(lineno, data); +} + +bool LVMPhysical::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 90deca4..53527f3 100644 --- a/hscript/disk.hh +++ b/hscript/disk.hh @@ -116,7 +116,12 @@ public: class Encrypt : public Key { }; -class LVMPhysical : public Key { +class LVMPhysical : public StringKey { +private: + LVMPhysical(int _line, const std::string &_d) : StringKey(_line, _d) {} +public: + static Key *parseFromData(const std::string &, int, int*, int*); + bool execute(ScriptOptions) const override; }; class LVMGroup : public Key { diff --git a/hscript/script.cc b/hscript/script.cc index afb1870..cd15089 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -110,6 +110,12 @@ struct Script::ScriptPrivate { std::vector< std::unique_ptr<DiskLabel> > disklabels; /*! Partition creation keys */ std::vector< std::unique_ptr<Partition> > partitions; + /*! LVM physical volume keys */ + std::vector< std::unique_ptr<LVMPhysical> > lvm_pvs; + /*! LVM volume group keys */ + std::vector< std::unique_ptr<LVMGroup> > lvm_vgs; + /*! LVM logical volume keys */ + std::vector< std::unique_ptr<LVMVolume> > lvm_lvs; /*! Target system's mountpoints. */ std::vector< std::unique_ptr<Mount> > mounts; @@ -174,6 +180,18 @@ struct Script::ScriptPrivate { std::unique_ptr<Partition> p(dynamic_cast<Partition *>(obj)); this->partitions.push_back(std::move(p)); return true; + } else if(key_name == "lvm_pv") { + std::unique_ptr<LVMPhysical> pv(dynamic_cast<LVMPhysical *>(obj)); + this->lvm_pvs.push_back(std::move(pv)); + return true; + } else if(key_name == "lvm_vg") { + std::unique_ptr<LVMGroup> vg(dynamic_cast<LVMGroup *>(obj)); + this->lvm_vgs.push_back(std::move(vg)); + return true; + } else if(key_name == "lvm_lv") { + std::unique_ptr<LVMVolume> lv(dynamic_cast<LVMVolume *>(obj)); + this->lvm_lvs.push_back(std::move(lv)); + return true; } else if(key_name == "mount") { std::unique_ptr<Mount> mount(dynamic_cast<Mount *>(obj)); this->mounts.push_back(std::move(mount)); @@ -526,7 +544,8 @@ const Script *Script::load(std::istream &sstream, bool Script::validate() const { int failures = 0; - std::set<std::string> seen_diskids, seen_labels, seen_parts, seen_mounts; + std::set<std::string> seen_diskids, seen_labels, seen_parts, seen_pvs, + seen_mounts; std::map<const std::string, int> seen_iface; /* REQ: Runner.Validate.network */ @@ -779,6 +798,23 @@ bool Script::validate() const { seen_parts.insert(name); } + /* REQ: Runner.Validate.lvm_pv */ + for(auto &pv : this->internal->lvm_pvs) { + if(!pv->validate(this->opts)) { + failures++; + continue; + } + + /* We don't actually have a requirement, but... */ + if(seen_pvs.find(pv->value()) != seen_pvs.end()) { + failures++; + output_error("installfile:" + std::to_string(pv->lineno()), + "lvm_pv: a physical volume already exists on device " + + pv->value()); + } + seen_pvs.insert(pv->value()); + } + /* REQ: Runner.Validate.mount */ for(auto &mount : this->internal->mounts) { if(!mount->validate(this->opts)) { diff --git a/tests/fixtures/0163-lvmpv-basic.installfile b/tests/fixtures/0163-lvmpv-basic.installfile new file mode 100644 index 0000000..9712ccd --- /dev/null +++ b/tests/fixtures/0163-lvmpv-basic.installfile @@ -0,0 +1,10 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +diskid /dev/sdb WDC +disklabel /dev/sdb apm +partition /dev/sdb 1 8M boot +partition /dev/sdb 2 fill +lvm_pv /dev/sdb2 diff --git a/tests/fixtures/0164-lvmpv-invalid.installfile b/tests/fixtures/0164-lvmpv-invalid.installfile new file mode 100644 index 0000000..3abe2e5 --- /dev/null +++ b/tests/fixtures/0164-lvmpv-invalid.installfile @@ -0,0 +1,10 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +diskid /dev/sdb WDC +disklabel /dev/sdb apm +partition /dev/sdb 1 8M boot +partition /dev/sdb 2 fill +lvm_pv sdb2 diff --git a/tests/fixtures/0165-lvmpv-duplicate.installfile b/tests/fixtures/0165-lvmpv-duplicate.installfile new file mode 100644 index 0000000..1ec5ed8 --- /dev/null +++ b/tests/fixtures/0165-lvmpv-duplicate.installfile @@ -0,0 +1,11 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +diskid /dev/sdb WDC +disklabel /dev/sdb apm +partition /dev/sdb 1 8M boot +partition /dev/sdb 2 fill +lvm_pv /dev/sdb2 +lvm_pv /dev/sdb2 diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb index df504ca..976f0f6 100644 --- a/tests/spec/validator_spec.rb +++ b/tests/spec/validator_spec.rb @@ -788,6 +788,24 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do expect(last_command_started).to have_output(/error: .*partition.*size/) end end + context "for 'lvm_pv' key" do + it "succeeds with normal value" do + use_fixture '0163-lvmpv-basic.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "fails with a non-absolute block device path" do + use_fixture '0164-lvmpv-invalid.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_pv.*path/) + end + it "fails with duplicate physical volumes" do + use_fixture '0165-lvmpv-duplicate.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_pv.*exists/) + end + end end context "unique keys" do # Runner.Validate.network. |