示例#1
0
def api_cross_symlink(username, repository, sourcename, linkname):
    flist = HubPublicFlist(config, repository, sourcename)
    linkflist = HubPublicFlist(config, username, linkname)

    if not flist.user_exists:
        return api_response("source repository not found", 404)

    if not flist.file_exists:
        return api_response("source not found", 404)

    # remove previous symlink if existing
    if os.path.islink(linkflist.target):
        os.unlink(linkflist.target)

    # if it was not a link but a regular file, we don't overwrite
    # existing flist, we only allows updating links
    if os.path.isfile(linkflist.target):
        return api_response("link destination is already a file", 401)

    cwd = os.getcwd()
    os.chdir(linkflist.user_path)

    os.symlink("../" + flist.username + "/" + flist.filename,
               linkflist.filename)
    os.chdir(cwd)

    return api_response()
示例#2
0
def api_promote(username, sourcerepo, sourcefile, targetname):
    flist = HubPublicFlist(config, sourcerepo, sourcefile)
    destination = HubPublicFlist(config, username, targetname)

    if not flist.user_exists:
        return api_response("user not found", 404)

    if not flist.file_exists:
        return api_response("source not found", 404)

    # ensure target exists
    if not destination.user_exists:
        destination.user_create()

    # remove previous file if existing
    if os.path.exists(destination.target):
        os.unlink(destination.target)

    print("[+] promote: %s -> %s" % (flist.target, destination.target))
    shutil.copy(flist.target, destination.target)

    status = {
        'source': {
            'username': flist.username,
            'filename': flist.filename,
        },
        'destination': {
            'username': destination.username,
            'filename': destination.filename,
        }
    }

    return api_response(extra=status)
示例#3
0
def api_flist_upload(request, username, validate=False):
    # check if the post request has the file part
    if 'file' not in request.files:
        return {'status': 'error', 'message': 'no file found'}

    file = request.files['file']

    # if user does not select file, browser also
    # submit a empty part without filename
    if file.filename == '':
        return {'status': 'error', 'message': 'no file selected'}

    if not allowed_file(file.filename, validate):
        return {'status': 'error', 'message': 'this file is not allowed'}

    #
    # processing the file
    #
    filename = secure_filename(file.filename)

    print("[+] saving file")
    source = os.path.join(config['upload-directory'], filename)
    file.save(source)

    cleanfilename = file_from_flist(filename)
    flist = HubPublicFlist(config, username, cleanfilename)
    flist.user_create()

    # it's a new flist, let's do the normal flow
    if not validate:
        workspace = flist.raw.workspace()
        flist.raw.unpack(source, workspace.name)
        stats = flist.raw.create(workspace.name, flist.target)

    # we have an existing flist and checking contents
    # we don't need to create the flist, we just ensure the
    # contents is on the backend
    else:
        flist.loads(source)
        stats = flist.validate()
        if stats['response']['failure'] > 0:
            return {
                'status':
                'error',
                'message':
                'unauthorized upload, contents is not fully present on backend'
            }

        flist.commit()

    # removing uploaded source file
    os.unlink(source)

    return {
        'status': 'success',
        'flist': flist.filename,
        'home': username,
        'stats': stats,
        'timing': {}
    }
示例#4
0
def api_my_rename(source, destination):
    username = session['username']
    flist = HubPublicFlist(config, username, source)
    destflist = HubPublicFlist(config, username, destination)

    if not flist.user_exists:
        return api_response("user not found", 404)

    if not flist.file_exists:
        return api_response("source not found", 404)

    os.rename(flist.target, destflist.target)

    return api_response()
示例#5
0
def api_my_merge(target):
    username = session['username']

    sources = request.get_json(silent=True, force=True)
    data = flist_merge_data(sources, target)

    if data['error'] != None:
        return api_response(data['error'], 500)

    flist = HubPublicFlist(config, username, data['target'])
    status = flist.merge(data['sources'])

    if not status == True:
        return api_response(status, 500)

    return api_response()
示例#6
0
def api_flist_upload_prepare(request, username, validate=False):
    # check if the post request has the file part
    if 'file' not in request.files:
        return {'status': 'error', 'message': 'no file found'}

    file = request.files['file']

    # if user does not select file, browser also
    # submit a empty part without filename
    if file.filename == '':
        return {'status': 'error', 'message': 'no file selected'}

    if not allowed_file(file.filename, validate):
        return {'status': 'error', 'message': 'this file is not allowed'}

    #
    # processing the file
    #
    filename = secure_filename(file.filename)

    print("[+] saving file")
    source = os.path.join(config['upload-directory'], filename)
    file.save(source)

    cleanfilename = file_from_flist(filename)
    flist = HubPublicFlist(config, username, cleanfilename, announcer)
    flist.raw.newtask()

    print("[+] flist creation id: %s" % flist.raw.jobid)

    job = threading.Thread(target=flist.create, args=(source, ))
    job.start()

    return {'status': 'success', 'jobid': flist.raw.jobid}
    """
示例#7
0
def api_user_contents(username):
    flist = HubPublicFlist(config, username, "unknown")
    if not flist.user_exists:
        abort(404)

    contents = api_user_contents(username, flist.user_path)

    response = make_response(json.dumps(contents) + "\n")
    response.headers["Content-Type"] = "application/json"

    return response
示例#8
0
def api_fileslist():
    repositories = api_repositories()
    fileslist = {}

    for repository in repositories:
        flist = HubPublicFlist(config, repository['name'], "unknown")
        contents = api_user_contents(flist.username, flist.user_path)

        fileslist[repository['name']] = contents

    return fileslist
示例#9
0
def checksum_flist(username, flist):
    flist = HubPublicFlist(config, username, flist)
    hash = flist.checksum

    if not hash:
        abort(404)

    response = make_response(hash + "\n")
    response.headers["Content-Type"] = "text/plain"

    return response
示例#10
0
def flist_merge():
    username = session['username']

    if request.method == 'POST':
        data = flist_merge_post()
        print(data)

        if data['error']:
            return internalRedirect("merge.html", data['error'])

        flist = HubPublicFlist(config, username, data['target'])
        status = flist.merge(data['sources'])

        if not status == True:
            variables = {'error': status}
            return globalTemplate("merge.html", variables)

        return uploadSuccess(data['target'], 0, data['target'])

    # Merge page
    return internalRedirect("merge.html")
示例#11
0
def api_delete(username, source):
    flist = HubPublicFlist(config, username, source)

    if not flist.user_exists:
        return api_response("user not found", 404)

    if not flist.file_exists:
        return api_response("source not found", 404)

    os.unlink(flist.target)

    return api_response()
示例#12
0
def api_readme(username, flist):
    flist = HubPublicFlist(config, username, flist)

    if not flist.user_exists:
        return api_response("user not found", 404)

    if not flist.file_exists:
        return api_response("source not found", 404)

    readme = api_flist_md(flist)

    response = make_response(json.dumps(readme) + "\n")
    response.headers["Content-Type"] = "application/json"

    return response
示例#13
0
def flist_merge_data(sources, target):
    data = {}
    data['error'] = None
    data['sources'] = sources
    data['target'] = target

    if not isinstance(sources, list):
        data['error'] = 'malformed json request'
        return data

    if len(data['sources']) == 0:
        data['error'] = "no source found"
        return data

    # ensure .flist extension to each sources
    fsources = []
    for source in data['sources']:
        # missing username/filename
        if "/" not in source:
            data['error'] = "malformed source filename"
            return data

        cleaned = source if source.endswith(".flist") else source + ".flist"
        fsources.append(cleaned)

    data['sources'] = fsources

    # ensure each sources exists
    for source in data['sources']:
        temp = source.split("/")
        item = HubPublicFlist(config, temp[0], temp[1])

        if not item.file_exists:
            data['error'] = "%s does not exists" % source
            return data

    if not data['target']:
        data['error'] = "missing build (target) name"
        return data

    if "/" in data['target']:
        data['error'] = "build name not allowed"
        return data

    if not data['target'].endswith('.flist'):
        data['target'] += '.flist'

    return data
示例#14
0
def show_flist_txt(username, flist):
    flist = HubPublicFlist(config, username, flist)
    if not flist.file_exists:
        abort(404)

    text = "File:     %s\n" % flist.filename
    text += "Uploader: %s\n" % username
    text += "Source:   %s/%s/%s\n" % (config['public-website'], username,
                                      flist.filename)
    text += "Storage:  zdb://%s:%d\n" % (config['backend-public-host'],
                                         config['backend-public-port'])
    text += "Checksum: %s\n" % flist.checksum

    response = make_response(text)
    response.headers["Content-Type"] = "text/plain"

    return response
示例#15
0
def api_inspect(username, flist):
    flist = HubPublicFlist(config, username, flist)

    if not flist.user_exists:
        return api_response("user not found", 404)

    if not flist.file_exists:
        return api_response("source not found", 404)

    if request.method == 'GET':
        contents = api_contents(flist)

    if request.method == 'INFO':
        contents = api_flist_info(flist)

    response = make_response(json.dumps(contents) + "\n")
    response.headers["Content-Type"] = "application/json"

    return response
示例#16
0
def show_flist_md(username, flist):
    flist = HubPublicFlist(config, username, flist)
    if not flist.file_exists:
        abort(404)

    variables = {
        'targetuser':
        username,
        'flistname':
        flist.filename,
        'flisturl':
        "%s/%s/%s" % (config['public-website'], username, flist.filename),
        'ardbhost':
        'zdb://%s:%d' %
        (config['backend-public-host'], config['backend-public-port']),
        'checksum':
        flist.checksum
    }

    return globalTemplate("preview.html", variables)
示例#17
0
def show_flist_json(username, flist):
    flist = HubPublicFlist(config, username, flist)
    if not flist.file_exists:
        abort(404)

    data = {
        'flist':
        flist,
        'uploader':
        username,
        'source':
        "%s/%s/%s" % (config['public-website'], username, flist),
        'storage':
        "zdb://%s:%d" %
        (config['backend-public-host'], config['backend-public-port']),
        'checksum':
        flist.checksum
    }

    response = make_response(json.dumps(data) + "\n")
    response.headers["Content-Type"] = "application/json"

    return response
示例#18
0
    def converter(self, dockerimage, username="******"):
        dockername = uuid.uuid4().hex
        print("[+] docker-convert: temporary docker name: %s" % dockername)

        if ":" not in dockerimage:
            dockerimage = "%s:latest" % dockerimage

        #
        # loading image from docker-hub
        #
        print("[+] docker-convert: pulling image: %s" % dockerimage)
        self.progress("Pulling docker image: %s" % dockerimage, 10)

        try:
            # progress pull
            self.pull(dockerimage)

            # fetch real image name
            image = self.dockerclient.images.pull(dockerimage)

        except docker.errors.ImageNotFound:
            return {'status': 'error', 'message': 'docker image not found'}

        except docker.errors.APIError:
            return {'status': 'error', 'message': 'could not pull this image'}

        #
        # building init-command line
        #
        command = None

        if not image.attrs['Config']['Cmd'] and not image.attrs['Config'][
                'Entrypoint']:
            command = "/bin/sh"

        print("[+] docker-convert: starting temporary container")
        self.progress("Initializing temporary container", 52)

        cn = self.dockerclient.containers.create(dockerimage,
                                                 name=dockername,
                                                 hostname=dockername,
                                                 command=command)

        #
        # exporting docker
        #
        print("[+] docker-convert: creating target directory")
        tmpdir = tempfile.TemporaryDirectory(
            prefix=dockername, dir=self.config['docker-work-directory'])
        os.chmod(tmpdir.name, 0o755)

        print("[+] docker-convert: dumping files to: %s" % tmpdir.name)
        self.progress("Extracting container root filesystem", 54)

        subprocess.call([
            'sh', '-c',
            'docker export %s | tar -xpf - -C %s' % (dockername, tmpdir.name)
        ])

        #
        # docker init command to container startup command
        #
        print("[+] docker-convert: creating container entrypoint")
        self.progress("Creating container metadata", 55)

        command, args, env, cwd = self.container_boot(cn)

        boot = {
            'startup': {
                'entry': {
                    'name': "core.system",
                    'args': {
                        'name': command,
                        'args': args,
                        'env': env,
                        'dir': cwd,
                    }
                }
            }
        }

        with open(os.path.join(tmpdir.name, '.startup.toml'), 'w') as f:
            f.write(toml.dumps(boot))

        #
        # bundle the image
        #
        print("[+] docker-convert: parsing the flist")
        self.progress("Preparing filesystem flist", 56)

        flistname = dockerimage.replace(":", "-").replace('/', '-')

        flist = HubPublicFlist(self.config, username, flistname,
                               self.announcer)
        flist.raw.jobid = self.jobid
        flist.user_create()
        info = flist.raw.create(tmpdir.name, flist.target)

        print("[+] docker-convert: cleaning temporary files")
        self.progress("Cleaning up temporary files", 95)
        tmpdir.cleanup()

        print("[+] docker-convert: destroying the container")
        self.progress("Cleaning up container", 97)
        cn.remove(force=True)

        print("[+] docker-convert: cleaning up the docker image")
        self.progress("Cleaning up docker image", 99)
        self.dockerclient.images.remove(dockerimage, force=True)

        if info['success'] == False:
            return {'status': 'error', 'message': info['error']['message']}

        self.progress("Image ready !", 100)

        return {
            'status': 'success',
            'file': flist.filename,
            'flist': info['response'],
            'timing': {}
        }
示例#19
0
def show_user(username):
    flist = HubPublicFlist(config, username, "unknown")
    if not flist.user_exists:
        abort(404)

    return globalTemplate("user.html", {'targetuser': username})
示例#20
0
def download_flist(username, flist):
    flist = HubPublicFlist(config, username, flist)
    return send_from_directory(directory=flist.user_path,
                               filename=flist.filename)