Revision 1ca709c1

b/INSTALL
133 133
  `utf8-string <http://hackage.haskell.org/package/utf8-string>`_
134 134
  libraries; these usually come with the GHC compiler
135 135
- `deepseq <http://hackage.haskell.org/package/deepseq>`_
136
- `curl <http://hackage.haskell.org/package/curl>`_, tested with
137
  versions 1.3.4 and above
136 138

  
137 139
Some of these are also available as package in Debian/Ubuntu::
138 140

  
139 141
  $ apt-get install ghc6 libghc6-json-dev libghc6-network-dev \
140
                    libghc6-parallel-dev libghc6-deepseq-dev
142
                    libghc6-parallel-dev libghc6-deepseq-dev \
143
                    libghc6-curl-dev
141 144

  
142 145
Or in newer versions of these distributions (using GHC 7.x)::
143 146

  
144 147
  $ apt-get install ghc libghc-json-dev libghc-network-dev \
145
                    libghc-parallel-dev  libghc-deepseq-dev \
146
                    libghc-utf8-string-dev
148
                    libghc-parallel-dev libghc-deepseq-dev \
149
                    libghc-utf8-string-dev libghc-curl-dev
147 150

  
148
In Fedora, they are available via packages as well::
151
In Fedora, some of them are available via packages as well::
149 152

  
150 153
  $ yum install ghc ghc-json-devel ghc-network-devel \
151 154
                    ghc-parallel-devel ghc-deepseq-devel
......
158 161
Then install the additional libraries via
159 162
``cabal``::
160 163

  
161
  $ cabal install json network parallel utf8-string
162

  
163
The compilation of the htools components is automatically enabled when
164
the compiler and the requisite libraries are found. You can use the
165
``--enable-htools`` configure flag to force the selection (at which
166
point ``./configure`` will fail if it doesn't find the prerequisites).
167

  
164
  $ cabal install json network parallel utf8-string curl
168 165

  
169 166
Haskell optional features
170 167
~~~~~~~~~~~~~~~~~~~~~~~~~
171 168

  
172 169
Optionally, more functionality can be enabled if your build machine has
173
a few more Haskell libraries enabled: RAPI access to remote cluster from
174
htools (``--enable-htools-rapi``), the ``ganeti-confd``
175
daemon (``--enable-confd``) and the monitoring agent
170
a few more Haskell libraries enabled: the ``ganeti-confd`` daemon
171
(``--enable-confd``) and the monitoring agent
176 172
(``--enable-monitoring``). The list of extra dependencies for these is:
177 173

  
178
- `curl <http://hackage.haskell.org/package/curl>`_, tested with
179
  versions 1.3.4 and above
180 174
- `hslogger <http://software.complete.org/hslogger>`_, version 1.1 and
181 175
  above (note that Debian Squeeze only has version 1.0.9)
182 176
- `Crypto <http://hackage.haskell.org/package/Crypto>`_, tested with
......
193 187
the exception of curl), so you can use either apt::
194 188

  
195 189
  $ apt-get install libghc-hslogger-dev libghc-crypto-dev libghc-text-dev \
196
                    libghc-hinotify-dev libghc-regex-pcre-dev libghc-curl-dev \
190
                    libghc-hinotify-dev libghc-regex-pcre-dev \
197 191
                    libghc-attoparsec-dev libghc-vector-dev
198 192

  
199 193
or ``cabal``::
200 194

  
201
  $ cabal install hslogger Crypto text hinotify regex-pcre curl \
195
  $ cabal install hslogger Crypto text hinotify regex-pcre \
202 196
                  attoparsec vector
203 197

  
204 198
to install them.
205 199

  
206
The most recent Fedora doesn't provide ``curl``, ``crypto``,
207
``inotify``. So these need to be installed using ``cabal``, if
208
desired. The other packages can be installed via ``yum``::
200
The most recent Fedora doesn't provide ``crypto``, ``inotify``. So these
201
need to be installed using ``cabal``, if desired. The other packages can
202
be installed via ``yum``::
209 203

  
210 204
  $ yum install ghc-hslogger-devel ghc-text-devel \
211 205
                ghc-regex-pcre-devel
b/Makefile.am
770 770
	@rm -f $(notdir $@).tix
771 771
	$(GHC) --make \
772 772
	  $(HFLAGS) \
773
	  $(HS_NOCURL) $(HS_PARALLEL3) $(HS_REGEX_PCRE) \
773
	  $(HS_PARALLEL3) $(HS_REGEX_PCRE) \
774 774
	  -osuf $(notdir $@).o -hisuf $(notdir $@).hi \
775 775
	  $(HEXTRA) $(HEXTRA_INT) $@
776 776
	@touch "$@"
......
1844 1844
	$(LN_S) ../hscolour.css $(APIDOC_HS_DIR)/Ganeti/Confd/hscolour.css
1845 1845
	set -e ; \
1846 1846
	cd src; \
1847
	if [ "$(HS_NOCURL)" ]; \
1848
	then OPTGHC="--optghc=$(HS_NOCURL)"; \
1849
	else OPTGHC=""; \
1850
	fi; \
1847
	OPTGHC=""; \
1851 1848
	if [ "$(HS_PARALLEL3)" ]; \
1852 1849
	then OPTGHC="$$OPTGHC --optghc=$(HS_PARALLEL3)"; \
1853 1850
	fi; \
......
1871 1868
	rm -f TAGS
1872 1869
	$(GHC) -e ":etags" -v0 \
1873 1870
	  $(filter-out -O -Werror,$(HFLAGS)) \
1874
	  $(HS_NOCURL) $(HS_PARALLEL3) $(HS_REGEX_PCRE) \
1871
	  $(HS_PARALLEL3) $(HS_REGEX_PCRE) \
1875 1872
	  $(HS_LIBTEST_SRCS)
1876 1873
	find . -path './lib/*.py' -o -path './scripts/gnt-*' -o \
1877 1874
	  -path './daemons/ganeti-*' -o -path './tools/*' -o \
b/configure.ac
467 467
  AC_MSG_WARN([qemu-img not found, using ovfconverter will not be possible])
468 468
fi
469 469

  
470
# --enable-htools-rapi
471
HTOOLS_RAPI=
472
AC_ARG_ENABLE([htools-rapi],
473
        [AS_HELP_STRING([--enable-htools-rapi],
474
        [enable use of curl in the Haskell code (default: check)])],
475
        [],
476
        [enable_htools_rapi=check])
477

  
478 470
# --enable-confd
479 471
ENABLE_CONFD=
480 472
AC_ARG_ENABLE([confd],
......
517 509

  
518 510
# check for modules, first custom/special checks
519 511
AC_MSG_NOTICE([checking for required haskell modules])
520
HS_NOCURL=-DNO_CURL
521
if test "$enable_htools_rapi" != no; then
522
  AC_GHC_PKG_CHECK([curl], [HS_NOCURL=], [])
523
  if test -n "$HS_NOCURL"; then
524
    if test "$enable_htools_rapi" = check; then
525
      AC_MSG_WARN(m4_normalize([The curl library was not found, Haskell
526
                                code will be compiled without RAPI support]))
527
    else
528
      AC_MSG_FAILURE(m4_normalize([The curl library was not found, but it has
529
                                   been requested]))
530
    fi
531
  else
532
    AC_MSG_NOTICE([Enabling curl/RAPI/RPC usage in Haskell code])
533
  fi
534
fi
535
AC_SUBST(HS_NOCURL)
536

  
537 512
HS_PARALLEL3=
538 513
AC_GHC_PKG_CHECK([parallel-3.*], [HS_PARALLEL3=-DPARALLEL3],
539 514
                 [AC_GHC_PKG_REQUIRE(parallel)], t)
540 515
AC_SUBST(HS_PARALLEL3)
541 516

  
542 517
# and now standard modules
518
AC_GHC_PKG_REQUIRE(curl)
543 519
AC_GHC_PKG_REQUIRE(json)
544 520
AC_GHC_PKG_REQUIRE(network)
545 521
AC_GHC_PKG_REQUIRE(mtl)
......
641 617
        ;;
642 618
    esac
643 619
  ]],
644
  [[case "x${has_confd}x${HS_NOCURL}x" in
645
     xTruexx)
620
  [[case "x${has_confd}x" in
621
     xTruex)
646 622
       enable_split_query=True
647 623
       ;;
648 624
     *)
......
655 631
  AC_MSG_ERROR([Split queries require the confd daemon])
656 632
fi
657 633

  
658
if test x$enable_split_query = xTrue -a x$HS_NOCURL != x; then
659
  AC_MSG_ERROR([Split queries require the htools-rapi feature (curl library)])
660
fi
661

  
662 634
if test x$enable_split_query = xTrue; then
663 635
  AC_MSG_NOTICE([Split query functionality enabled])
664 636
fi
b/src/Ganeti/HTools/Backend/Rapi.hs
33 33
import Control.Exception
34 34
import Data.List (isPrefixOf)
35 35
import Data.Maybe (fromMaybe)
36
#ifndef NO_CURL
37 36
import Network.Curl
38 37
import Network.Curl.Types ()
39
#endif
40 38
import Control.Monad
41 39
import Text.JSON (JSObject, fromJSObject, decodeStrict)
42 40
import Text.JSON.Types (JSValue(..))
......
61 59
-- | Read an URL via curl and return the body if successful.
62 60
getUrl :: (Monad m) => String -> IO (m String)
63 61

  
64
#ifdef NO_CURL
65
getUrl _ = return $ fail "RAPI/curl backend disabled at compile time"
66

  
67
#else
68

  
69 62
-- | Connection timeout (when using non-file methods).
70 63
connTimeout :: Long
71 64
connTimeout = 15
......
88 81
            CurlOK -> return body
89 82
            _ -> fail $ printf "Curl error for '%s', error %s"
90 83
                 url (show code))
91
#endif
92 84

  
93 85
-- | Helper to convert I/O errors in 'Bad' values.
94 86
ioErrToResult :: IO a -> IO (Result a)
b/src/Ganeti/Rpc.hs
1
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, CPP,
1
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
2 2
  BangPatterns, TemplateHaskell #-}
3 3

  
4 4
{-| Implementation of the RPC client.
......
7 7

  
8 8
{-
9 9

  
10
Copyright (C) 2012 Google Inc.
10
Copyright (C) 2012, 2013 Google Inc.
11 11

  
12 12
This program is free software; you can redistribute it and/or modify
13 13
it under the terms of the GNU General Public License as published by
......
75 75
import qualified Text.JSON as J
76 76
import Text.JSON.Pretty (pp_value)
77 77

  
78
#ifndef NO_CURL
79 78
import Network.Curl
80 79
import qualified Ganeti.Path as P
81
#endif
82 80

  
83 81
import qualified Ganeti.Constants as C
84 82
import Ganeti.Objects
......
88 86

  
89 87
-- * Base RPC functionality and types
90 88

  
91
#ifndef NO_CURL
92 89
-- | The curl options used for RPC.
93 90
curlOpts :: [CurlOption]
94 91
curlOpts = [ CurlFollowLocation False
......
98 95
           , CurlSSLKeyType "PEM"
99 96
           , CurlConnectTimeout (fromIntegral C.rpcConnectTimeout)
100 97
           ]
101
#endif
102 98

  
103 99
-- | Data type for RPC error reporting.
104 100
data RpcError
105
  = CurlDisabledError
106
  | CurlLayerError Node String
101
  = CurlLayerError Node String
107 102
  | JsonDecodeError String
108 103
  | RpcResultError String
109 104
  | OfflineNodeError Node
......
111 106

  
112 107
-- | Provide explanation to RPC errors.
113 108
explainRpcError :: RpcError -> String
114
explainRpcError CurlDisabledError =
115
    "RPC/curl backend disabled at compile time"
116 109
explainRpcError (CurlLayerError node code) =
117 110
    "Curl error for " ++ nodeName node ++ ", " ++ code
118 111
explainRpcError (JsonDecodeError msg) =
......
164 157
                   -> IO (ERpcError String)
165 158

  
166 159
executeHttpRequest _ (Left rpc_err) = return $ Left rpc_err
167
#ifdef NO_CURL
168
executeHttpRequest _ _ = return $ Left CurlDisabledError
169
#else
170 160
executeHttpRequest node (Right request) = do
171 161
  cert_file <- P.nodedCertFile
172 162
  let reqOpts = [ CurlTimeout (fromIntegral $ requestTimeout request)
......
181 171
  return $ case code of
182 172
             CurlOK -> Right body
183 173
             _ -> Left $ CurlLayerError node (show code)
184
#endif
185 174

  
186 175
-- | Prepare url for the HTTP request.
187 176
prepareUrl :: (RpcCall a) => Node -> a -> String

Also available in: Unified diff