summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hscript/disk.cc192
-rw-r--r--hscript/disk.hh46
-rw-r--r--hscript/script.cc27
-rw-r--r--tests/fixtures/0135-partition-basic.installfile8
-rw-r--r--tests/fixtures/0136-partition-size-bytes.installfile8
-rw-r--r--tests/fixtures/0137-partition-size-kbytes.installfile8
-rw-r--r--tests/fixtures/0138-partition-size-mbytes.installfile8
-rw-r--r--tests/fixtures/0139-partition-size-gbytes.installfile8
-rw-r--r--tests/fixtures/0140-partition-size-tbytes.installfile8
-rw-r--r--tests/fixtures/0141-partition-size-ebytes.installfile8
-rw-r--r--tests/fixtures/0142-partition-size-percent.installfile8
-rw-r--r--tests/fixtures/0143-partition-size-percent-overflow.installfile8
-rw-r--r--tests/fixtures/0144-partition-size-fill.installfile8
-rw-r--r--tests/fixtures/0145-partition-size-nonnumeric.installfile8
-rw-r--r--tests/fixtures/0146-partition-size-bad-suffix.installfile8
-rw-r--r--tests/fixtures/0147-partition-size-overflow.installfile8
-rw-r--r--tests/fixtures/0148-partition-size-overflow-k.installfile8
-rw-r--r--tests/fixtures/0149-partition-size-overflow-m.installfile8
-rw-r--r--tests/fixtures/0150-partition-size-overflow-g.installfile8
-rw-r--r--tests/fixtures/0151-partition-size-overflow-t.installfile8
-rw-r--r--tests/fixtures/0152-partition-type-boot.installfile8
-rw-r--r--tests/fixtures/0153-partition-type-esp.installfile8
-rw-r--r--tests/fixtures/0154-partition-type-none.installfile8
-rw-r--r--tests/fixtures/0155-partition-type-invalid.installfile8
-rw-r--r--tests/fixtures/0156-partition-num-nonnumeric.installfile8
-rw-r--r--tests/fixtures/0157-partition-nonblock.installfile8
-rw-r--r--tests/fixtures/0158-partition-nondev.installfile8
-rw-r--r--tests/fixtures/0159-partition-num-duplicate.installfile9
-rw-r--r--tests/fixtures/0160-partition-missing-num.installfile8
-rw-r--r--tests/fixtures/0161-partition-missing-size.installfile8
-rw-r--r--tests/fixtures/0162-partition-size-case.installfile8
-rw-r--r--tests/spec/validator_spec.rb159
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.