Statistics
| Branch: | Tag: | Revision:

root / src / Ganeti / Errors.hs @ 13d26b66

History | View | Annotate | Download (6.5 kB)

1 ef3ad027 Iustin Pop
{-# LANGUAGE TemplateHaskell #-}
2 ef3ad027 Iustin Pop
3 ef3ad027 Iustin Pop
{-| Implementation of the Ganeti error types.
4 ef3ad027 Iustin Pop
5 ef3ad027 Iustin Pop
This module implements our error hierarchy. Currently we implement one
6 ef3ad027 Iustin Pop
identical to the Python one; later we might one to have separate ones
7 ef3ad027 Iustin Pop
for frontend (clients), master and backend code.
8 ef3ad027 Iustin Pop
9 ef3ad027 Iustin Pop
-}
10 ef3ad027 Iustin Pop
11 ef3ad027 Iustin Pop
{-
12 ef3ad027 Iustin Pop
13 ef3ad027 Iustin Pop
Copyright (C) 2012 Google Inc.
14 ef3ad027 Iustin Pop
15 ef3ad027 Iustin Pop
This program is free software; you can redistribute it and/or modify
16 ef3ad027 Iustin Pop
it under the terms of the GNU General Public License as published by
17 ef3ad027 Iustin Pop
the Free Software Foundation; either version 2 of the License, or
18 ef3ad027 Iustin Pop
(at your option) any later version.
19 ef3ad027 Iustin Pop
20 ef3ad027 Iustin Pop
This program is distributed in the hope that it will be useful, but
21 ef3ad027 Iustin Pop
WITHOUT ANY WARRANTY; without even the implied warranty of
22 ef3ad027 Iustin Pop
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23 ef3ad027 Iustin Pop
General Public License for more details.
24 ef3ad027 Iustin Pop
25 ef3ad027 Iustin Pop
You should have received a copy of the GNU General Public License
26 ef3ad027 Iustin Pop
along with this program; if not, write to the Free Software
27 ef3ad027 Iustin Pop
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 ef3ad027 Iustin Pop
02110-1301, USA.
29 ef3ad027 Iustin Pop
30 ef3ad027 Iustin Pop
-}
31 ef3ad027 Iustin Pop
32 ef3ad027 Iustin Pop
module Ganeti.Errors
33 ef3ad027 Iustin Pop
  ( ErrorCode(..)
34 ef3ad027 Iustin Pop
  , GanetiException(..)
35 ef3ad027 Iustin Pop
  , ErrorResult
36 7adb7dff Iustin Pop
  , errToResult
37 f56fc1a6 Iustin Pop
  , errorExitCode
38 7adb7dff Iustin Pop
  , excName
39 f56fc1a6 Iustin Pop
  , formatError
40 32be18fc Petr Pudlak
  , ResultG
41 9491766c Hrvoje Ribicic
  , maybeToError
42 ef3ad027 Iustin Pop
  ) where
43 ef3ad027 Iustin Pop
44 ef3ad027 Iustin Pop
import Text.JSON hiding (Result, Ok)
45 f56fc1a6 Iustin Pop
import System.Exit
46 ef3ad027 Iustin Pop
47 ef3ad027 Iustin Pop
import Ganeti.THH
48 ef3ad027 Iustin Pop
import Ganeti.BasicTypes
49 ef3ad027 Iustin Pop
import qualified Ganeti.Constants as C
50 ef3ad027 Iustin Pop
51 ef3ad027 Iustin Pop
-- | Error code types for 'OpPrereqError'.
52 ef3ad027 Iustin Pop
$(declareSADT "ErrorCode"
53 ef3ad027 Iustin Pop
  [ ("ECodeResolver",  'C.errorsEcodeResolver)
54 ef3ad027 Iustin Pop
  , ("ECodeNoRes",     'C.errorsEcodeNores)
55 6bee863c Michael Hanselmann
  , ("ECodeTempNoRes", 'C.errorsEcodeTempNores)
56 ef3ad027 Iustin Pop
  , ("ECodeInval",     'C.errorsEcodeInval)
57 ef3ad027 Iustin Pop
  , ("ECodeState",     'C.errorsEcodeState)
58 ef3ad027 Iustin Pop
  , ("ECodeNoEnt",     'C.errorsEcodeNoent)
59 ef3ad027 Iustin Pop
  , ("ECodeExists",    'C.errorsEcodeExists)
60 ef3ad027 Iustin Pop
  , ("ECodeNotUnique", 'C.errorsEcodeNotunique)
61 ef3ad027 Iustin Pop
  , ("ECodeFault",     'C.errorsEcodeFault)
62 ef3ad027 Iustin Pop
  , ("ECodeEnviron",   'C.errorsEcodeEnviron)
63 ef3ad027 Iustin Pop
  ])
64 ef3ad027 Iustin Pop
$(makeJSONInstance ''ErrorCode)
65 ef3ad027 Iustin Pop
66 ef3ad027 Iustin Pop
$(genException "GanetiException"
67 ef3ad027 Iustin Pop
  [ ("GenericError", [excErrMsg])
68 ef3ad027 Iustin Pop
  , ("LockError", [excErrMsg])
69 ef3ad027 Iustin Pop
  , ("PidFileLockError", [excErrMsg])
70 ef3ad027 Iustin Pop
  , ("HypervisorError", [excErrMsg])
71 ef3ad027 Iustin Pop
  , ("ProgrammerError", [excErrMsg])
72 ef3ad027 Iustin Pop
  , ("BlockDeviceError", [excErrMsg])
73 ef3ad027 Iustin Pop
  , ("ConfigurationError", [excErrMsg])
74 86a24969 Dato Simó
  , ("ConfigVersionMismatch", [ ("expVer", [t| Int |])
75 86a24969 Dato Simó
                              , ("actVer", [t| Int |])])
76 ef3ad027 Iustin Pop
  , ("ReservationError", [excErrMsg])
77 ef3ad027 Iustin Pop
  , ("RemoteError", [excErrMsg])
78 ef3ad027 Iustin Pop
  , ("SignatureError", [excErrMsg])
79 ef3ad027 Iustin Pop
  , ("ParameterError", [excErrMsg])
80 ef3ad027 Iustin Pop
  , ("ResultValidationError", [excErrMsg])
81 ef3ad027 Iustin Pop
  , ("OpPrereqError", [excErrMsg, ("errCode", [t| ErrorCode |])])
82 ef3ad027 Iustin Pop
  , ("OpExecError", [excErrMsg])
83 ef3ad027 Iustin Pop
  , ("OpResultError", [excErrMsg])
84 ef3ad027 Iustin Pop
  , ("OpCodeUnknown", [excErrMsg])
85 ef3ad027 Iustin Pop
  , ("JobLost", [excErrMsg])
86 ef3ad027 Iustin Pop
  , ("JobFileCorrupted", [excErrMsg])
87 ef3ad027 Iustin Pop
  , ("ResolverError", [ ("errHostname", [t| String |])
88 ef3ad027 Iustin Pop
                      , ("errResolverCode", [t| Int |])
89 ef3ad027 Iustin Pop
                      , ("errResolverMsg", [t| String |])])
90 ef3ad027 Iustin Pop
  , ("HooksFailure", [excErrMsg])
91 ef3ad027 Iustin Pop
  , ("HooksAbort", [("errs", [t| [(String, String, String)] |])])
92 ef3ad027 Iustin Pop
  , ("UnitParseError", [excErrMsg])
93 ef3ad027 Iustin Pop
  , ("ParseError", [excErrMsg])
94 ef3ad027 Iustin Pop
  , ("TypeEnforcementError", [excErrMsg])
95 bca39f5c Iustin Pop
  , ("X509CertError", [ ("certFileName", [t| String |])
96 bca39f5c Iustin Pop
                      , excErrMsg ])
97 ef3ad027 Iustin Pop
  , ("TagError", [excErrMsg])
98 ef3ad027 Iustin Pop
  , ("CommandError", [excErrMsg])
99 ef3ad027 Iustin Pop
  , ("StorageError", [excErrMsg])
100 ef3ad027 Iustin Pop
  , ("InotifyError", [excErrMsg])
101 ef3ad027 Iustin Pop
  , ("JobQueueError", [excErrMsg])
102 ef3ad027 Iustin Pop
  , ("JobQueueDrainError", [excErrMsg])
103 ef3ad027 Iustin Pop
  , ("JobQueueFull", [])
104 ef3ad027 Iustin Pop
  , ("ConfdMagicError", [excErrMsg])
105 ef3ad027 Iustin Pop
  , ("ConfdClientError", [excErrMsg])
106 ef3ad027 Iustin Pop
  , ("UdpDataSizeError", [excErrMsg])
107 ef3ad027 Iustin Pop
  , ("NoCtypesError", [excErrMsg])
108 ef3ad027 Iustin Pop
  , ("IPAddressError", [excErrMsg])
109 ef3ad027 Iustin Pop
  , ("LuxiError", [excErrMsg])
110 ef3ad027 Iustin Pop
  , ("QueryFilterParseError", [excErrMsg]) -- not consistent with Python
111 ef3ad027 Iustin Pop
  , ("RapiTestResult", [excErrMsg])
112 ef3ad027 Iustin Pop
  , ("FileStoragePathError", [excErrMsg])
113 ef3ad027 Iustin Pop
  ])
114 ef3ad027 Iustin Pop
115 ed5a07f2 Petr Pudlak
instance Error GanetiException where
116 a87a017b Petr Pudlak
  strMsg = GenericError
117 ed5a07f2 Petr Pudlak
118 ef3ad027 Iustin Pop
instance JSON GanetiException where
119 ef3ad027 Iustin Pop
  showJSON = saveGanetiException
120 ef3ad027 Iustin Pop
  readJSON = loadGanetiException
121 ef3ad027 Iustin Pop
122 ef3ad027 Iustin Pop
-- | Error monad using 'GanetiException' type alias.
123 ef3ad027 Iustin Pop
type ErrorResult = GenericResult GanetiException
124 ef3ad027 Iustin Pop
125 ef3ad027 Iustin Pop
$(genStrOfOp ''GanetiException "excName")
126 f56fc1a6 Iustin Pop
127 f56fc1a6 Iustin Pop
-- | Returns the exit code of a program that should be used if we got
128 f56fc1a6 Iustin Pop
-- back an exception from masterd.
129 f56fc1a6 Iustin Pop
errorExitCode :: GanetiException -> ExitCode
130 f56fc1a6 Iustin Pop
errorExitCode (ConfigurationError {}) = ExitFailure 2
131 f56fc1a6 Iustin Pop
errorExitCode _ = ExitFailure 1
132 f56fc1a6 Iustin Pop
133 f56fc1a6 Iustin Pop
-- | Formats an exception.
134 f56fc1a6 Iustin Pop
formatError :: GanetiException -> String
135 f56fc1a6 Iustin Pop
formatError (ConfigurationError msg) =
136 f56fc1a6 Iustin Pop
  "Corrup configuration file: " ++ msg ++ "\nAborting."
137 f56fc1a6 Iustin Pop
formatError (HooksAbort errs) =
138 f56fc1a6 Iustin Pop
  unlines $
139 f56fc1a6 Iustin Pop
  "Failure: hooks execution failed:":
140 f56fc1a6 Iustin Pop
  map (\(node, script, out) ->
141 f56fc1a6 Iustin Pop
         "  node: " ++ node ++ ", script: " ++ script ++
142 f56fc1a6 Iustin Pop
                    if null out
143 f56fc1a6 Iustin Pop
                      then " (no output)"
144 f56fc1a6 Iustin Pop
                      else ", output: " ++ out
145 f56fc1a6 Iustin Pop
      ) errs
146 f56fc1a6 Iustin Pop
formatError (HooksFailure msg) =
147 f56fc1a6 Iustin Pop
  "Failure: hooks general failure: " ++ msg
148 f56fc1a6 Iustin Pop
formatError (ResolverError host _ _) =
149 f56fc1a6 Iustin Pop
  -- FIXME: in Python, this uses the system hostname to format the
150 f56fc1a6 Iustin Pop
  -- error differently if we are failing to resolve our own hostname
151 f56fc1a6 Iustin Pop
  "Failure: can't resolve hostname " ++ host
152 f56fc1a6 Iustin Pop
formatError (OpPrereqError msg code) =
153 f56fc1a6 Iustin Pop
  "Failure: prerequisites not met for this" ++
154 f56fc1a6 Iustin Pop
  " operation:\nerror type: " ++ show code ++ ", error details:\n" ++ msg
155 f56fc1a6 Iustin Pop
formatError (OpExecError msg) =
156 f56fc1a6 Iustin Pop
  "Failure: command execution error:\n" ++ msg
157 f56fc1a6 Iustin Pop
formatError (TagError msg) =
158 f56fc1a6 Iustin Pop
  "Failure: invalid tag(s) given:\n" ++ msg
159 f56fc1a6 Iustin Pop
formatError (JobQueueDrainError _)=
160 f56fc1a6 Iustin Pop
  "Failure: the job queue is marked for drain and doesn't accept new requests"
161 f56fc1a6 Iustin Pop
formatError JobQueueFull =
162 f56fc1a6 Iustin Pop
  "Failure: the job queue is full and doesn't accept new" ++
163 f56fc1a6 Iustin Pop
  " job submissions until old jobs are archived"
164 f56fc1a6 Iustin Pop
formatError (TypeEnforcementError msg) =
165 f56fc1a6 Iustin Pop
  "Parameter Error: " ++ msg
166 f56fc1a6 Iustin Pop
formatError (ParameterError msg) =
167 f56fc1a6 Iustin Pop
  "Failure: unknown/wrong parameter name '" ++ msg ++ "'"
168 f56fc1a6 Iustin Pop
formatError (JobLost msg) =
169 f56fc1a6 Iustin Pop
  "Error checking job status: " ++ msg
170 f56fc1a6 Iustin Pop
formatError (QueryFilterParseError msg) =
171 f56fc1a6 Iustin Pop
  -- FIXME: in Python, this has a more complex error message
172 f56fc1a6 Iustin Pop
  "Error while parsing query filter: " ++ msg
173 f56fc1a6 Iustin Pop
formatError (GenericError msg) =
174 f56fc1a6 Iustin Pop
  "Unhandled Ganeti error: " ++ msg
175 f56fc1a6 Iustin Pop
formatError err =
176 f56fc1a6 Iustin Pop
  "Unhandled exception: " ++ show err
177 7adb7dff Iustin Pop
178 32be18fc Petr Pudlak
-- | A type for IO actions with errors properly handled as
179 32be18fc Petr Pudlak
-- 'GanetiException's.
180 32be18fc Petr Pudlak
-- TODO: Move to Errors.hs
181 32be18fc Petr Pudlak
type ResultG = ResultT GanetiException IO
182 32be18fc Petr Pudlak
183 7adb7dff Iustin Pop
-- | Convert from an 'ErrorResult' to a standard 'Result'.
184 7adb7dff Iustin Pop
errToResult :: ErrorResult a -> Result a
185 7adb7dff Iustin Pop
errToResult (Ok a)  = Ok a
186 7adb7dff Iustin Pop
errToResult (Bad e) = Bad $ formatError e
187 9491766c Hrvoje Ribicic
188 9491766c Hrvoje Ribicic
-- | Convert from a 'Maybe' to a an 'ErrorResult'.
189 9491766c Hrvoje Ribicic
maybeToError :: String -> Maybe a -> ErrorResult a
190 9491766c Hrvoje Ribicic
maybeToError _ (Just a) = Ok a
191 9491766c Hrvoje Ribicic
maybeToError m  Nothing = Bad $ GenericError m