Revision 11e90588
b/lib/network.py | ||
---|---|---|
26 | 26 |
import ipaddr |
27 | 27 |
|
28 | 28 |
from bitarray import bitarray |
29 |
from base64 import b64encode |
|
30 |
from base64 import b64decode |
|
29 | 31 |
|
30 | 32 |
from ganeti import errors |
31 | 33 |
|
... | ... | |
92 | 94 |
self.gateway6 = ipaddr.IPv6Address(self.net.gateway6) |
93 | 95 |
|
94 | 96 |
if self.net.reservations: |
95 |
self.reservations = bitarray(self.net.reservations) |
|
97 |
self.reservations = bitarray() |
|
98 |
# pylint: disable=E1103 |
|
99 |
self.reservations.frombytes(b64decode(self.net.reservations)) |
|
96 | 100 |
else: |
97 | 101 |
self.reservations = bitarray(self.network.numhosts) |
98 | 102 |
# pylint: disable=E1103 |
99 | 103 |
self.reservations.setall(False) |
100 | 104 |
|
101 | 105 |
if self.net.ext_reservations: |
102 |
self.ext_reservations = bitarray(self.net.ext_reservations) |
|
106 |
self.ext_reservations = bitarray() |
|
107 |
# pylint: disable=E1103 |
|
108 |
self.ext_reservations.frombytes(b64decode(self.net.ext_reservations)) |
|
103 | 109 |
else: |
104 | 110 |
self.ext_reservations = bitarray(self.network.numhosts) |
105 | 111 |
# pylint: disable=E1103 |
... | ... | |
129 | 135 |
|
130 | 136 |
""" |
131 | 137 |
# pylint: disable=E1103 |
132 |
self.net.ext_reservations = self.ext_reservations.to01()
|
|
133 |
self.net.reservations = self.reservations.to01()
|
|
138 |
self.net.ext_reservations = b64encode(self.ext_reservations.tobytes())
|
|
139 |
self.net.reservations = b64encode(self.reservations.tobytes())
|
|
134 | 140 |
|
135 | 141 |
def _Mark(self, address, value=True, external=False): |
136 | 142 |
idx = self._GetAddrIndex(address) |
b/src/Ganeti/Network.hs | ||
---|---|---|
41 | 41 |
import qualified Data.Vector.Unboxed as V |
42 | 42 |
|
43 | 43 |
import Ganeti.Objects |
44 |
import Ganeti.Utils (b64StringToBitString) |
|
44 | 45 |
|
45 | 46 |
-- | An address pool, holding a network plus internal and external |
46 | 47 |
-- reservations. |
... | ... | |
75 | 76 |
-- | Converts a maybe bit string to a bit vector. Returns an empty bit vector on |
76 | 77 |
-- nothing. |
77 | 78 |
maybeStr2BitVec :: Maybe String -> V.Vector Bool |
78 |
maybeStr2BitVec (Just s) = bitStringToBitVector s |
|
79 |
maybeStr2BitVec (Just s) = bitStringToBitVector $ b64StringToBitString s
|
|
79 | 80 |
maybeStr2BitVec Nothing = V.fromList ([]::[Bool]) |
80 | 81 |
|
81 | 82 |
-- | Converts a string to a bit vector. The character '0' is interpreted |
b/src/Ganeti/Query/Network.hs | ||
---|---|---|
46 | 46 |
import Ganeti.Query.Common |
47 | 47 |
import Ganeti.Query.Types |
48 | 48 |
import Ganeti.Types |
49 |
import Ganeti.Utils (b64StringToBitString) |
|
49 | 50 |
|
50 | 51 |
-- | There is no actual runtime. |
51 | 52 |
data Runtime = Runtime |
... | ... | |
175 | 176 |
getExtReservationsString :: Network -> ResultEntry |
176 | 177 |
getExtReservationsString net = |
177 | 178 |
let addrs = getReservations (networkNetwork net) |
178 |
(fromMaybe "" $ networkExtReservations net) |
|
179 |
(b64StringToBitString $ fromMaybe "" $ networkExtReservations net)
|
|
179 | 180 |
in rsNormal . intercalate ", " $ map show addrs |
180 | 181 |
|
181 | 182 |
-- | Dummy function for collecting live data (which networks don't have). |
b/src/Ganeti/Utils.hs | ||
---|---|---|
58 | 58 |
, splitEithers |
59 | 59 |
, recombineEithers |
60 | 60 |
, setOwnerAndGroupFromNames |
61 |
, b64StringToBitString |
|
62 |
, bitStringToB64String |
|
61 | 63 |
) where |
62 | 64 |
|
63 | 65 |
import Data.Char (toUpper, isAlphaNum, isDigit, isSpace) |
... | ... | |
77 | 79 |
import System.Posix.Files |
78 | 80 |
import System.Time |
79 | 81 |
|
82 |
import qualified Data.ByteString as BS |
|
83 |
import Data.ByteString.Base64 (decodeLenient, encode) |
|
84 |
import qualified Data.ByteString.Char8 as BSC |
|
85 |
import Data.Word (Word8) |
|
86 |
import Data.Char (intToDigit, digitToInt) |
|
87 |
import Numeric (showIntAtBase, readInt) |
|
88 |
|
|
80 | 89 |
-- * Debug functions |
81 | 90 |
|
82 | 91 |
-- | To be used only for debugging, breaks referential integrity. |
... | ... | |
458 | 467 |
let uid = fst ents M.! daemon |
459 | 468 |
let gid = snd ents M.! dGroup |
460 | 469 |
setOwnerAndGroup filename uid gid |
470 |
|
|
471 |
type BitString = String |
|
472 |
|
|
473 |
-- | Base 64 encoded String to BitString |
|
474 |
wordsToBitString :: [Word8] -> BitString |
|
475 |
wordsToBitString = |
|
476 |
concatMap (padBits . wordToBits) |
|
477 |
where |
|
478 |
wordToBits = flip (showIntAtBase 2 intToDigit) "" |
|
479 |
padBits bs = replicate (8 - length bs) '0' ++ bs |
|
480 |
|
|
481 |
decodeB64String :: String -> [Word8] |
|
482 |
decodeB64String = BS.unpack . decodeLenient . BSC.pack |
|
483 |
|
|
484 |
b64StringToBitString :: String -> BitString |
|
485 |
b64StringToBitString = wordsToBitString . decodeB64String |
|
486 |
|
|
487 |
-- | A BitString to Base 64 encoded String |
|
488 |
bitStringToWords :: BitString -> [Word8] |
|
489 |
bitStringToWords [] = [] |
|
490 |
bitStringToWords bs = |
|
491 |
bitStringToWord c : bitStringToWords rest |
|
492 |
where |
|
493 |
bitStringToWord = fst . head . readInt 2 (const True) digitToInt |
|
494 |
(c, rest) = splitAt 8 bs |
|
495 |
|
|
496 |
encodeB64String :: [Word8] -> String |
|
497 |
encodeB64String = BSC.unpack . encode . BS.pack |
|
498 |
|
|
499 |
bitStringToB64String :: BitString -> String |
|
500 |
bitStringToB64String = encodeB64String . bitStringToWords |
b/test/hs/Test/Ganeti/Objects.hs | ||
---|---|---|
62 | 62 |
import Ganeti.Objects as Objects |
63 | 63 |
import Ganeti.JSON |
64 | 64 |
import Ganeti.Types |
65 |
import Ganeti.Utils (bitStringToB64String) |
|
65 | 66 |
|
66 | 67 |
-- * Arbitrary instances |
67 | 68 |
|
... | ... | |
238 | 239 |
genValidNetwork :: Gen Objects.Network |
239 | 240 |
genValidNetwork = do |
240 | 241 |
-- generate netmask for the IPv4 network |
241 |
netmask <- fromIntegral <$> choose (24::Int, 30)
|
|
242 |
netmask <- fromIntegral <$> choose (24::Int, 29)
|
|
242 | 243 |
name <- genName >>= mkNonEmpty |
243 | 244 |
mac_prefix <- genMaybe genName |
244 | 245 |
net <- arbitrary |
245 | 246 |
net6 <- genMaybe genIp6Net |
246 | 247 |
gateway <- genMaybe arbitrary |
247 | 248 |
gateway6 <- genMaybe genIp6Addr |
248 |
res <- liftM Just (genBitString $ netmask2NumHosts netmask) |
|
249 |
ext_res <- liftM Just (genBitString $ netmask2NumHosts netmask) |
|
249 |
res <- liftM (Just . bitStringToB64String) |
|
250 |
(genBitString $ netmask2NumHosts netmask) |
|
251 |
ext_res <- liftM (Just . bitStringToB64String) |
|
252 |
(genBitString $ netmask2NumHosts netmask) |
|
250 | 253 |
uuid <- arbitrary |
251 | 254 |
ctime <- arbitrary |
252 | 255 |
mtime <- arbitrary |
b/tools/cfgupgrade | ||
---|---|---|
34 | 34 |
import logging |
35 | 35 |
import time |
36 | 36 |
from cStringIO import StringIO |
37 |
from bitarray import bitarray |
|
38 |
from base64 import b64encode, b64decode |
|
37 | 39 |
|
38 | 40 |
from ganeti import constants |
39 | 41 |
from ganeti import serializer |
... | ... | |
126 | 128 |
_FillIPolicySpecs(default_ipolicy, ipolicy) |
127 | 129 |
|
128 | 130 |
|
131 |
# pylint: disable=E1101 |
|
129 | 132 |
def UpgradeNetworks(config_data): |
130 |
networks = config_data.get("networks", None)
|
|
133 |
networks = config_data.get("networks", {})
|
|
131 | 134 |
if not networks: |
132 | 135 |
config_data["networks"] = {} |
136 |
for nobj in networks.values(): |
|
137 |
for key in ("reservations", "ext_reservations"): |
|
138 |
r = nobj[key] |
|
139 |
if options.tob64: |
|
140 |
try: |
|
141 |
b = bitarray(r) |
|
142 |
nobj[key] = b64encode(b.tobytes()) |
|
143 |
except ValueError: |
|
144 |
print("No 01 network found! Probably already in base64.") |
|
145 |
if options.to01: |
|
146 |
try: |
|
147 |
b = bitarray(r) |
|
148 |
print("01 network found! Do nothing.") |
|
149 |
except ValueError: |
|
150 |
b = bitarray() |
|
151 |
b.frombytes(b64decode(r)) |
|
152 |
nobj[key] = b.to01() |
|
153 |
print("%s: %s -> %s" % (nobj["name"], r, nobj[key])) |
|
133 | 154 |
|
134 | 155 |
|
135 | 156 |
def UpgradeCluster(config_data): |
... | ... | |
395 | 416 |
parser.add_option("--downgrade", |
396 | 417 |
help="Downgrade to the previous stable version", |
397 | 418 |
action="store_true", dest="downgrade", default=False) |
419 |
parser.add_option("--tob64", |
|
420 |
help="Change to base64 encoded networks", |
|
421 |
action="store_true", dest="tob64", default=False) |
|
422 |
parser.add_option("--to01", |
|
423 |
help="Change to non encoded networks (01 bitarrays)", |
|
424 |
action="store_true", dest="to01", default=False) |
|
398 | 425 |
(options, args) = parser.parse_args() |
399 | 426 |
|
400 | 427 |
# We need to keep filenames locally because they might be renamed between |
Also available in: Unified diff