Example #1
0
    def init(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])

        o = shell.call('ceph mon_status')
        mon_status = jsonobject.loads(o)
        fsid = mon_status.monmap.fsid_

        existing_pools = shell.call('ceph osd lspools')
        for pool in cmd.pools:
            if pool.predefined and pool.name not in existing_pools:
                raise Exception(
                    'cannot find pool[%s] in the ceph cluster, you must create it manually'
                    % pool.name)
            if pool.name not in existing_pools and (ceph.is_xsky()
                                                    or ceph.is_sandstone()):
                raise Exception(
                    'The ceph storage type to be added does not support auto initialize pool, please create it manually'
                )
            else:
                shell.call('ceph osd pool create %s 128' % pool.name)

        rsp = InitRsp()
        rsp.fsid = fsid
        self._set_capacity_to_response(rsp)

        return jsonobject.dumps(rsp)
Example #2
0
    def init(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])

        o = shell.call('ceph mon_status')
        mon_status = jsonobject.loads(o)
        fsid = mon_status.monmap.fsid_

        existing_pools = shell.call('ceph osd lspools')
        for pool in cmd.pools:
            if pool.predefined and pool.name not in existing_pools:
                raise Exception(
                    'cannot find pool[%s] in the ceph cluster, you must create it manually'
                    % pool.name)
            if pool.name not in existing_pools and (ceph.is_xsky()
                                                    or ceph.is_sandstone()):
                raise Exception(
                    'The ceph storage type to be added does not support auto initialize pool, please create it manually'
                )
            else:
                shell.call('ceph osd pool create %s 128' % pool.name)

        rsp = InitRsp()

        if cmd.nocephx is False:
            o = shell.call(
                "ceph -f json auth get-or-create client.zstack mon 'allow r' osd 'allow *' 2>/dev/null"
            ).strip(' \n\r\t')
            o = jsonobject.loads(o)
            rsp.userKey = o[0].key_

        rsp.fsid = fsid
        self._set_capacity_to_response(rsp)

        return jsonobject.dumps(rsp)
Example #3
0
    def create(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])

        path = self._normalize_install_path(cmd.installPath)
        rsp = CreateEmptyVolumeRsp()

        call_string = None
        if ceph.is_xsky():
            # do NOT round to MB
            call_string = 'rbd create --size %dB --image-format 2 %s' % (
                cmd.size, path)
            rsp.size = cmd.size
        else:
            size_M = sizeunit.Byte.toMegaByte(cmd.size) + 1
            call_string = 'rbd create --size %s --image-format 2 %s' % (size_M,
                                                                        path)
            rsp.size = cmd.size + sizeunit.MegaByte.toByte(1)

        call_string = self._wrap_shareable_cmd(cmd, call_string)

        skip_cmd = "rbd info %s ||" % path if cmd.skipIfExisting else ""
        shell.call(skip_cmd + call_string)

        self._set_capacity_to_response(rsp)
        return jsonobject.dumps(rsp)
Example #4
0
    def add_pool(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        existing_pools = shell.call('ceph osd pool ls')

        pool_names = existing_pools.split("\n")

        realname = eval('u"' + cmd.poolName + '"').encode('utf-8')
        if not cmd.isCreate and realname not in pool_names:
            raise Exception(
                'cannot find the pool[%s] in the ceph cluster, you must create it manually'
                % realname)

        if cmd.isCreate and realname in pool_names:
            raise Exception(
                'have pool named[%s] in the ceph cluster, can\'t create new pool with same name'
                % realname)

        if (ceph.is_xsky() or ceph.is_sandstone()
            ) and cmd.isCreate and realname not in pool_names:
            raise Exception(
                'current ceph storage type only support add exist pool, please create it manually'
            )

        if realname not in pool_names:
            shell.call('ceph osd pool create %s 128' % realname)

        rsp = AgentResponse()
        self._set_capacity_to_response(rsp)

        return jsonobject.dumps(rsp)
Example #5
0
    def _get_file_actual_size(self, path):
        ret = bash.bash_r("rbd info %s | grep -q fast-diff" % path)

        # if no fast-diff supported and not xsky ceph skip actual size check
        if ret != 0 and not ceph.is_xsky():
            return None

        # use json format result first
        r, jstr = bash.bash_ro("rbd du %s --format json" % path)
        if r == 0 and bool(jstr):
            total_size = 0
            result = jsonobject.loads(jstr)
            if result.images is not None:
                for item in result.images:
                    total_size += int(item.used_size)
                return total_size

        r, size = bash.bash_ro(
            "rbd du %s | awk 'END {if(NF==3) {print $3} else {print $4,$5} }' | sed s/[[:space:]]//g"
            % path,
            pipe_fail=True)
        if r != 0:
            return None

        size = size.strip()
        if not size:
            return None

        return sizeunit.get_size(size)
Example #6
0
    def migrate_volume_segment(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentResponse()
        src_install_path = self._normalize_install_path(cmd.srcInstallPath)
        dst_install_path = self._normalize_install_path(cmd.dstInstallPath)
        src_size = self._get_file_size(src_install_path)
        dst_size = self._get_dst_volume_size(dst_install_path,
                                             cmd.dstMonHostname,
                                             cmd.dstMonSshUsername,
                                             cmd.dstMonSshPassword,
                                             cmd.dstMonSshPort)
        if dst_size > src_size:
            if cmd.isXsky:
                # xsky / ceph -> xsky, size must be equal
                rsp.success = False
                rsp.error = "Failed to migrate volume segment because dst size: %s > src size: %s" % (
                    dst_size, src_size)
                return jsonobject.dumps(rsp)
            elif ceph.is_xsky() == False:
                # ceph -> ceph, don't check size
                rsp.success = True
            else:
                # xsky -> ceph, not supported
                rsp.success = False
                rsp.error = "Failed to migrate volume segment because xsky migrate to ceph is not supported now"
                return jsonobject.dumps(rsp)
        if dst_size < src_size:
            ret = self._resize_dst_volume(dst_install_path, src_size,
                                          cmd.dstMonHostname,
                                          cmd.dstMonSshUsername,
                                          cmd.dstMonSshPassword,
                                          cmd.dstMonSshPort)
            if ret != 0:
                rsp.success = False
                rsp.error = "Failed to resize volume before migrate."
                return jsonobject.dumps(rsp)

        ret = self._migrate_volume_segment(
            cmd.parentUuid, cmd.resourceUuid, cmd.srcInstallPath,
            cmd.dstInstallPath, cmd.dstMonHostname, cmd.dstMonSshUsername,
            cmd.dstMonSshPassword, cmd.dstMonSshPort, cmd)
        if ret != 0:
            rsp.success = False
            rsp.error = "Failed to migrate volume segment from one ceph primary storage to another."
        self._set_capacity_to_response(rsp)
        return jsonobject.dumps(rsp)
Example #7
0
    def _get_file_actual_size(self, path):
        ret = bash.bash_r("rbd info %s | grep -q fast-diff" % path)

        # if no fast-diff supported and not xsky ceph skip actual size check
        if ret != 0 and not ceph.is_xsky():
            return None

        r, size = bash.bash_ro("rbd du %s | tail -1 | awk '{ print $3 }'" %
                               path)

        if r != 0:
            return None

        if not size:
            return None

        size = size.strip('\t\n ')
        return sizeunit.get_size(size)
Example #8
0
    def _set_capacity_to_response(self, rsp):
        o = shell.call('ceph df -f json')
        df = jsonobject.loads(o)

        if df.stats.total_bytes__ is not None:
            total = long(df.stats.total_bytes_)
        elif df.stats.total_space__ is not None:
            total = long(df.stats.total_space__) * 1024
        else:
            raise Exception('unknown ceph df output: %s' % o)

        if df.stats.total_avail_bytes__ is not None:
            avail = long(df.stats.total_avail_bytes_)
        elif df.stats.total_avail__ is not None:
            avail = long(df.stats.total_avail_) * 1024
        else:
            raise Exception('unknown ceph df output: %s' % o)

        rsp.totalCapacity = total
        rsp.availableCapacity = avail
        if ceph.is_xsky():
            rsp.type = "xsky"

        if not df.pools:
            return

        pools = ceph.getCephPoolsCapacity()
        if not pools:
            return

        rsp.poolCapacities = []
        for pool in pools:
            poolCapacity = CephPoolCapacity(pool.poolName,
                                            pool.availableCapacity,
                                            pool.replicatedSize,
                                            pool.usedCapacity,
                                            pool.poolTotalSize)
            rsp.poolCapacities.append(poolCapacity)