summaryrefslogtreecommitdiff
path: root/hscript
diff options
context:
space:
mode:
Diffstat (limited to 'hscript')
-rw-r--r--hscript/disk.cc56
-rw-r--r--hscript/disk.hh22
-rw-r--r--hscript/script.cc35
3 files changed, 111 insertions, 2 deletions
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<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_mounts;
+ seen_vg_names, seen_vg_pvs, seen_lvs, seen_mounts;
std::map<const std::string, int> 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)) {