LGTM, thanks

On Thu, Apr 3, 2014 at 4:46 PM, Jose A. Lopes <[email protected]> wrote:

> This patch makes the metadata daemon web server serve the OS scripts
> via the instance communication mechanism.  This is achieved by
> retrieving the "os" field from the instance parameters and serving the
> file directly from the 'Constants.osSearchPath', typically
> '/srv/ganeti/os/*/{create,import,export,rename,verify}'.
>
> Signed-off-by: Jose A. Lopes <[email protected]>
> ---
>  src/Ganeti/Metad/WebServer.hs | 45
> +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>
> diff --git a/src/Ganeti/Metad/WebServer.hs b/src/Ganeti/Metad/WebServer.hs
> index 0e02fda..0c87b81 100644
> --- a/src/Ganeti/Metad/WebServer.hs
> +++ b/src/Ganeti/Metad/WebServer.hs
> @@ -39,6 +39,7 @@ import Snap.Util.FileServe
>  import Snap.Http.Server
>  import Text.JSON (JSValue, Result(..), JSObject)
>  import qualified Text.JSON as JSON
> +import System.FilePath ((</>))
>
>  import Ganeti.Daemon
>  import qualified Ganeti.Constants as Constants
> @@ -51,6 +52,12 @@ import Ganeti.Metad.Types (InstanceParams)
>
>  type MetaM = Snap ()
>
> +split :: String -> [String]
> +split str =
> +  case span (/= '/') str of
> +    (x, []) -> [x]
> +    (x, _:xs) -> x:split xs
> +
>  lookupInstanceParams :: MonadError String m => String -> Map String b ->
> m b
>  lookupInstanceParams inst params =
>    case Map.lookup inst params of
> @@ -95,6 +102,28 @@ serveOsPackage inst instParams =
>              Nothing -> Error $ "Could not find OS package for " ++ show
> inst
>              Just x -> fst <$> (JSON.readJSON x :: Result (String, String))
>
> +serveOsScript :: String -> Map String JSValue -> String -> MetaM
> +serveOsScript inst params script =
> +  do instParams <- lookupInstanceParams inst params
> +     maybeResult (getOsType instParams) $ \os ->
> +       if null os
> +       then throwError $ "There is no OS for " ++ show inst
> +       else serveScript os Constants.osSearchPath
> +  where getOsType instParams =
> +          do obj <- JSON.readJSON instParams :: Result (JSObject JSValue)
> +             case lookup "os" (JSON.fromJSObject obj) of
> +               Nothing -> Error $ "Could not find OS for " ++ show inst
> +               Just x -> JSON.readJSON x :: Result String
> +
> +        serveScript :: String -> [String] -> MetaM
> +        serveScript os [] =
> +          throwError $ "Could not find OS script " ++ show (os </> script)
> +        serveScript os (d:ds) =
> +          serveFile (d </> os </> script)
> +          `CatchIO.catch`
> +          \err -> do let _ = err :: IOError
> +                     serveScript os ds
> +
>  handleMetadata
>    :: MVar InstanceParams -> Method -> String -> String -> String -> MetaM
>  handleMetadata _ GET  "ganeti" "latest" "meta_data.json" =
> @@ -114,6 +143,22 @@ handleMetadata params GET  "ganeti" "latest"
> "os/parameters.json" =
>         \err -> do
>           liftIO . Logging.logWarning $ "Could not serve OS parameters: "
> ++ err
>           error404
> +handleMetadata params GET  "ganeti" "latest" script | isScript script =
> +  do remoteAddr <- ByteString.unpack . rqRemoteAddr <$> getRequest
> +     instanceParams <- liftIO $ do
> +       Logging.logInfo $ "OS package for " ++ show remoteAddr
> +       readMVar params
> +     serveOsScript remoteAddr instanceParams (last $ split script)
> `catchError`
> +       \err -> do
> +         liftIO . Logging.logWarning $ "Could not serve OS scripts: " ++
> err
> +         error404
> +  where isScript =
> +          (`elem` [ "os/scripts/create"
> +                  , "os/scripts/export"
> +                  , "os/scripts/import"
> +                  , "os/scripts/rename"
> +                  , "os/scripts/verify"
> +                  ])
>  handleMetadata _ GET  "ganeti" "latest" "read" =
>    liftIO $ Logging.logInfo "ganeti READ"
>  handleMetadata _ POST "ganeti" "latest" "write" =
> --
> 1.9.1.423.g4596e3a
>
>

Reply via email to