Option<Error> validateContainerId(const ContainerID& containerId) { // Slashes are disallowed as these IDs are mapped to directories. // // Periods are disallowed because our string representation of // ContainerID uses periods: <uuid>.<child>.<grandchild>. // For example: <uuid>.redis.backup // // Spaces are disallowed as they can render logs confusing and // need escaping on terminals when dealing with paths. // // TODO(bmahler): Add common/validation.hpp to share ID validation. // Note that this however is slightly stricter than other IDs in // that we do not allow periods or spaces. auto invalidCharacter = [](char c) { return iscntrl(c) || c == os::POSIX_PATH_SEPARATOR || c == os::WINDOWS_PATH_SEPARATOR || c == '.' || c == ' '; }; const string& id = containerId.value(); if (id.empty()) { return Error("'ContainerID.value' must be non-empty"); } if (std::any_of(id.begin(), id.end(), invalidCharacter)) { return Error("'ContainerID.value' '" + id + "'" " contains invalid characters"); } // TODO(bmahler): Print the invalid field nicely within the error // (e.g. 'parent.parent.parent.value'). For now we only have one // level of nesting so it's ok. if (containerId.has_parent()) { Option<Error> parentError = validateContainerId(containerId.parent()); if (parentError.isSome()) { return Error("'ContainerID.parent' is invalid: " + parentError->message); } } return None(); }
Option<Error> validateContainerId(const ContainerID& containerId) { const string& id = containerId.value(); // Check common Mesos ID rules. Option<Error> error = common::validation::validateID(id); if (error.isSome()) { return Error(error->message); } // Check ContainerID specific rules. // // Periods are disallowed because our string representation of // ContainerID uses periods: <uuid>.<child>.<grandchild>. // For example: <uuid>.redis.backup // // Spaces are disallowed as they can render logs confusing and // need escaping on terminals when dealing with paths. auto invalidCharacter = [](char c) { return c == '.' || c == ' '; }; if (std::any_of(id.begin(), id.end(), invalidCharacter)) { return Error("'ContainerID.value' '" + id + "'" " contains invalid characters"); } // TODO(bmahler): Print the invalid field nicely within the error // (e.g. 'parent.parent.parent.value'). For now we only have one // level of nesting so it's ok. if (containerId.has_parent()) { Option<Error> parentError = validateContainerId(containerId.parent()); if (parentError.isSome()) { return Error("'ContainerID.parent' is invalid: " + parentError->message); } } return None(); }
bool operator==(const ContainerID& left, const ContainerID& right) { return left.value() == right.value() && left.has_parent() == right.has_parent() && (!left.has_parent() || left.parent() == right.parent()); }