X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/425e5bf0ddbce8c801e0f172b21457aea6a9c954..297b0cd3faa9e114c40079e3490eb95cf0ec9701:/lib/query.py diff --git a/lib/query.py b/lib/query.py index 28afec1..51448ba 100644 --- a/lib/query.py +++ b/lib/query.py @@ -322,6 +322,16 @@ def _WrapNot(fn, lhs, rhs): return not fn(lhs, rhs) +def _PrepareRegex(pattern): + """Compiles a regular expression. + + """ + try: + return re.compile(pattern) + except re.error, err: + raise errors.ParameterError("Invalid regex pattern (%s)" % err) + + class _FilterCompilerHelper: """Converts a query filter to a callable usable for filtering. @@ -349,8 +359,9 @@ class _FilterCompilerHelper: _EQUALITY_CHECKS = [ (QFF_HOSTNAME, lambda lhs, rhs: utils.MatchNameComponent(rhs, [lhs], - case_sensitive=False)), - (None, operator.eq), + case_sensitive=False), + None), + (None, operator.eq, None), ] """Known operators @@ -377,12 +388,13 @@ class _FilterCompilerHelper: # Binary operators qlang.OP_EQUAL: (_OPTYPE_BINARY, _EQUALITY_CHECKS), qlang.OP_NOT_EQUAL: - (_OPTYPE_BINARY, [(flags, compat.partial(_WrapNot, fn)) - for (flags, fn) in _EQUALITY_CHECKS]), - qlang.OP_GLOB: (_OPTYPE_BINARY, NotImplemented), - qlang.OP_REGEXP: (_OPTYPE_BINARY, NotImplemented), + (_OPTYPE_BINARY, [(flags, compat.partial(_WrapNot, fn), valprepfn) + for (flags, fn, valprepfn) in _EQUALITY_CHECKS]), + qlang.OP_REGEXP: (_OPTYPE_BINARY, [ + (None, lambda lhs, rhs: rhs.search(lhs), _PrepareRegex), + ]), qlang.OP_CONTAINS: (_OPTYPE_BINARY, [ - (None, operator.contains), + (None, operator.contains, None), ]), } @@ -556,8 +568,12 @@ class _FilterCompilerHelper: if hints_fn: hints_fn(op, datakind, name, value) - for (fn_flags, fn) in op_data: + for (fn_flags, fn, valprepfn) in op_data: if fn_flags is None or fn_flags & field_flags: + # Prepare value if necessary (e.g. compile regular expression) + if valprepfn: + value = valprepfn(value) + return compat.partial(_WrapBinaryOp, fn, retrieval_fn, value) raise errors.ProgrammerError("Unable to find operator implementation" @@ -1243,6 +1259,7 @@ class InstanceQueryData: # Used for individual rows self.inst_hvparams = None self.inst_beparams = None + self.inst_osparams = None self.inst_nicparams = None def __iter__(self): @@ -1255,6 +1272,7 @@ class InstanceQueryData: for inst in self.instances: self.inst_hvparams = self.cluster.FillHV(inst, skip_globals=True) self.inst_beparams = self.cluster.FillBE(inst) + self.inst_osparams = self.cluster.SimpleFillOS(inst.os, inst.osparams) self.inst_nicparams = [self.cluster.SimpleFillNIC(nic.nicparams) for nic in inst.nics] @@ -1620,11 +1638,14 @@ def _GetInstanceParameterFields(): fields = [ # Filled parameters (_MakeField("hvparams", "HypervisorParameters", QFT_OTHER, - "Hypervisor parameters"), + "Hypervisor parameters (merged)"), IQ_CONFIG, 0, lambda ctx, _: ctx.inst_hvparams), (_MakeField("beparams", "BackendParameters", QFT_OTHER, - "Backend parameters"), + "Backend parameters (merged)"), IQ_CONFIG, 0, lambda ctx, _: ctx.inst_beparams), + (_MakeField("osparams", "OpSysParameters", QFT_OTHER, + "Operating system parameters (merged)"), + IQ_CONFIG, 0, lambda ctx, _: ctx.inst_osparams), # Unfilled parameters (_MakeField("custom_hvparams", "CustomHypervisorParameters", QFT_OTHER, @@ -1633,6 +1654,9 @@ def _GetInstanceParameterFields(): (_MakeField("custom_beparams", "CustomBackendParameters", QFT_OTHER, "Custom backend parameters",), IQ_CONFIG, 0, _GetItemAttr("beparams")), + (_MakeField("custom_osparams", "CustomOpSysParameters", QFT_OTHER, + "Custom operating system parameters",), + IQ_CONFIG, 0, _GetItemAttr("osparams")), (_MakeField("custom_nicparams", "CustomNicParameters", QFT_OTHER, "Custom network interface parameters"), IQ_CONFIG, 0, lambda ctx, inst: [nic.nicparams for nic in inst.nics]), @@ -1883,11 +1907,63 @@ def _BuildGroupFields(): GQ_INST, 0, _GetSortedList(group_to_instances)), ]) + # Other fields + fields.extend([ + (_MakeField("tags", "Tags", QFT_OTHER, "Tags"), GQ_CONFIG, 0, + lambda ctx, group: list(group.GetTags())), + ]) + fields.extend(_GetItemTimestampFields(GQ_CONFIG)) return _PrepareFieldList(fields, []) +class OsInfo(objects.ConfigObject): + __slots__ = [ + "name", + "valid", + "hidden", + "blacklisted", + "variants", + "api_versions", + "parameters", + "node_status", + ] + + +def _BuildOsFields(): + """Builds list of fields for operating system queries. + + """ + fields = [ + (_MakeField("name", "Name", QFT_TEXT, "Operating system name"), + None, 0, _GetItemAttr("name")), + (_MakeField("valid", "Valid", QFT_BOOL, + "Whether operating system definition is valid"), + None, 0, _GetItemAttr("valid")), + (_MakeField("hidden", "Hidden", QFT_BOOL, + "Whether operating system is hidden"), + None, 0, _GetItemAttr("hidden")), + (_MakeField("blacklisted", "Blacklisted", QFT_BOOL, + "Whether operating system is blacklisted"), + None, 0, _GetItemAttr("blacklisted")), + (_MakeField("variants", "Variants", QFT_OTHER, + "Operating system variants"), + None, 0, _ConvWrap(utils.NiceSort, _GetItemAttr("variants"))), + (_MakeField("api_versions", "ApiVersions", QFT_OTHER, + "Operating system API versions"), + None, 0, _ConvWrap(sorted, _GetItemAttr("api_versions"))), + (_MakeField("parameters", "Parameters", QFT_OTHER, + "Operating system parameters"), + None, 0, _ConvWrap(utils.NiceSort, _GetItemAttr("parameters"))), + (_MakeField("node_status", "NodeStatus", QFT_OTHER, + "Status from node"), + None, 0, _GetItemAttr("node_status")), + ] + + return _PrepareFieldList(fields, []) + + #: Fields available for node queries NODE_FIELDS = _BuildNodeFields() @@ -1900,12 +1976,16 @@ LOCK_FIELDS = _BuildLockFields() #: Fields available for node group queries GROUP_FIELDS = _BuildGroupFields() +#: Fields available for operating system queries +OS_FIELDS = _BuildOsFields() + #: All available resources ALL_FIELDS = { constants.QR_INSTANCE: INSTANCE_FIELDS, constants.QR_NODE: NODE_FIELDS, constants.QR_LOCK: LOCK_FIELDS, constants.QR_GROUP: GROUP_FIELDS, + constants.QR_OS: OS_FIELDS, } #: All available field lists