LGTM, thanks

On Fri, Mar 20, 2015 at 3:32 PM, 'Petr Pudlak' via ganeti-devel <
[email protected]> wrote:

> commit 94d312e52635bed7daac9e86a77873eb2e114e5e
> Merge: 2d2f44d d54e169
> Author: Petr Pudlak <[email protected]>
> Date:   Fri Mar 20 15:29:33 2015 +0100
>
>     Merge branch 'stable-2.12' into stable-2.13
>
>     * stable-2.12
>       QA: Fix CheckFileUnmodified to work with vcluster
>       QA: Fix white-spaces in CheckFileUnmodified
>       QA: Check that the cluster verify doesn't change the config
>       QA: Allow to check that an operation doesn't change a file
>       Use only shared configuration lock for ComputeDRBDMap
>       Only assert properties of non-None objects
>       If any IO error happens during job forking, retry
>       Add a function for retrying `MonadError` computations
>
>     * stable-2.11
>       Improve speed of Xen hypervisor unit tests
>       Improve Xen instance state handling
>
>     * stable-2.10
>       Make QA fail if KVM hotplugging fails
>       Always preserve QA command output
>       Don't lose stdout/stderr in AssertCommand
>       qa_utils: Allow passing fail=None to AssertCommand
>       qa_utils: Make AssertCommand return stdout/stderr as well
>       Allow plain/DRBD conversions regardless of lack of disks
>       Add support for ipolicy modifications to mock config
>
>     Conflicts:
>         lib/cmdlib/instance.py - propagate changes from 2.12
>         qa/qa_cluster.py - propagate changes from 2.12
>         qa/qa_instance.py - propagate changes from 2.12
>         qa/qa_utils.py - propagate changes from 2.12
>         src/Ganeti/Utils/Monad.hs - merge changes from both branches
>
> diff --cc lib/cmdlib/instance.py
> index bed2e3d,d5b2c6b..269e47f
> --- a/lib/cmdlib/instance.py
> +++ b/lib/cmdlib/instance.py
> @@@ -3916,11 -3679,18 +3916,16 @@@ class LUInstanceSetParams(LogicalUnit)
>
>       """
>       secondary_nodes =
> self.cfg.GetInstanceSecondaryNodes(self.instance.uuid)
> -     assert len(secondary_nodes) == 1
> +
>       assert self.instance.disk_template == constants.DT_DRBD8
> +     assert len(secondary_nodes) == 1 or not self.instance.disks
> +
>  -    pnode_uuid = self.instance.primary_node
>  -
> +     # it will not be possible to calculate the snode_uuid later
> +     snode_uuid = None
> +     if secondary_nodes:
> +       snode_uuid = secondary_nodes[0]
>
> -     snode_uuid = secondary_nodes[0]
>  -    feedback_fn("Converting template to plain")
>  +    feedback_fn("Converting disk template from 'drbd' to 'plain'")
>
>       disks = self.cfg.GetInstanceDisks(self.instance.uuid)
>       old_disks = AnnotateDiskParams(self.instance, disks, self.cfg)
> diff --cc qa/qa_cluster.py
> index 51a3b15,adf508a..166a5ee
> --- a/qa/qa_cluster.py
> +++ b/qa/qa_cluster.py
> @@@ -51,8 -51,8 +51,8 @@@ import qa_job_util
>   import qa_logging
>   import qa_utils
>
>  -from qa_utils import AssertEqual, AssertCommand, GetCommandOutput, \
>  -                     CheckFileUnmodified
>  +from qa_utils import AssertEqual, AssertCommand,
> AssertRedirectedCommand, \
> -   GetCommandOutput
> ++  GetCommandOutput, CheckFileUnmodified
>
>
>   # Prefix for LVM volumes created by QA code during tests
> diff --cc qa/qa_instance.py
> index ffe6a31,6cbe96e..a00cfa7
> --- a/qa/qa_instance.py
> +++ b/qa/qa_instance.py
> @@@ -633,22 -630,7 +652,14 @@@ def TestInstanceModify(instance)
>         ])
>     elif default_hv == constants.HT_KVM and \
>       qa_config.TestEnabled("instance-device-hotplug"):
> -     args.extend([
> -       ["--net", "-1:add", "--hotplug"],
> -       ["--net", "-1:modify,mac=aa:bb:cc:dd:ee:ff", "--hotplug",
> "--force"],
> -       ["--net", "-1:remove", "--hotplug"],
> -       ])
> -     args.extend([
> -       ["--disk", "-1:add,size=1G", "--hotplug"],
> -       ["--disk", "-1:remove", "--hotplug"],
> -       ])
> +     _TestKVMHotplug(instance)
>  +  elif default_hv == constants.HT_LXC:
>  +    args.extend([
>  +      ["-H", "%s=0" % constants.HV_CPU_MASK],
>  +      ["-H", "%s=%s" % (constants.HV_CPU_MASK, constants.VALUE_DEFAULT)],
>  +      ["-H", "%s=0" % constants.HV_LXC_NUM_TTYS],
>  +      ["-H", "%s=%s" % (constants.HV_LXC_NUM_TTYS,
> constants.VALUE_DEFAULT)],
>  +      ])
>
>     url = "http://example.com/busybox.img";
>     args.extend([
> diff --cc src/Ganeti/Utils/Monad.hs
> index c1bd630,0000000..cd09a0d
> mode 100644,000000..100644
> --- a/src/Ganeti/Utils/Monad.hs
> +++ b/src/Ganeti/Utils/Monad.hs
> @@@ -1,87 -1,0 +1,97 @@@
>  +{-| Utility functions for MonadPlus operations
>  +
>  +-}
>  +
>  +{-
>  +
>  +Copyright (C) 2014 Google Inc.
>  +All rights reserved.
>  +
>  +Redistribution and use in source and binary forms, with or without
>  +modification, are permitted provided that the following conditions are
>  +met:
>  +
>  +1. Redistributions of source code must retain the above copyright notice,
>  +this list of conditions and the following disclaimer.
>  +
>  +2. Redistributions in binary form must reproduce the above copyright
>  +notice, this list of conditions and the following disclaimer in the
>  +documentation and/or other materials provided with the distribution.
>  +
>  +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
>  +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
>  +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> PARTICULAR
>  +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
>  +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
>  +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
>  +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
>  +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
>  +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
>  +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
>  +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>  +
>  +-}
>  +
>  +module Ganeti.Utils.Monad
>  +  ( mretryN
>  +  , retryMaybeN
>  +  , anyM
>  +  , allM
>  +  , orM
>  +  , unfoldrM
>  +  , unfoldrM'
> ++  , retryErrorN
>  +  ) where
>  +
>  +import Control.Monad
> ++import Control.Monad.Error
>  +import Control.Monad.Trans.Maybe
>  +
>  +-- | Retries the given action up to @n@ times.
>  +-- The action signals failure by 'mzero'.
>  +mretryN :: (MonadPlus m) => Int -> (Int -> m a) -> m a
>  +mretryN n = msum . flip map [1..n]
>  +
>  +-- | Retries the given action up to @n@ times.
>  +-- The action signals failure by 'mzero'.
>  +retryMaybeN :: (Monad m) => Int -> (Int -> MaybeT m a) -> m (Maybe a)
>  +retryMaybeN = (runMaybeT .) . mretryN
>  +
> ++-- | Retries the given action up to @n@ times until it succeeds.
> ++-- If all actions fail, the error of the last one is returned.
> ++-- The action is always run at least once, even if @n@ is less than 1.
> ++retryErrorN :: (MonadError e m) => Int -> (Int -> m a) -> m a
> ++retryErrorN n f = loop 1
> ++  where
> ++    loop i | i < n      = catchError (f i) (const $ loop (i + 1))
> ++           | otherwise  = f i
>  +
> - -- From monad-loops (until we can / want to depend on it):
> ++-- * From monad-loops (until we can / want to depend on it):
>  +
>  +-- | Short-circuit 'any' with a monadic predicate.
>  +anyM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
>  +anyM p = foldM (\v x -> if v then return True else p x) False
>  +
>  +-- | Short-circuit 'all' with a monadic predicate.
>  +allM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
>  +allM p = foldM (\v x -> if v then p x else return False) True
>  +
>  +-- | Short-circuit 'or' for values of type Monad m => m Bool
>  +orM :: (Monad m) => [m Bool] -> m Bool
>  +orM = anyM id
>  +
>  +-- |See 'Data.List.unfoldr'.  This is a monad-friendly version of that.
>  +unfoldrM :: (Monad m) => (a -> m (Maybe (b,a))) -> a -> m [b]
>  +unfoldrM = unfoldrM'
>  +
>  +-- | See 'Data.List.unfoldr'. This is a monad-friendly version of that,
> with a
>  +-- twist. Rather than returning a list, it returns any MonadPlus type of
> your
>  +-- choice.
>  +unfoldrM' :: (Monad m, MonadPlus f) => (a -> m (Maybe (b,a))) -> a -> m
> (f b)
>  +unfoldrM' f z = do
>  +        x <- f z
>  +        case x of
>  +                Nothing         -> return mzero
>  +                Just (x', z')   -> do
>  +                        xs <- unfoldrM' f z'
>  +                        return (return x' `mplus` xs)
>

Hrvoje Ribicic
Ganeti Engineering
Google Germany GmbH
Dienerstr. 12, 80331, München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Christine Elizabeth Flores
Steuernummer: 48/725/00206
Umsatzsteueridentifikationsnummer: DE813741370

Reply via email to