From 0d626d668ba6c14022ca88611aff2365cbe4f30c Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Thu, 31 Oct 2019 13:05:47 -0500 Subject: hscript: Implement lvm_lv, add tests --- hscript/disk.cc | 56 +++++++++++++++++++++++++ hscript/disk.hh | 22 ++++++++++ hscript/script.cc | 35 +++++++++++++++- tests/fixtures/0171-lvmlv-basic.installfile | 12 ++++++ tests/fixtures/0172-lvmlv-badvg.installfile | 12 ++++++ tests/fixtures/0173-lvmlv-badlv.installfile | 12 ++++++ tests/fixtures/0174-lvmlv-bad-size.installfile | 12 ++++++ tests/fixtures/0175-lvmlv-invalid.installfile | 12 ++++++ tests/fixtures/0176-lvmlv-duplicate.installfile | 13 ++++++ tests/fixtures/0177-lvmlv-no-vg.installfile | 6 +++ tests/spec/validator_spec.rb | 39 +++++++++++++++++ 11 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/0171-lvmlv-basic.installfile create mode 100644 tests/fixtures/0172-lvmlv-badvg.installfile create mode 100644 tests/fixtures/0173-lvmlv-badlv.installfile create mode 100644 tests/fixtures/0174-lvmlv-bad-size.installfile create mode 100644 tests/fixtures/0175-lvmlv-invalid.installfile create mode 100644 tests/fixtures/0176-lvmlv-duplicate.installfile create mode 100644 tests/fixtures/0177-lvmlv-no-vg.installfile diff --git a/hscript/disk.cc b/hscript/disk.cc index a8c70db..a54b36d 100644 --- a/hscript/disk.cc +++ b/hscript/disk.cc @@ -550,6 +550,62 @@ bool LVMGroup::execute(ScriptOptions) const { } +Key *LVMVolume::parseFromData(const std::string &data, int lineno, int *errors, + int *) { + std::string vg, name, size_str; + std::string::size_type name_start, size_start; + SizeType size_type; + uint64_t size; + + long spaces = std::count(data.cbegin(), data.cend(), ' '); + if(spaces != 2) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "lvm_lv: expected 3 elements, got: " + + std::to_string(spaces), + "syntax is: lvm_lv [vg] [name] [size]"); + return nullptr; + } + + name_start = data.find_first_of(' '); + vg = data.substr(0, name_start); + size_start = data.find_first_of(' ', name_start + 1); + name = data.substr(name_start + 1, size_start - name_start - 1); + size_str = data.substr(size_start + 1); + + if(!is_valid_lvm_name(vg)) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "lvm_lv: invalid volume group name"); + return nullptr; + } + + if(!is_valid_lvm_lv_name(name)) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "lvm_lv: invalid volume name"); + return nullptr; + } + + if(!parse_size_string(size_str, &size, &size_type)) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "lvm_lv: invalid size", size_str); + return nullptr; + } + + return new LVMVolume(lineno, vg, name, size_type, size); +} + +bool LVMVolume::validate(ScriptOptions) const { + return true; +} + +bool LVMVolume::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 a9adba4..43bb56d 100644 --- a/hscript/disk.hh +++ b/hscript/disk.hh @@ -145,6 +145,28 @@ public: }; class LVMVolume : public Key { +private: + const std::string _vg; + const std::string _lvname; + const SizeType _size_type; + const uint64_t _size; + + LVMVolume(int _line, const std::string &_v, const std::string &_n, + SizeType _t, uint64_t _s) : Key(_line), _vg(_v), _lvname(_n), + _size_type(_t), _size(_s) {} +public: + /*! Retrieve the volume group to which this volume belongs. */ + const std::string vg() const { return this->_vg; } + /*! Retrieve the name of this volume. */ + const std::string name() const { return this->_lvname; } + /*! Retrieve the type of size that this volume uses. */ + SizeType size_type() const { return this->_size_type; } + /*! Retrieve the size of this volume. */ + uint64_t size() const { return this->_size; } + + static Key *parseFromData(const std::string &, int, int*, int*); + bool validate(ScriptOptions) const override; + bool execute(ScriptOptions) const override; }; class Filesystem : public Key { diff --git a/hscript/script.cc b/hscript/script.cc index 357ed15..f1fa5d6 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -672,7 +672,7 @@ bool add_default_repos(std::vector> &repos) { bool Script::validate() const { int failures = 0; std::set seen_diskids, seen_labels, seen_parts, seen_pvs, - seen_vg_names, seen_vg_pvs, seen_mounts; + seen_vg_names, seen_vg_pvs, seen_lvs, seen_mounts; std::map seen_iface; /* REQ: Runner.Validate.network */ @@ -879,7 +879,7 @@ bool Script::validate() const { "lvm_vg: a physical volume does not exist on " + vg->pv()); } -#endif +#endif /* HAS_INSTALL_ENV */ } else { /* We can't tell if we aren't running on the target. */ output_warning("installfile:" + std::to_string(vg->lineno()), @@ -889,6 +889,37 @@ bool Script::validate() const { } } + /* REQ: Runner.Validate.lvm_lv */ + for(auto &lv : this->internal->lvm_lvs) { + const std::string lvpath(lv->vg() + "/" + lv->name()); + if(!lv->validate(this->opts)) { + failures++; + continue; + } + + if(seen_lvs.find(lvpath) != seen_lvs.end()) { + failures++; + output_error("installfile:" + std::to_string(lv->lineno()), + "lvm_lv: a volume with the name " + lv->name() + + " already exists on the volume group " + lv->vg()); + } + seen_lvs.insert(lvpath); + + 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)) { +#ifdef HAS_INSTALL_ENV + if(!fs::exists("/dev/" + lv->vg())) { + failures++; + output_error("installfile:" + std::to_string(lv->lineno()), + "lvm_lv: volume group " + lv->vg() + + " does not exist"); + } +#endif /* HAS_INSTALL_ENV */ + } + } + } + /* REQ: Runner.Validate.mount */ for(auto &mount : this->internal->mounts) { if(!mount->validate(this->opts)) { diff --git a/tests/fixtures/0171-lvmlv-basic.installfile b/tests/fixtures/0171-lvmlv-basic.installfile new file mode 100644 index 0000000..8c5e4d8 --- /dev/null +++ b/tests/fixtures/0171-lvmlv-basic.installfile @@ -0,0 +1,12 @@ +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_vg /dev/sdb2 MyVolGroup +lvm_lv MyVolGroup root fill diff --git a/tests/fixtures/0172-lvmlv-badvg.installfile b/tests/fixtures/0172-lvmlv-badvg.installfile new file mode 100644 index 0000000..fe28560 --- /dev/null +++ b/tests/fixtures/0172-lvmlv-badvg.installfile @@ -0,0 +1,12 @@ +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_vg /dev/sdb2 MyVolGroup +lvm_lv -MyVolGroup root fill diff --git a/tests/fixtures/0173-lvmlv-badlv.installfile b/tests/fixtures/0173-lvmlv-badlv.installfile new file mode 100644 index 0000000..da20e5e --- /dev/null +++ b/tests/fixtures/0173-lvmlv-badlv.installfile @@ -0,0 +1,12 @@ +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_vg /dev/sdb2 MyVolGroup +lvm_lv MyVolGroup xml_cdata fill diff --git a/tests/fixtures/0174-lvmlv-bad-size.installfile b/tests/fixtures/0174-lvmlv-bad-size.installfile new file mode 100644 index 0000000..8cf747e --- /dev/null +++ b/tests/fixtures/0174-lvmlv-bad-size.installfile @@ -0,0 +1,12 @@ +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_vg /dev/sdb2 MyVolGroup +lvm_lv MyVolGroup root 9Z diff --git a/tests/fixtures/0175-lvmlv-invalid.installfile b/tests/fixtures/0175-lvmlv-invalid.installfile new file mode 100644 index 0000000..74bf7ab --- /dev/null +++ b/tests/fixtures/0175-lvmlv-invalid.installfile @@ -0,0 +1,12 @@ +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_vg /dev/sdb2 MyVolGroup +lvm_lv MyVolGroup root diff --git a/tests/fixtures/0176-lvmlv-duplicate.installfile b/tests/fixtures/0176-lvmlv-duplicate.installfile new file mode 100644 index 0000000..c5045bb --- /dev/null +++ b/tests/fixtures/0176-lvmlv-duplicate.installfile @@ -0,0 +1,13 @@ +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_vg /dev/sdb2 MyVolGroup +lvm_lv MyVolGroup root fill +lvm_lv MyVolGroup root fill diff --git a/tests/fixtures/0177-lvmlv-no-vg.installfile b/tests/fixtures/0177-lvmlv-no-vg.installfile new file mode 100644 index 0000000..509f258 --- /dev/null +++ b/tests/fixtures/0177-lvmlv-no-vg.installfile @@ -0,0 +1,6 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +mount /dev/sda1 / +lvm_lv NonExistentGroup root fill diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb index 0443140..21def58 100644 --- a/tests/spec/validator_spec.rb +++ b/tests/spec/validator_spec.rb @@ -834,6 +834,45 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do expect(last_command_started).to have_output(/error: .*lvm_vg.*expected/) end end + context "for 'lvm_lv' key" do + it "succeeds with a simple value" do + use_fixture '0171-lvmlv-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 valid volume group name" do + use_fixture '0172-lvmlv-badvg.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_lv.*name/) + end + it "requires a valid logical volume name" do + use_fixture '0173-lvmlv-badlv.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_lv.*name/) + end + it "requires a valid size" do + use_fixture '0174-lvmlv-bad-size.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_lv.*size/) + end + it "requires a size to be specified" do + use_fixture '0175-lvmlv-invalid.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_lv.*expected/) + end + it "requires a unique VG/LV name pair" do + use_fixture '0176-lvmlv-duplicate.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*lvm_lv.*already/) + end + it "requires the volume group to be present" do + use_fixture '0177-lvmlv-no-vg.installfile' + run_validate ' -i' + skip "This build does not support this test" if last_command_started.stdout =~ /runtime environment only/ + expect(last_command_started).to have_output(/error: .*lvm_lv.*volume group/) + end + end end context "unique keys" do # Runner.Validate.network. -- cgit v1.2.3-70-g09d2