diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-10-25 04:35:58 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2019-10-25 04:35:58 -0500 |
commit | ec32bbe2c9a77ae150de08e14c0a30e33ac5e321 (patch) | |
tree | bb920df38fc77fbf21246a05e3569d9917184089 | |
parent | 4755175ad26eaff1765407bb01f8820f394f847b (diff) | |
download | horizon-ec32bbe2c9a77ae150de08e14c0a30e33ac5e321.tar.gz horizon-ec32bbe2c9a77ae150de08e14c0a30e33ac5e321.tar.bz2 horizon-ec32bbe2c9a77ae150de08e14c0a30e33ac5e321.tar.xz horizon-ec32bbe2c9a77ae150de08e14c0a30e33ac5e321.zip |
hscript: Implement Partition, add tests
32 files changed, 648 insertions, 1 deletions
diff --git a/hscript/disk.cc b/hscript/disk.cc index 875d84f..c41e6d0 100644 --- a/hscript/disk.cc +++ b/hscript/disk.cc @@ -189,6 +189,198 @@ bool DiskLabel::execute(ScriptOptions) const { } +/*! Parse a size string into a size and type. + * @param in_size (in) The string to parse. + * @param out_size (out) Where to which to write the size in bytes or %. + * @param type (out) The type of size determined. + * @returns true if the string was parseable, false otherwise. + */ +bool parse_size_string(const std::string &in_size, uint64_t *out_size, SizeType *type) { + std::string size(in_size), numbers, suffix; + std::string::size_type suffix_pos; + uint64_t multiplicand = 0; + + /* Validate parameters */ + if(out_size == nullptr || type == nullptr) { + return false; + } + + /* Simpler since the string isn't case-sensitive. */ + std::transform(size.cbegin(), size.cend(), size.begin(), ::tolower); + + if(size == "fill") { + /* That was easy™ */ + *type = SizeType::Fill; + *out_size = 0; + return true; + } + + if(size.size() <= 1) { + /* at least two characters are required: + * - a 9 byte partition is invalid + */ + return false; + } + + if(size.size() > 21) { + output_error("partition", "Value too large"); + return false; + } + + suffix_pos = size.find_first_not_of("12345667890"); + /* this is always correct unless suffix is %, which is handled below */ + *type = SizeType::Bytes; + try { + *out_size = std::stoul(size.substr(0, suffix_pos)); + } catch(const std::exception &) { + /* something is wrong; throw the same error as a non-numeric value */ + suffix_pos = 0; + } + + if(suffix_pos == std::string::npos) { + output_warning("partition", "size has no suffix; assuming bytes"); + return true; + } + + if(suffix_pos == 0) { + output_error("partition", "size must be a whole number, " + "followed by optional suffix [K|M|G|T|%]"); + return false; + } + + suffix = size.substr(suffix_pos); + +#define OVERFLOW_ON(MAX_VAL) \ + if(*out_size > MAX_VAL) {\ + output_error("partition", "Value too large");\ + return false;\ + } + + switch(suffix[0]) { + case 'k': + multiplicand = 1024; + OVERFLOW_ON(0x3FFFFFFFFFFFFF) + break; + case 'm': + multiplicand = 1048576; + OVERFLOW_ON(0xFFFFFFFFFFF) + break; + case 'g': + multiplicand = 1073741824; + OVERFLOW_ON(0x3FFFFFFFF) + break; + case 't': + multiplicand = 1099511627776; + OVERFLOW_ON(0xFFFFFF) + break; + case '%': + *type = SizeType::Percent; + multiplicand = 1; + OVERFLOW_ON(100) + break; + } + +#undef OVERFLOW_ON + + /* if multiplicand is 0, it's an invalid suffix. */ + if(suffix.size() != 1 || multiplicand == 0) { + output_error("partition", "size suffix must be K, M, G, T, or %"); + return false; + } + + *out_size *= multiplicand; + return true; +} + + +Key *Partition::parseFromData(const std::string &data, int lineno, int *errors, + int *) { + std::string block, pno, size_str, typecode; + std::string::size_type next_pos, last_pos; + int part_no; + SizeType size_type; + uint64_t size; + PartitionType type = None; + + long spaces = std::count(data.cbegin(), data.cend(), ' '); + if(spaces < 2 || spaces > 3) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "partition: expected either 3 or 4 elements, got: " + + std::to_string(spaces), + "syntax is: partition [block] [#] [size] ([type])"); + return nullptr; + } + + last_pos = next_pos = data.find_first_of(' '); + block = data.substr(0, next_pos); + + if(block.compare(0, 4, "/dev")) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "partition: expected path to block device", + "'" + block + "' is not a valid block device path"); + return nullptr; + } + + next_pos = data.find_first_of(' ', last_pos + 1); + pno = data.substr(last_pos + 1, next_pos - last_pos); + try { + part_no = std::stoi(pno); + } catch(const std::exception &) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "partition: expected partition number, got", pno); + return nullptr; + } + last_pos = next_pos; + next_pos = data.find_first_of(' ', last_pos + 1); + if(next_pos == std::string::npos) { + size_str = data.substr(last_pos + 1); + } else { + size_str = data.substr(last_pos + 1, next_pos - last_pos - 1); + typecode = data.substr(next_pos + 1); + } + if(!parse_size_string(size_str, &size, &size_type)) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "partition: invalid size", size_str); + return nullptr; + } + + if(!typecode.empty()) { + std::transform(typecode.cbegin(), typecode.cend(), typecode.begin(), + ::tolower); + if(typecode == "boot") { + type = Boot; + } else if(typecode == "esp") { + type = ESP; + } else { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "partition: expected type code, got: " + typecode, + "valid type codes are 'boot' and 'esp'"); + return nullptr; + } + } + + return new Partition(lineno, block, part_no, size_type, size, type); +} + +bool Partition::validate(ScriptOptions opts) const { +#ifdef HAS_INSTALL_ENV + if(opts.test(InstallEnvironment)) { + return is_block_device("partition", this->lineno(), this->device()); + } +#endif /* HAS_INSTALL_ENV */ + return true; +} + +bool Partition::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 f8a9574..90deca4 100644 --- a/hscript/disk.hh +++ b/hscript/disk.hh @@ -64,7 +64,53 @@ public: bool execute(ScriptOptions) const override; }; +/*! The type of size a disk key has */ +enum SizeType { + /*! Sized in bytes */ + Bytes, + /*! Sized as a percentage of the whole disk */ + Percent, + /*! Fill the rest of the disk */ + Fill +}; + class Partition : public Key { +public: + /*! Valid partition type codes */ + enum PartitionType { + /*! None (default) */ + None = 0, + /*! Bootable */ + Boot, + /*! EFI System Partition (GPT only) */ + ESP + }; +private: + const std::string _block; + const int _partno; + const SizeType _size_type; + const uint64_t _size; + const PartitionType _type; + + Partition(int _line, const std::string &_b, const int _p, + const SizeType _st, const uint64_t _s, const PartitionType _pt) : + Key(_line), _block(_b), _partno(_p), _size_type(_st), _size(_s), + _type(_pt) {} +public: + /*! Retrieve the block device that this key identifies. */ + const std::string device() const { return this->_block; } + /*! Retrieve the partition number that this key identifies. */ + int partno() const { return this->_partno; } + /*! Retrieve the type of size that this partition uses. */ + SizeType size_type() const { return this->_size_type; } + /*! Retrieve the size of this partition. */ + uint64_t size() const { return this->_size; } + /*! Retrieve the Type Code of this partition, if any. */ + PartitionType type() const { return this->_type; } + + static Key *parseFromData(const std::string &, int, int*, int*); + bool validate(ScriptOptions) const override; + bool execute(ScriptOptions) const override; }; class Encrypt : public Key { diff --git a/hscript/script.cc b/hscript/script.cc index 63ea3de..afb1870 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -108,6 +108,8 @@ struct Script::ScriptPrivate { std::vector< std::unique_ptr<DiskId> > diskids; /*! Disklabel configuration keys */ std::vector< std::unique_ptr<DiskLabel> > disklabels; + /*! Partition creation keys */ + std::vector< std::unique_ptr<Partition> > partitions; /*! Target system's mountpoints. */ std::vector< std::unique_ptr<Mount> > mounts; @@ -168,6 +170,10 @@ struct Script::ScriptPrivate { std::unique_ptr<DiskLabel> l(dynamic_cast<DiskLabel *>(obj)); this->disklabels.push_back(std::move(l)); return true; + } else if(key_name == "partition") { + std::unique_ptr<Partition> p(dynamic_cast<Partition *>(obj)); + this->partitions.push_back(std::move(p)); + return true; } else if(key_name == "mount") { std::unique_ptr<Mount> mount(dynamic_cast<Mount *>(obj)); this->mounts.push_back(std::move(mount)); @@ -520,7 +526,7 @@ const Script *Script::load(std::istream &sstream, bool Script::validate() const { int failures = 0; - std::set<std::string> seen_diskids, seen_labels, seen_mounts; + std::set<std::string> seen_diskids, seen_labels, seen_parts, seen_mounts; std::map<const std::string, int> seen_iface; /* REQ: Runner.Validate.network */ @@ -754,6 +760,25 @@ bool Script::validate() const { seen_labels.insert(label->device()); } + /* REQ: Runner.Validate.partition */ + for(auto &part : this->internal->partitions) { + if(!part->validate(this->opts)) { + failures++; + continue; + } + + /* REQ: Runner.Validate.partition.Unique */ + std::string name = part->device() + std::to_string(part->partno()); + if(seen_parts.find(name) != seen_parts.end()) { + failures++; + output_error("installfile:" + std::to_string(part->lineno()), + "partition: partition #" + + std::to_string(part->partno()) + + " already exists on device " + part->device()); + } + seen_parts.insert(name); + } + /* REQ: Runner.Validate.mount */ for(auto &mount : this->internal->mounts) { if(!mount->validate(this->opts)) { diff --git a/tests/fixtures/0135-partition-basic.installfile b/tests/fixtures/0135-partition-basic.installfile new file mode 100644 index 0000000..3e01567 --- /dev/null +++ b/tests/fixtures/0135-partition-basic.installfile @@ -0,0 +1,8 @@ +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 +mount /dev/sdb1 / diff --git a/tests/fixtures/0136-partition-size-bytes.installfile b/tests/fixtures/0136-partition-size-bytes.installfile new file mode 100644 index 0000000..07caa90 --- /dev/null +++ b/tests/fixtures/0136-partition-size-bytes.installfile @@ -0,0 +1,8 @@ +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 1048576 +mount /dev/sdb1 / diff --git a/tests/fixtures/0137-partition-size-kbytes.installfile b/tests/fixtures/0137-partition-size-kbytes.installfile new file mode 100644 index 0000000..45a82e2 --- /dev/null +++ b/tests/fixtures/0137-partition-size-kbytes.installfile @@ -0,0 +1,8 @@ +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 1048576K +mount /dev/sdb1 / diff --git a/tests/fixtures/0138-partition-size-mbytes.installfile b/tests/fixtures/0138-partition-size-mbytes.installfile new file mode 100644 index 0000000..c6dfc79 --- /dev/null +++ b/tests/fixtures/0138-partition-size-mbytes.installfile @@ -0,0 +1,8 @@ +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 1024M +mount /dev/sdb1 / diff --git a/tests/fixtures/0139-partition-size-gbytes.installfile b/tests/fixtures/0139-partition-size-gbytes.installfile new file mode 100644 index 0000000..4921abf --- /dev/null +++ b/tests/fixtures/0139-partition-size-gbytes.installfile @@ -0,0 +1,8 @@ +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 20G +mount /dev/sdb1 / diff --git a/tests/fixtures/0140-partition-size-tbytes.installfile b/tests/fixtures/0140-partition-size-tbytes.installfile new file mode 100644 index 0000000..04769eb --- /dev/null +++ b/tests/fixtures/0140-partition-size-tbytes.installfile @@ -0,0 +1,8 @@ +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 1T +mount /dev/sdb1 / diff --git a/tests/fixtures/0141-partition-size-ebytes.installfile b/tests/fixtures/0141-partition-size-ebytes.installfile new file mode 100644 index 0000000..5d41250 --- /dev/null +++ b/tests/fixtures/0141-partition-size-ebytes.installfile @@ -0,0 +1,8 @@ +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 2E +mount /dev/sdb1 / diff --git a/tests/fixtures/0142-partition-size-percent.installfile b/tests/fixtures/0142-partition-size-percent.installfile new file mode 100644 index 0000000..da4ca7d --- /dev/null +++ b/tests/fixtures/0142-partition-size-percent.installfile @@ -0,0 +1,8 @@ +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 50% +mount /dev/sdb1 / diff --git a/tests/fixtures/0143-partition-size-percent-overflow.installfile b/tests/fixtures/0143-partition-size-percent-overflow.installfile new file mode 100644 index 0000000..d180063 --- /dev/null +++ b/tests/fixtures/0143-partition-size-percent-overflow.installfile @@ -0,0 +1,8 @@ +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 110% +mount /dev/sdb1 / diff --git a/tests/fixtures/0144-partition-size-fill.installfile b/tests/fixtures/0144-partition-size-fill.installfile new file mode 100644 index 0000000..3e01567 --- /dev/null +++ b/tests/fixtures/0144-partition-size-fill.installfile @@ -0,0 +1,8 @@ +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 +mount /dev/sdb1 / diff --git a/tests/fixtures/0145-partition-size-nonnumeric.installfile b/tests/fixtures/0145-partition-size-nonnumeric.installfile new file mode 100644 index 0000000..d83dd8a --- /dev/null +++ b/tests/fixtures/0145-partition-size-nonnumeric.installfile @@ -0,0 +1,8 @@ +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 abc123 +mount /dev/sdb1 / diff --git a/tests/fixtures/0146-partition-size-bad-suffix.installfile b/tests/fixtures/0146-partition-size-bad-suffix.installfile new file mode 100644 index 0000000..01858f1 --- /dev/null +++ b/tests/fixtures/0146-partition-size-bad-suffix.installfile @@ -0,0 +1,8 @@ +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 10h +mount /dev/sdb1 / diff --git a/tests/fixtures/0147-partition-size-overflow.installfile b/tests/fixtures/0147-partition-size-overflow.installfile new file mode 100644 index 0000000..ae4d159 --- /dev/null +++ b/tests/fixtures/0147-partition-size-overflow.installfile @@ -0,0 +1,8 @@ +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 9999999999999999999999 +mount /dev/sdb1 / diff --git a/tests/fixtures/0148-partition-size-overflow-k.installfile b/tests/fixtures/0148-partition-size-overflow-k.installfile new file mode 100644 index 0000000..2e94c1e --- /dev/null +++ b/tests/fixtures/0148-partition-size-overflow-k.installfile @@ -0,0 +1,8 @@ +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 9999999999999999999K +mount /dev/sdb1 / diff --git a/tests/fixtures/0149-partition-size-overflow-m.installfile b/tests/fixtures/0149-partition-size-overflow-m.installfile new file mode 100644 index 0000000..7144534 --- /dev/null +++ b/tests/fixtures/0149-partition-size-overflow-m.installfile @@ -0,0 +1,8 @@ +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 9999999999999999999M +mount /dev/sdb1 / diff --git a/tests/fixtures/0150-partition-size-overflow-g.installfile b/tests/fixtures/0150-partition-size-overflow-g.installfile new file mode 100644 index 0000000..8a21811 --- /dev/null +++ b/tests/fixtures/0150-partition-size-overflow-g.installfile @@ -0,0 +1,8 @@ +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 99999999999G +mount /dev/sdb1 / diff --git a/tests/fixtures/0151-partition-size-overflow-t.installfile b/tests/fixtures/0151-partition-size-overflow-t.installfile new file mode 100644 index 0000000..7cd707b --- /dev/null +++ b/tests/fixtures/0151-partition-size-overflow-t.installfile @@ -0,0 +1,8 @@ +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 19999999T +mount /dev/sdb1 / diff --git a/tests/fixtures/0152-partition-type-boot.installfile b/tests/fixtures/0152-partition-type-boot.installfile new file mode 100644 index 0000000..56f86d6 --- /dev/null +++ b/tests/fixtures/0152-partition-type-boot.installfile @@ -0,0 +1,8 @@ +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 boot +mount /dev/sdb1 / diff --git a/tests/fixtures/0153-partition-type-esp.installfile b/tests/fixtures/0153-partition-type-esp.installfile new file mode 100644 index 0000000..2556772 --- /dev/null +++ b/tests/fixtures/0153-partition-type-esp.installfile @@ -0,0 +1,8 @@ +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 esp +mount /dev/sdb1 / diff --git a/tests/fixtures/0154-partition-type-none.installfile b/tests/fixtures/0154-partition-type-none.installfile new file mode 100644 index 0000000..3e01567 --- /dev/null +++ b/tests/fixtures/0154-partition-type-none.installfile @@ -0,0 +1,8 @@ +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 +mount /dev/sdb1 / diff --git a/tests/fixtures/0155-partition-type-invalid.installfile b/tests/fixtures/0155-partition-type-invalid.installfile new file mode 100644 index 0000000..73e8282 --- /dev/null +++ b/tests/fixtures/0155-partition-type-invalid.installfile @@ -0,0 +1,8 @@ +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 huh +mount /dev/sdb1 / diff --git a/tests/fixtures/0156-partition-num-nonnumeric.installfile b/tests/fixtures/0156-partition-num-nonnumeric.installfile new file mode 100644 index 0000000..2335a7d --- /dev/null +++ b/tests/fixtures/0156-partition-num-nonnumeric.installfile @@ -0,0 +1,8 @@ +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 a fill +mount /dev/sdb1 / diff --git a/tests/fixtures/0157-partition-nonblock.installfile b/tests/fixtures/0157-partition-nonblock.installfile new file mode 100644 index 0000000..8c24d27 --- /dev/null +++ b/tests/fixtures/0157-partition-nonblock.installfile @@ -0,0 +1,8 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +diskid /dev/sdb WDBNCE2500PNC +disklabel /dev/sdb gpt +partition /dev/console 1 fill +mount /dev/loop0 / diff --git a/tests/fixtures/0158-partition-nondev.installfile b/tests/fixtures/0158-partition-nondev.installfile new file mode 100644 index 0000000..1cdb905 --- /dev/null +++ b/tests/fixtures/0158-partition-nondev.installfile @@ -0,0 +1,8 @@ +network false +hostname test.machine +pkginstall adelie-base +rootpw $6$gumtLGmHwOVIRpQR$2M9PUO24hy5mofzWWf9a.YLbzOgOlUby1g0hDj.wG67E2wrrvys59fq02PPdxBdbgkLZFtjfEx6MHZwMBamwu/ +diskid /dev/sdb WDBNCE2500PNC +disklabel /dev/sdb gpt +partition sdb 1 fill +mount /dev/sdb1 / diff --git a/tests/fixtures/0159-partition-num-duplicate.installfile b/tests/fixtures/0159-partition-num-duplicate.installfile new file mode 100644 index 0000000..afddf25 --- /dev/null +++ b/tests/fixtures/0159-partition-num-duplicate.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 +partition /dev/sdb 1 fill +mount /dev/sdb1 / diff --git a/tests/fixtures/0160-partition-missing-num.installfile b/tests/fixtures/0160-partition-missing-num.installfile new file mode 100644 index 0000000..2f224ee --- /dev/null +++ b/tests/fixtures/0160-partition-missing-num.installfile @@ -0,0 +1,8 @@ +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 +mount /dev/sdb1 / diff --git a/tests/fixtures/0161-partition-missing-size.installfile b/tests/fixtures/0161-partition-missing-size.installfile new file mode 100644 index 0000000..8022692 --- /dev/null +++ b/tests/fixtures/0161-partition-missing-size.installfile @@ -0,0 +1,8 @@ +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 +mount /dev/sdb1 / diff --git a/tests/fixtures/0162-partition-size-case.installfile b/tests/fixtures/0162-partition-size-case.installfile new file mode 100644 index 0000000..f4d9450 --- /dev/null +++ b/tests/fixtures/0162-partition-size-case.installfile @@ -0,0 +1,8 @@ +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 +mount /dev/sdb1 / diff --git a/tests/spec/validator_spec.rb b/tests/spec/validator_spec.rb index 457aa93..df504ca 100644 --- a/tests/spec/validator_spec.rb +++ b/tests/spec/validator_spec.rb @@ -629,6 +629,165 @@ RSpec.describe 'HorizonScript validation', :type => :aruba do expect(last_command_started).to have_output(/error: .*disklabel.*type/) end end + context "for 'partition' key" do + it "succeeds with a typical value" do + use_fixture '0135-partition-basic.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + context "size value" do + it "supports bytes" do + use_fixture '0136-partition-size-bytes.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "supports kilobytes (K)" do + use_fixture '0137-partition-size-kbytes.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "supports megabytes (M)" do + use_fixture '0138-partition-size-mbytes.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "supports gigabytes (G)" do + use_fixture '0139-partition-size-gbytes.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "supports terabytes (T)" do + use_fixture '0140-partition-size-tbytes.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "does not support exabytes (E)" do + use_fixture '0141-partition-size-ebytes.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*suffix/) + end + it "supports percentages" do + use_fixture '0142-partition-size-percent.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "does not support percentages over 100" do + use_fixture '0143-partition-size-percent-overflow.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*too large/) + end + it "supports the literal value 'fill'" do + use_fixture '0144-partition-size-fill.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "does not support non-numeric values" do + use_fixture '0145-partition-size-nonnumeric.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*number/) + end + it "does not support incorrect suffixes" do + use_fixture '0146-partition-size-bad-suffix.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*suffix/) + end + it "correctly handles byte overflow" do + use_fixture '0147-partition-size-overflow.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*too large/) + end + it "correctly handles kilobyte overflow (K)" do + use_fixture '0148-partition-size-overflow-k.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*too large/) + end + it "correctly handles megabyte overflow (M)" do + use_fixture '0149-partition-size-overflow-m.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*too large/) + end + it "correctly handles gigabyte overflow (G)" do + use_fixture '0150-partition-size-overflow-g.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*too large/) + end + it "correctly handles terabyte overflow (T)" do + use_fixture '0151-partition-size-overflow-t.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*too large/) + end + it "supports mixed-case 'fill'" do + use_fixture '0162-partition-size-case.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + end + context "type code" do + it "handles 'boot'" do + use_fixture '0152-partition-type-boot.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "handles 'esp'" do + use_fixture '0153-partition-type-esp.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "handles no value" do + use_fixture '0154-partition-type-none.installfile' + run_validate + expect(last_command_started).to have_output(PARSER_SUCCESS) + expect(last_command_started).to have_output(VALIDATOR_SUCCESS) + end + it "errors on invalid type code" do + use_fixture '0155-partition-type-invalid.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*partition.*invalid/) + end + end + it "errors on non-numeric partition number" do + use_fixture '0156-partition-num-nonnumeric.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*partition.*number/) + end + it "requires a block device" do + use_fixture '0157-partition-nonblock.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: .*partition.*block/) + end + it "requires an absolute device path" do + use_fixture '0158-partition-nondev.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*partition.*device/) + end + it "requires partition numbers to be unique per block device" do + use_fixture '0159-partition-num-duplicate.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*partition.*already exists/) + end + it "requires a partition number" do + use_fixture '0160-partition-missing-num.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*partition.*expected/) + end + it "requires a size" do + use_fixture '0161-partition-missing-size.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*partition.*size/) + end + end end context "unique keys" do # Runner.Validate.network. |