1 {-| Implementation of the Ganeti Query2 job queries.
7 Copyright (C) 2012 Google Inc.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 module Ganeti.Query.Job
33 import qualified Data.Map as Map
34 import qualified Text.JSON as J
36 import Ganeti.BasicTypes
37 import qualified Ganeti.Constants as C
40 import Ganeti.Query.Common
41 import Ganeti.Query.Language
42 import Ganeti.Query.Types
45 -- | The runtime data for a job.
46 type RuntimeData = Result (QueuedJob, Bool)
48 -- | Job priority explanation.
50 jobPrioDoc = "Current job priority (" ++ show C.opPrioLowest ++ " to " ++
51 show C.opPrioHighest ++ ")"
54 tsDoc :: String -> String
55 tsDoc = (++ " (tuple containing seconds and microseconds)")
57 -- | Wrapper for unavailable job.
58 maybeJob :: (J.JSON a) =>
59 (QueuedJob -> a) -> RuntimeData -> JobId -> ResultEntry
60 maybeJob _ (Bad _) _ = rsUnavail
61 maybeJob f (Ok (v, _)) _ = rsNormal $ f v
63 -- | Wrapper for optional fields that should become unavailable.
64 maybeJobOpt :: (J.JSON a) =>
65 (QueuedJob -> Maybe a) -> RuntimeData -> JobId -> ResultEntry
66 maybeJobOpt _ (Bad _) _ = rsUnavail
67 maybeJobOpt f (Ok (v, _)) _ = case f v of
71 -- | Simple helper for a job getter.
72 jobGetter :: (J.JSON a) => (QueuedJob -> a) -> FieldGetter JobId RuntimeData
73 jobGetter = FieldRuntime . maybeJob
75 -- | Simple helper for a per-opcode getter.
76 opsGetter :: (J.JSON a) => (QueuedOpCode -> a) -> FieldGetter JobId RuntimeData
77 opsGetter f = FieldRuntime $ maybeJob (map f . qjOps)
79 -- | Simple helper for a per-opcode optional field getter.
80 opsOptGetter :: (J.JSON a) =>
81 (QueuedOpCode -> Maybe a) -> FieldGetter JobId RuntimeData
83 FieldRuntime $ maybeJob (map (\qo -> case f qo of
85 Just a -> J.showJSON a) . qjOps)
87 -- | Archived field name.
88 archivedField :: String
89 archivedField = "archived"
91 -- | Check whether we should look at archived jobs as well.
92 wantArchived :: [FilterField] -> Bool
93 wantArchived = (archivedField `elem`)
95 -- | List of all node fields. FIXME: QFF_JOB_ID on the id field.
96 jobFields :: FieldList JobId RuntimeData
98 [ (FieldDefinition "id" "ID" QFTNumber "Job ID", FieldSimple rsNormal,
100 , (FieldDefinition "status" "Status" QFTText "Job status",
101 jobGetter calcJobStatus, QffNormal)
102 , (FieldDefinition "priority" "Priority" QFTNumber jobPrioDoc,
103 jobGetter calcJobPriority, QffNormal)
104 , (FieldDefinition archivedField "Archived" QFTBool
105 "Whether job is archived",
106 FieldRuntime (\jinfo _ -> case jinfo of
107 Ok (_, archive) -> rsNormal archive
108 _ -> rsUnavail), QffNormal)
109 , (FieldDefinition "ops" "OpCodes" QFTOther "List of all opcodes",
110 opsGetter qoInput, QffNormal)
111 , (FieldDefinition "opresult" "OpCode_result" QFTOther
112 "List of opcodes results", opsGetter qoResult, QffNormal)
113 , (FieldDefinition "opstatus" "OpCode_status" QFTOther
114 "List of opcodes status", opsGetter qoStatus, QffNormal)
115 , (FieldDefinition "oplog" "OpCode_log" QFTOther
116 "List of opcode output logs", opsGetter qoLog, QffNormal)
117 , (FieldDefinition "opstart" "OpCode_start" QFTOther
118 "List of opcode start timestamps (before acquiring locks)",
119 opsOptGetter qoStartTimestamp, QffNormal)
120 , (FieldDefinition "opexec" "OpCode_exec" QFTOther
121 "List of opcode execution start timestamps (after acquiring locks)",
122 opsOptGetter qoExecTimestamp, QffNormal)
123 , (FieldDefinition "opend" "OpCode_end" QFTOther
124 "List of opcode execution end timestamps",
125 opsOptGetter qoEndTimestamp, QffNormal)
126 , (FieldDefinition "oppriority" "OpCode_prio" QFTOther
127 "List of opcode priorities", opsGetter qoPriority, QffNormal)
128 , (FieldDefinition "summary" "Summary" QFTOther
129 "List of per-opcode summaries",
130 opsGetter (extractOpSummary . qoInput), QffNormal)
131 , (FieldDefinition "received_ts" "Received" QFTOther
132 (tsDoc "Timestamp of when job was received"),
133 FieldRuntime (maybeJobOpt qjReceivedTimestamp), QffTimestamp)
134 , (FieldDefinition "start_ts" "Start" QFTOther
135 (tsDoc "Timestamp of job start"),
136 FieldRuntime (maybeJobOpt qjStartTimestamp), QffTimestamp)
137 , (FieldDefinition "end_ts" "End" QFTOther
138 (tsDoc "Timestamp of job end"),
139 FieldRuntime (maybeJobOpt qjEndTimestamp), QffTimestamp)
142 -- | The node fields map.
143 fieldsMap :: FieldMap JobId RuntimeData
145 Map.fromList $ map (\v@(f, _, _) -> (fdefName f, v)) jobFields
147 -- | Load the given jobs from disk.
148 loadRuntimeData :: [JobId] -> Bool -> IO [RuntimeData]
149 loadRuntimeData ids archived = do
151 mapM (loadJobFromDisk qdir archived) ids