diff --git a/wally/utils.py b/wally/utils.py
index a0f10e8..dfd0e8c 100644
--- a/wally/utils.py
+++ b/wally/utils.py
@@ -1,33 +1,19 @@
-import re
 import os
 import sys
-import math
-import time
 import uuid
-import socket
 import logging
 import datetime
-import ipaddress
-import threading
 import contextlib
-import subprocess
-from fractions import Fraction
 
-from typing import Any, Tuple, Union, List, Iterator, Iterable, Optional, IO, cast, TypeVar, Callable
-
-try:
-    import psutil
-except ImportError:
-    psutil = None
+from typing import Any, Tuple, Iterator, Iterable
 
 try:
     from petname import Generate as pet_generate
 except ImportError:
-    def pet_generate(x: str, y: str) -> str:
+    def pet_generate(_1: str, _2: str) -> str:
         return str(uuid.uuid4())
 
-
-from .types import TNumber, Number
+from cephlib.common import run_locally, sec_to_str
 
 
 logger = logging.getLogger("wally")
@@ -65,63 +51,6 @@
     pass
 
 
-class Timeout(Iterable[float]):
-    def __init__(self, timeout: int, message: str = None, min_tick: int = 1, no_exc: bool = False) -> None:
-        self.end_time = time.time() + timeout
-        self.message = message
-        self.min_tick = min_tick
-        self.prev_tick_at = time.time()
-        self.no_exc = no_exc
-
-    def tick(self) -> bool:
-        current_time = time.time()
-
-        if current_time > self.end_time:
-            if self.message:
-                msg = "Timeout: {}".format(self.message)
-            else:
-                msg = "Timeout"
-
-            if self.no_exc:
-                return False
-
-            raise TimeoutError(msg)
-
-        sleep_time = self.min_tick - (current_time - self.prev_tick_at)
-        if sleep_time > 0:
-            time.sleep(sleep_time)
-            self.prev_tick_at = time.time()
-        else:
-            self.prev_tick_at = current_time
-
-        return True
-
-    def __iter__(self) -> Iterator[float]:
-        return cast(Iterator[float], self)
-
-    def __next__(self) -> float:
-        if not self.tick():
-            raise StopIteration()
-        return self.end_time - time.time()
-
-
-def greater_digit_pos(val: Number) -> int:
-    return int(math.floor(math.log10(val))) + 1
-
-
-def round_digits(val: TNumber, num_digits: int = 3) -> TNumber:
-    pow = 10 ** (greater_digit_pos(val) - num_digits)
-    return type(val)(int(val / pow) * pow)
-
-
-def is_ip(data: str) -> bool:
-    try:
-        ipaddress.ip_address(data)
-        return True
-    except ValueError:
-        return False
-
-
 def log_block(message: str, exc_logger:logging.Logger = None) -> LogError:
     logger.debug("Starts : " + message)
     return LogError(message, exc_logger)
@@ -133,212 +62,6 @@
         raise StopTestError(message)
 
 
-def parse_creds(creds: str) -> Tuple[str, str, str]:
-    """Parse simple credentials format user[:passwd]@host"""
-    user, passwd_host = creds.split(":", 1)
-
-    if '@' not in passwd_host:
-        passwd, host = passwd_host, None
-    else:
-        passwd, host = passwd_host.rsplit('@', 1)
-
-    return user, passwd, host
-
-
-SMAP = dict(k=1024, m=1024 ** 2, g=1024 ** 3, t=1024 ** 4)
-
-
-def ssize2b(ssize: Union[str, int]) -> int:
-    try:
-        if isinstance(ssize, int):
-            return ssize
-
-        ssize = ssize.lower()
-        if ssize[-1] in SMAP:
-            return int(ssize[:-1]) * SMAP[ssize[-1]]
-        return int(ssize)
-    except (ValueError, TypeError, AttributeError):
-        raise ValueError("Unknow size format {!r}".format(ssize))
-
-
-RSMAP = [('K', 1024),
-         ('M', 1024 ** 2),
-         ('G', 1024 ** 3),
-         ('T', 1024 ** 4)]
-
-
-def b2ssize(value: Union[int, float]) -> str:
-    if isinstance(value, float) and value < 100:
-        return b2ssize_10(value)
-
-    value = int(value)
-    if value < 1024:
-        return str(value) + " "
-
-    # make mypy happy
-    scale = 1
-    name = ""
-
-    for name, scale in RSMAP:
-        if value < 1024 * scale:
-            if value % scale == 0:
-                return "{} {}i".format(value // scale, name)
-            else:
-                return "{:.1f} {}i".format(float(value) / scale, name)
-
-    return "{}{}i".format(value // scale, name)
-
-
-RSMAP_10 = [(' f', 0.001 ** 4),
-            (' n', 0.001 ** 3),
-            (' u', 0.001 ** 2),
-            (' m', 0.001),
-            (' ', 1),
-            (' K', 1000),
-            (' M', 1000 ** 2),
-            (' G', 1000 ** 3),
-            (' T', 1000 ** 4),
-            (' P', 1000 ** 5),
-            (' E', 1000 ** 6)]
-
-
-def has_next_digit_after_coma(x: float) -> bool:
-    return x * 10 - int(x * 10) > 1
-
-
-def has_second_digit_after_coma(x: float) -> bool:
-    return (x * 10 - int(x * 10)) * 10 > 1
-
-
-def b2ssize_10(value: Union[int, float]) -> str:
-    # make mypy happy
-    scale = 1
-    name = " "
-
-    if value == 0.0:
-        return "0 "
-
-    if value / RSMAP_10[0][1] < 1.0:
-        return "{:.2e} ".format(value)
-
-    for name, scale in RSMAP_10:
-        cval = value / scale
-        if cval < 1000:
-            # detect how many digits after dot to show
-            if cval > 100:
-                return "{}{}".format(int(cval), name)
-            if cval > 10:
-                if has_next_digit_after_coma(cval):
-                    return "{:.1f}{}".format(cval, name)
-                else:
-                    return "{}{}".format(int(cval), name)
-            if cval >= 1:
-                if has_second_digit_after_coma(cval):
-                    return "{:.2f}{}".format(cval, name)
-                elif has_next_digit_after_coma(cval):
-                    return "{:.1f}{}".format(cval, name)
-                return "{}{}".format(int(cval), name)
-            raise AssertionError("Can't get here")
-
-    return "{}{}".format(int(value // scale), name)
-
-
-def run_locally(cmd: Union[str, List[str]], input_data: str = "", timeout: int = 20) -> str:
-    if isinstance(cmd, str):
-        shell = True
-        cmd_str = cmd
-    else:
-        shell = False
-        cmd_str = " ".join(cmd)
-
-    proc = subprocess.Popen(cmd,
-                            shell=shell,
-                            stdin=subprocess.PIPE,
-                            stdout=subprocess.PIPE,
-                            stderr=subprocess.PIPE)
-    res = []  # type: List[Tuple[bytes, bytes]]
-
-    def thread_func() -> None:
-        rr = proc.communicate(input_data.encode("utf8"))
-        res.extend(rr)
-
-    thread = threading.Thread(target=thread_func,
-                              name="Local cmd execution")
-    thread.daemon = True
-    thread.start()
-    thread.join(timeout)
-
-    if thread.is_alive():
-        if psutil is not None:
-            parent = psutil.Process(proc.pid)
-            for child in parent.children(recursive=True):
-                child.kill()
-            parent.kill()
-        else:
-            proc.kill()
-
-        thread.join()
-        raise RuntimeError("Local process timeout: " + cmd_str)
-
-    stdout_data, stderr_data = zip(*res)  # type: List[bytes], List[bytes]
-
-    out = b"".join(stdout_data).decode("utf8")
-    err = b"".join(stderr_data).decode("utf8")
-
-    if 0 != proc.returncode:
-        raise subprocess.CalledProcessError(proc.returncode,
-                                            cmd_str, out + err)
-
-    return out
-
-
-def get_ip_for_target(target_ip: str) -> str:
-    if not is_ip(target_ip):
-        target_ip = socket.gethostbyname(target_ip)
-
-    first_dig = map(int, target_ip.split("."))
-    if first_dig == 127:
-        return '127.0.0.1'
-
-    data = run_locally('ip route get to'.split(" ") + [target_ip])
-
-    rr1 = r'{0} via [.0-9]+ dev (?P<dev>.*?) src (?P<ip>[.0-9]+)$'
-    rr1 = rr1.replace(" ", r'\s+')
-    rr1 = rr1.format(target_ip.replace('.', r'\.'))
-
-    rr2 = r'{0} dev (?P<dev>.*?) src (?P<ip>[.0-9]+)$'
-    rr2 = rr2.replace(" ", r'\s+')
-    rr2 = rr2.format(target_ip.replace('.', r'\.'))
-
-    data_line = data.split("\n")[0].strip()
-    res1 = re.match(rr1, data_line)
-    res2 = re.match(rr2, data_line)
-
-    if res1 is not None:
-        return res1.group('ip')
-
-    if res2 is not None:
-        return res2.group('ip')
-
-    raise OSError("Can't define interface for {0}".format(target_ip))
-
-
-def open_for_append_or_create(fname: str) -> IO[str]:
-    if not os.path.exists(fname):
-        return open(fname, "w")
-
-    fd = open(fname, 'r+')
-    fd.seek(0, os.SEEK_END)
-    return fd
-
-
-def sec_to_str(seconds: int) -> str:
-    h = seconds // 3600
-    m = (seconds % 3600) // 60
-    s = seconds % 60
-    return "{}:{:02d}:{:02d}".format(h, m, s)
-
-
 def yamable(data: Any) -> Any:
     if isinstance(data, (tuple, list)):
         return map(yamable, data)
@@ -352,16 +75,6 @@
     return data
 
 
-def flatten(data: Iterable[Any]) -> List[Any]:
-    res = []
-    for i in data:
-        if isinstance(i, (list, tuple, set)):
-            res.extend(flatten(i))
-        else:
-            res.append(i)
-    return res
-
-
 def get_creds_openrc(path: str) -> Tuple[str, str, str, str, bool]:
     fc = open(path).read()
 
@@ -369,7 +82,7 @@
 
     msg = "Failed to get creads from openrc file"
     with LogError(msg):
-        data = run_locally(['/bin/bash'], input_data=fc + "\n" + echo)
+        data = run_locally(['/bin/bash'], input_data=(fc + "\n" + echo).encode('utf8')).decode("utf8")
 
     msg = "Failed to get creads from openrc file: " + data
     with LogError(msg):
@@ -383,19 +96,6 @@
     return user, passwd, tenant, auth_url, insecure
 
 
-def which(program: str) -> Optional[str]:
-    def is_exe(fpath):
-        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
-
-    for path in os.environ["PATH"].split(os.pathsep):
-        path = path.strip('"')
-        exe_file = os.path.join(path, program)
-        if is_exe(exe_file):
-            return exe_file
-
-    return None
-
-
 @contextlib.contextmanager
 def empty_ctx(val: Any = None) -> Iterator[Any]:
     yield val
@@ -414,17 +114,6 @@
     return results_dir, run_uuid
 
 
-def to_ip(host_or_ip: str) -> str:
-    # translate hostname to address
-    try:
-        ipaddress.ip_address(host_or_ip)
-        return host_or_ip
-    except ValueError:
-        ip_addr = socket.gethostbyname(host_or_ip)
-        logger.info("Will use ip_addr %r instead of hostname %r", ip_addr, host_or_ip)
-        return ip_addr
-
-
 def get_time_interval_printable_info(seconds: int) -> Tuple[str, str]:
     exec_time_s = sec_to_str(seconds)
     now_dt = datetime.datetime.now()
@@ -432,68 +121,6 @@
     return exec_time_s, "{:%H:%M:%S}".format(end_dt)
 
 
-FM_FUNC_INPUT = TypeVar("FM_FUNC_INPUT")
-FM_FUNC_RES = TypeVar("FM_FUNC_RES")
-
-
-def flatmap(func: Callable[[FM_FUNC_INPUT], Iterable[FM_FUNC_RES]],
-            inp_iter: Iterable[FM_FUNC_INPUT]) -> Iterator[FM_FUNC_RES]:
-    for val in inp_iter:
-        for res in func(val):
-            yield res
-
-
-_coefs = {
-    'n': Fraction(1, 1000**3),
-    'u': Fraction(1, 1000**2),
-    'm': Fraction(1, 1000),
-    'K': 1000,
-    'M': 1000 ** 2,
-    'G': 1000 ** 3,
-    'Ki': 1024,
-    'Mi': 1024 ** 2,
-    'Gi': 1024 ** 3,
-}
-
-
-def split_unit(units: str) -> Tuple[Union[Fraction, int], str]:
-    if len(units) > 2 and units[:2] in _coefs:
-        return _coefs[units[:2]], units[2:]
-    if len(units) > 1 and units[0] in _coefs:
-        return _coefs[units[0]], units[1:]
-    else:
-        return 1, units
-
-
-conversion_cache = {}
-
-
-def unit_conversion_coef(from_unit: str, to_unit: str) -> Union[Fraction, int]:
-    key = (from_unit, to_unit)
-    if key in conversion_cache:
-        return conversion_cache[key]
-
-    f1, u1 = split_unit(from_unit)
-    f2, u2 = split_unit(to_unit)
-
-    assert u1 == u2, "Can't convert {!r} to {!r}".format(from_unit, to_unit)
-
-    if isinstance(f1, int) and isinstance(f2, int):
-        if f1 % f2 != 0:
-            res = Fraction(f1, f2)
-        else:
-            res = f1 // f2
-    else:
-        res = f1 / f2
-
-    if isinstance(res, Fraction) and cast(Fraction, res).denominator == 1:
-        res = cast(Fraction, res).numerator
-
-    conversion_cache[key] = res
-
-    return res
-
-
 def shape2str(shape: Iterable[int]) -> str:
     return "*".join(map(str, shape))
 
