Esempio n. 1
0
def add():
    """
    录入新的应用
    :return:
    """
    ps = request.values
    name = ps.get('name')
    version = ps.get('version', default="1.0.0")

    notEmptyStr(name=name, version=version)

    id = ps.get('id')

    app = Application(name=name,
                      id=id,
                      version=version,
                      remark=ps.get('remark'))

    if id and int(id) > 0:
        oldApp = Application.query.get(id)
        if oldApp is None:
            raise ServiceException("ID=%d 的应用不存在故不能编辑" % id)

        copyEntityBean(app, oldApp)
    else:
        # 判断应用名是否重复
        oldApp = Application.query.getOne(name=name)
        if oldApp:
            raise ServiceException("应用 %s 已经存在,不能重复录入" % name)

        db.session.add(app)

    db.session.commit()

    op = "录入" if id is 0 else "编辑"
    LOG.info("%s应用 %s" % (op, app))
    return jsonify(Result.ok("应用 %s %s成功(版本=%s)" % (name, op, version),
                             app.id))
Esempio n. 2
0
def filesystemContent(name):
    """

    :param name:
    :return:
    """
    location = Q("location", "", str)

    file = os.path.join(__detect_app_dir(name), location)
    if not os.path.exists(file):
        raise ServiceException("查询的文件不存在:%s" % location)

    # 读取前 1024 字节判断文本类型
    raw = open(file, 'rb').read(min(512, os.path.getsize(file)))
    result = chardet.detect(raw)
    encoding = result['encoding']

    with open(file, 'r', encoding=encoding) as f:
        try:
            return jsonify(Result.ok(data=f.read()))
        except Exception as e:
            raise ServiceException("尝试用编码 {} 读取 {} 但不成功:{}".format(
                encoding, location, str(e)))
Esempio n. 3
0
def install():
    """
    安装 docker ,只支持 linux 系统

    对于 Linux 系统,直接执行
    curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
    快速安装 docker, 详见:https://yq.aliyun.com/articles/7695?spm=5176.100239.blogcont29941.14.kJOgzy

    :return:
    """
    is_linux = sys.platform == 'Linux'
    if not is_linux:
        raise ServiceException("只支持在 Linux 系统下安装 docker(其他平台请手动安装)")
    # cmd = "curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -"
    pass
Esempio n. 4
0
def filesystemUpload(name):
    """
    上传新文件
    :param name:
    :return:
    """
    file = __detect_file()
    location = Q("location", "", str)
    target_file = os.path.join(__detect_app_dir(name), location, file.filename)

    # 如果文件已经存在,则取消上传
    if os.path.exists(target_file):
        raise ServiceException("目标文件已经存在:%s/%s" % (location, file.filename))

    file.save(target_file)

    return jsonify(Result.ok("文件成功上传到 %s/%s" % (location, file.filename)))
Esempio n. 5
0
def __loadApp(aid):
    app = Application.query.get(aid)
    if app:
        return app
    else:
        raise ServiceException("ID={} 的应用不存在".format(aid))
Esempio n. 6
0
def __detect_file(form_name="file"):
    file = request.files[form_name]
    if file is None:
        raise ServiceException("无法检测到文件,请先上传")
    return file
Esempio n. 7
0
def load_from_file(file_path: str, application: Application, update=False,  **kwargs):
    """
    从指定的目录加载文件(用户上传的文件要求为`zip`格式的压缩文件)
    :param application:
    :param update: True = 迭代更新,False = 全新部署
    :param file_path:
    :param kwargs:
        remove  是否移除同名的旧容器,默认 True

    :return:
    """
    if file_path is None or not os.path.exists(file_path):
        raise ServiceException("参数 file_path 未定义或者找不到相应的文件:%s" % file_path)

    if not file_path.endswith(ZIP):
        raise ServiceException("load_from_file 只支持 %s 结尾的文件" % ZIP)

    app_dir = detect_app_dir(application)

    if update:
        files = update_app_with_zip(file_path, app_dir)
        return application.name, files

    unzip_dir, files = unzip(file_path)
    LOG.info("解压到 %s" % unzip_dir)

    container_name = application.name

    for file in [str(f) for f in files]:
        LOG.debug("processing %s", file)
        if file.endswith(TAR):
            LOG.info("检测到 %s 文件 %s,即将导入该镜像..." % (TAR, file))
            docker.loadImage(os.path.join(unzip_dir, file))
            LOG.info("docker 镜像导入成功")

        if file.endswith(ZIP):
            """对于 zip 格式的文件,解压到程序根目录"""
            unzip(os.path.join(unzip_dir, file), app_dir)
            LOG.info("解压 %s 到 %s" % (file, app_dir))

        if file in ["{}-{}.jar".format(application.name, application.version), "{}.jar".format(application.name)]:
            """
            对于 {application.name}.jar 、 {application.name}-{version}.jar 的文件,直接复制到 app_dir
            通常经过 spring-boot 打包的 jar 可以直接运行
            """
            copyFileToDir(os.path.join(unzip_dir, file), app_dir)

        if file == APP_JSON:
            with open(os.path.join(unzip_dir, file)) as app_json:
                content = __transform_placeholder(app_json.read(), application)
                LOG.info("获取并填充 %s :%s" % (APP_JSON, content))

                app_ps = json.loads(content)
                if 'args' not in app_ps:
                    app_ps['args'] = {}
                if 'image' not in app_ps:
                    raise ServiceException("{} 中必须定义 'image' 属性,否则无法创建容器".format(APP_JSON))

            container_name = detect_app_name(app_ps['args'], app_ps['image'])
            LOG.info("检测到 容器名:%s", container_name)

            # 判断是否需要移除旧的 container
            old_container = None
            if kwargs.pop("remove", True):
                try:
                    old_container = docker.getContainer(container_name)
                    LOG.info("name={} 的容器已经存在:{}, id={}".format(container_name, old_container, old_container.id))
                except Exception:
                    pass

                if old_container is not None:
                    try:
                        old_container.remove()
                        LOG.info("成功删除name=%s 的容器" % container_name)
                    except Exception as e:
                        raise ServiceException("无法删除 name={} 的容器: {}".format(container_name, str(e)))

            network = docker.createDefaultNetwork()
            app_ps['args']['network'] = network.name
            docker.createContainer(app_ps['image'], container_name, app_ps['cmd'], app_ps['args'])
            LOG.info("APP 容器 创建成功(image=%s,name=%s, network=%s)" % (app_ps['image'], container_name, network.name))

    shutil.rmtree(unzip_dir)

    return container_name, files