Esempio n. 1
0
    def __init__(self, bs, worker_config, args):
        Worker.__init__(self, bs, worker_config, args)

        self.client = docker.Client(version=os.environ.get('DOCKER_VERSION'),
                                    **kwargs_from_env(assert_hostname=False))
        log.info('Connecting to docker daemon ...')
        try:
            image = args.image
            if ':' in image:
                self.image, self.tag = image.split(':', 1)
            else:
                self.image, self.tag = image, None
            images = self.client.images(self.image)
        except ConnectionError as err:
            raise errors.BinstarError(
                "Docker client could not connect to daemon (is docker installed?)\n"
                "You may need to set your DOCKER_HOST environment variable")
        if not images:
            raise errors.BinstarError(
                "You do not have the docker image '{image}'\n"
                "You may need to run:\n\n\tdocker pull {image}s\n".format(
                    image=args.image))

        if self.args.allow_user_images:
            log.warn("Allowing users to specify docker images")
Esempio n. 2
0
def main(args):
    bs = get_binstar(args, cls=BinstarBuildAPI)

    if args.queue is None:
        username = queue_name = None
    elif args.queue.count('/') == 1:
        username, queue_name = args.queue.split('/', 1)
    elif args.queue.count('/') == 2:
        _, username, queue_name = args.queue.split('/', 2)
    elif args.queue.count('-') == 2:
        _, username, queue_name = args.queue.split('-', 2)
    else:
        raise errors.UserError(
            "Build queue must be of the form build-USERNAME-QUEUENAME or USERNAME/QUEUENAME"
        )

    if args.create:

        if queue_name is None:
            raise errors.BinstarError("Must specify a queue name to create")
        if not is_valid_name(queue_name):
            raise errors.BinstarError(
                'Invalid name for '
                'queue: {}.  Must start'
                ' with a letter and contain'
                ' only numbers, letters, -, and _'.format(queue_name))

        bs.add_build_queue(username, queue_name)
        print("Created queue %s" % queue_name)
        return

    if queue_name:
        queue = bs.build_queue(username, queue_name)

    if args.remove:
        if queue.get('workers'):
            prompt = ('This build queue still has workers attached. '
                      'Are you sure you want to remove it')
            if not bool_input(prompt, False):
                print("Not removing queue")
                return
        bs.remove_build_queue(username, queue_name)
        print("Removed queue %s" % queue_name)
        return

    if args.remove_worker:
        bs.remove_worker(username, queue_name, args.remove_worker)
        print("Removed worker %s from queue %s" %
              (args.remove_worker, queue_name))
        return

    if queue_name:
        print()
        show_queue(queue)
    else:
        show_queues(bs, username)
Esempio n. 3
0
def get_package_name(args, package_attrs, filename, package_type):
    if args.package:
        if 'name' in package_attrs and package_attrs['name'].lower() != args.package.lower():
            msg = 'Package name on the command line " %s" does not match the package name in the file "%s"'
            raise errors.BinstarError(msg % (args.package.lower(), package_attrs['name'].lower()))
        package_name = args.package
    else:
        if 'name' not in package_attrs:
            raise errors.BinstarError("Could not detect package name for package type %s, please use the --package option" % (package_type,))
        package_name = package_attrs['name']

    return package_name
Esempio n. 4
0
def add_package(aserver_api, args, username, package_name, package_attrs, package_type):
    try:
        return aserver_api.package(username, package_name)
    except errors.NotFound:
        if not args.auto_register:
            message = (
                'Anaconda repository package %s/%s does not exist. '
                'Please run "anaconda package --create" to create this package namespace in the cloud.' %
                (username, package_name)
            )
            logger.error(message)
            raise errors.UserError(message)
        else:
            if args.summary:
                summary = args.summary
            else:
                if 'summary' not in package_attrs:
                    message = "Could not detect package summary for package type %s, please use the --summary option" % (package_type,)
                    logger.error(message)
                    raise errors.BinstarError(message)
                summary = package_attrs['summary']

            public = not args.private

            return aserver_api.add_package(
                username,
                package_name,
                summary,
                package_attrs.get('license'),
                public=public,
                attrs=package_attrs,
                license_url=package_attrs.get('license_url'),
                license_family=package_attrs.get('license_family'),
                package_type=package_type,
            )
Esempio n. 5
0
    def register(cls,
                 bs,
                 username,
                 queue,
                 platform,
                 hostname,
                 dist,
                 name=None):
        '''
        Register the worker with anaconda server
        '''
        for worker in cls.registered_workers(bs):
            if name in (worker.name, worker.worker_id):
                raise errors.BinstarError('Cannot have duplicate worker '
                                          '--name or id: {}'.format(name))
        worker_id = bs.register_worker(username,
                                       queue,
                                       platform,
                                       hostname,
                                       dist,
                                       name=name)
        log.info('Registered worker with worker_id:\t{}'.format(worker_id))

        if name is None:
            name = worker_id

        return WorkerConfiguration(name, worker_id, username, queue, platform,
                                   hostname, dist)
Esempio n. 6
0
def add_package(aserver_api, args, username, package_name, package_attrs,
                package_type):
    try:
        aserver_api.package(username, package_name)
    except errors.NotFound:
        if not args.auto_register:
            raise errors.UserError(
                'Anaconda Cloud package %s/%s does not exist. '
                'Please run "anaconda package --create" to create this package namespace in the cloud.'
                % (username, package_name))
        else:

            if args.summary:
                summary = args.summary
            else:
                if 'summary' not in package_attrs:
                    raise errors.BinstarError(
                        "Could not detect package summary for package type %s, please use the --summary option"
                        % (package_type, ))
                summary = package_attrs['summary']

            aserver_api.add_package(username,
                                    package_name,
                                    summary,
                                    package_attrs.get('license'),
                                    public=True,
                                    attrs=package_attrs)
 def register_func(cls, *args, **kwargs):
     name = kwargs.get('name')
     if name in registered:
         raise errors.BinstarError(
             'already registered {}'.format(registered))
     registered[name] = True
     args2 = [name] + list(args)
     return WorkerConfiguration(*args2)
Esempio n. 8
0
def get_version(args, release_attrs, package_type):
    if args.version:
        version = args.version
    else:
        if 'version' not in release_attrs:
            raise errors.BinstarError("Could not detect package version for package type %s, please use the --version option" % (package_type,))
        version = release_attrs['version']
    return version
Esempio n. 9
0
    def load(cls, worker_name, bs):

        'Load a worker config from a worker_id'
        for worker in cls.registered_workers(bs):
            if worker_name == worker.worker_id or worker_name == worker.name:
                if worker.hostname == cls.HOSTNAME:
                    return worker
        raise errors.BinstarError('Worker with id '
                                  '{} not found'.format(worker_name))
Esempio n. 10
0
    def job_loop(self):
        """
        An iterator that will yield job_data objects when
        one is available.

        Also handles journaling of jobs

        """
        bs = self.bs
        worker_idle = False
        while 1:
            try:
                job_data = bs.pop_build_job(self.config.username,
                                            self.config.queue, self.worker_id)

            except errors.NotFound:
                self.write_status(False, "worker not found")
                if self.args.show_traceback:
                    raise
                else:
                    msg = ("This worker can no longer "
                           "pop items off the build queue. "
                           "Did someone remove it manually?")
                    raise errors.BinstarError(msg)

            except requests.ConnectionError as err:
                log.error("Trouble connecting to binstar at '{0}' ".format(
                    bs.domain))
                log.error("Could not retrieve work items")
                job_data = {}
                self.write_status(False, "Trouble connecting to binstar")

            except errors.ServerError as err:
                log.exception(err)
                log.error(
                    "There server '{0}' returned an error response ".format(
                        bs.domain))
                log.error("Could not retrieve work items")
                self.write_status(False, "Server error")
                job_data = {}
            else:
                self.write_status(True)

            if job_data.get('job') is None:
                if not worker_idle:
                    idle_msg = 'Worker is waiting for the next job'
                    log.info(idle_msg)
                worker_idle = True
                time.sleep(self.SLEEP_TIME)
                continue

            worker_idle = False

            yield job_data

            if self.args.one:
                break
Esempio n. 11
0
    def load(cls, worker_name, bs, warn=False):

        'Load a worker config from a worker_id'
        for worker in cls.registered_workers(bs):
            if worker_name in (worker.worker_id, worker.name):
                return worker

        raise errors.BinstarError('Worker with id '
                                  '{} not found'.format(worker_name))
Esempio n. 12
0
def submit_build(binstar, args):

    path = abspath(args.path)

    log.info('Getting build product: %s' % abspath(args.path))

    with open(join(path, '.binstar.yml')) as cfg:
        build_matrix = list(yaml.load_all(cfg))

    builds = list(serialize_builds(build_matrix))

    if args.platform:

        log.info("Only selecting builds on platform %s" % args.platform)
        builds = [b for b in builds if b['platform'] == args.platform]

    if not builds:
        msg = "No build instructions found"
        if args.platform:
            msg += " for platform %s" % args.platform
        raise errors.BinstarError(msg)

    log.info('Submitting %i sub builds' % len(builds))
    for i, build in enumerate(builds):
        log.info(' %i)' % i + ' %(platform)-10s  %(engine)-15s  %(env)-15s' % build)

    if not args.dry_run:
        if args.git_url:
            log.info("Submitting the following repo for package creation: %s" % args.git_url)

        else:
            with mktemp() as tmp:
                log.info("Archiving build directory for upload ...")
                with tarfile.open(tmp, mode='w|bz2') as tf:
                    exclude = ExcludeGit(path, use_git_ignore=not args.dont_git_ignore)
                    tf.add(path, '.', exclude=exclude)

                log.info("Created archive (%i files); Uploading to binstar" % exclude.num_included)
                queue_tags = []
                if args.buildhost:
                    queue_tags.append('hostname:%s' % args.buildhost)

                if args.dist:
                    queue_tags.append('dist:%s' % args.dist)

                with open(tmp, mode='rb') as fd:

                    build = binstar.submit_for_build(args.package.user, args.package.name, fd, builds,
                                                     channels=args.channels,
                                                     queue=args.queue, queue_tags=queue_tags,
                                                     test_only=args.test_only, callback=upload_print_callback(args))

                print_build_results(args, build)

    else:
        log.info('Build not submitted (dry-run)')
Esempio n. 13
0
    def __init__(self, bs, args):
        Worker.__init__(self, bs, args)

        self.client = docker.Client(base_url=os.environ.get('DOCKER_HOST'))
        log.info('Connecting to docker daemon ...')
        try:
            images = self.client.images(args.image)
        except ConnectionError as err:
            raise errors.BinstarError(
                "Docker client could not connect to daemon (is docker installed?)\n"
                "You may need to set your DOCKER_HOST environment variable")
        if not images:
            raise errors.BinstarError(
                "You do not have the docker image '%(image)s'\n"
                "You may need to run:\n\n\tdocker pull %(image)s\n" %
                dict(image=args.image))

        if self.args.allow_user_images:
            log.warn("Allowing users to specify docker images")
Esempio n. 14
0
def main(args):
    aserver_api = get_server_api(args.token, args.site)
    aserver_api.check_server()

    if args.user:
        username = args.user
    else:
        user = aserver_api.user()
        username = user['login']

    uploaded_packages = []
    uploaded_projects = []

    # Flatten file list because of 'windows_glob' function
    files = [f for fglob in args.files for f in fglob]

    if args.all:
        files += get_convert_files(files)

    for filename in files:
        if not exists(filename):
            message = 'file %s does not exist' % (filename)
            logger.error(message)
            raise errors.BinstarError(message)

        package_type = determine_package_type(filename, args)

        if package_type == 'project':
            uploaded_projects.append(upload_project(filename, args, username))
        else:
            if package_type == 'ipynb' and not args.mode == 'force':
                try:
                    nbformat.read(open(filename), nbformat.NO_CONVERT)
                except Exception as error:
                    logger.error("Invalid notebook file '%s': %s", filename,
                                 error)
                    logger.info("Use --force to upload the file anyways")
                    continue

            package_info = upload_package(filename,
                                          package_type=package_type,
                                          aserver_api=aserver_api,
                                          username=username,
                                          args=args)
            if package_info:
                uploaded_packages.append(package_info)

    for package, upload_info in uploaded_packages:
        package_url = upload_info.get(
            'url', 'https://anaconda.org/%s/%s' % (username, package))
        logger.info("{} located at:\n{}\n".format(
            verbose_package_type(package_type), package_url))

    for project_name, url in uploaded_projects:
        logger.info("Project {} uploaded to {}.\n".format(project_name, url))
Esempio n. 15
0
def determine_package_type(filename, args):
    """
    return the file type from the inspected package or from the
    -t/--package-type argument
    """
    if args.package_type:
        package_type = args.package_type
    else:
        log.info('detecting package type ...')
        sys.stdout.flush()
        package_type = detect_package_type(filename)
        if package_type is None:
            raise errors.BinstarError('Could not detect package type of file %r please specify package type with option --package-type' % filename)
        log.info(package_type)

    return package_type
Esempio n. 16
0
def main(args):

    binstar = get_binstar(args)

    print("main upload!")

    if args.dest and '/' in args.dest:
        username = args.dest.split('/', 1)[0]
    else:
        user = binstar.user()
        username = user['login']

    if args.dest:
        package_name = args.dest.rsplit('/', 1)[-1]
    else:
        package_name = os.path.basename(args.datafile).split('.')[0]

    if not exists(args.datafile):
        raise errors.BinstarError('file %s does not exist' % args.datafile)
    package_type = 'data'

    ensure_package(binstar, username, package_name, args.summary)
    ensure_version(binstar, username, package_name, args.version)
    ensure_unique(binstar,
                  username,
                  package_name,
                  args.version,
                  os.path.basename(args.datafile),
                  force=False)

    with open(args.datafile) as fd:
        upload_info = binstar.upload(username,
                                     package_name,
                                     args.version,
                                     os.path.basename(args.datafile),
                                     fd,
                                     package_type,
                                     args.description,
                                     attrs={'data_type': 'download'},
                                     channels=['main'],
                                     callback=upload_print_callback(args))

    log.info("\n\nUpload(s) Complete\n")

    package_url = upload_info.get(
        'url', 'https://anaconda.org/%s/%s' % (username, package_name))
    log.info("Package located at:\n%s\n" % package_url)
Esempio n. 17
0
def _real_upload_project(project, args, username):
    from anaconda_project import project_ops

    print("Uploading project: {}".format(project.name))

    status = project_ops.upload(project, site=args.site, username=username,
                                token=args.token, log_level=args.log_level)

    for log in status.logs:
        print(log)
    if not status:
        for error in status.errors:
            print(error, file=sys.stderr)
        print(status.status_description, file=sys.stderr)
        raise errors.BinstarError(status.status_description)
    else:
        print(status.status_description)
        return [project.name, status.url]
Esempio n. 18
0
def upload_project(project_path, args, username):
    try:
        from anaconda_project import project_ops
    except ImportError:
        raise errors.BinstarError("To upload projects such as {}, install the anaconda-project package.".format(project_path))

    from anaconda_project import project

    if os.path.exists(project_path) and not os.path.isdir(project_path):
        # make the single file into a temporary project directory
        with (_TmpDir(prefix="anaconda_upload_")) as dirname:
            shutil.copy(project_path, dirname)
            basename_no_extension = os.path.splitext(os.path.basename(project_path))[0]
            project = project_ops.create(dirname, name=basename_no_extension)
            return _real_upload_project(project, args, username)
    else:
        project = project.Project(directory_path=project_path)
        return _real_upload_project(project, args, username)
Esempio n. 19
0
    def deregister(self, bs, as_json=False):
        'Deregister the worker from anaconda server'

        try:

            removed_worker = bs.remove_worker(self.username, self.queue, self.worker_id)

            if not removed_worker:
                raise errors.BinstarError('Failed to remove_worker with argument of ' + \
                                          'worker_id\t{}\tqueue\t{}'.format(self.worker_id, self.queue))

            log.info('Deregistered worker with worker-id {}'.format(self.worker_id))
        except Exception:

            log.info('Failed on anaconda build deregister.\n')
            self.print_registered_workers(bs)
            log.info('deregister failed with error:\n')
            raise
Esempio n. 20
0
    def running(self):
        'Flag this worker id as running'

        if self.is_running():
            msg = "This worker appears to already be running with pid {}".format(self.pid)
            raise errors.BinstarError(msg)

        dst = '{}.{}'.format(self.filename, os.getpid())
        try:
            with open(dst, 'w') as out:
                out.write('')
        except (OSError, AttributeError):
            log.warning("Could not link the pid to a pidfile")
        try:
            yield
        finally:
            if os.path.isfile(dst):
                os.unlink(dst)
Esempio n. 21
0
 def validate_worker_name(cls, bs, name):
     workers_by_name = {}
     for worker in cls.registered_workers(bs):
         if not worker.name in workers_by_name:
             workers_by_name[worker.name] = [worker]
         else:
             workers_by_name[worker.name].append(worker)
     workers = workers_by_name.get(name, [])
     if len(workers) > 1:
         msg = ''
         for worker in workers:
             worker.name = name
             msg += '{name}, id:{worker_id}, hostname:{hostname}, queue:{username}/{queue}\n'.format(
                 **worker.to_dict())
         raise errors.BinstarError('Cannot anaconda worker run {}'
                                   ' (the name is ambiguous).  Use'
                                   ' one of the worker id\'s below'
                                   ' instead.\n\n' + msg)
Esempio n. 22
0
 def upload(self, force=False):
     """
     Uploads a notebook
     :param force: True/False
     :returns {}
     """
     self.package and self.release
     try:
         return self.aserver_api.upload(self.username, self.project,
                                        self.version, self.name,
                                        self.content_io(), "ipynb")
     except errors.Conflict:
         if force:
             self.remove()
             return self.upload()
         else:
             msg = "Conflict: {}/{} already exist".format(
                 self.project, self.version)
             raise errors.BinstarError(msg)
Esempio n. 23
0
 def upload(self, force=False):
     """
     Uploads a notebook
     :param force: True/False
     :returns {}
     """
     self.package and self.release
     try:
         return self.binstar.upload(self.username, self.project,
                                    self.version, basename(self.filepath),
                                    open(self.filepath, 'rb'),
                                    self.filepath.split('.')[-1])
     except errors.Conflict:
         if force:
             self.remove()
             return self.upload()
         else:
             msg = "Conflict: {} already exist in {}/{}".format(
                 self.filepath, self.project, self.version)
             raise errors.BinstarError(msg)
Esempio n. 24
0
def determine_package_type(filename, args):
    """
    return the file type from the inspected package or from the
    -t/--package-type argument
    """
    if args.package_type:
        package_type = args.package_type
    else:
        logger.info('Detecting file type...')

        package_type = detect_package_type(filename)

        if package_type is None:
            message = 'Could not detect package type of file %r please specify package type with option --package-type' % filename
            logger.error(message)
            raise errors.BinstarError(message)

        logger.info('File type is "%s"', package_type)

    return package_type
Esempio n. 25
0
def interactive_get_token(args, fail_if_already_exists=True):
    bs = get_server_api(args.token, args.site, args.log_level)
    config = get_config(remote_site=args.site)

    url = config.get('url', 'https://api.anaconda.org')
    parsed_url = urlparse(url)
    token = None
    hostname = getattr(args, 'hostname', platform.node())
    if getattr(args, 'login_username', None):
        username = args.login_username
    else:
        username = input('Username: '******'binstar_client:'
    site = args.site or config.get('default_site')
    if site and site != 'binstar':
        # For testing with binstar alpha site
        auth_name += '%s:' % site

    auth_name += '%s@%s' % (getpass.getuser(), hostname)

    password = getattr(args, 'login_password', None)

    for _ in range(3):
        try:
            sys.stderr.write("%s's " % username)

            if password is None:
                password = getpass.getpass(stream=sys.stderr)

            token = bs.authenticate(
                username,
                password,
                auth_name,
                url,
                created_with=' '.join(sys.argv),
                fail_if_already_exists=fail_if_already_exists,
                hostname=hostname)
            break

        except errors.Unauthorized:
            log.error(
                'Invalid Username password combination, please try again')
            password = None
            continue

        except errors.BinstarError as err:
            if fail_if_already_exists is True and err.args[1] == 400:
                log.warn('It appears you are already logged in from host %s' %
                         socket.gethostname())
                log.warn(
                    'Logging in again will remove the previous token. '
                    ' (This could cause troubles with virtual machines with the same hostname)'
                )
                log.warn('Otherwise you can login again and specify a '
                         'different hostname with "--hostname"')
                if bool_input("Would you like to continue"):
                    fail_if_already_exists = False
                    continue
                else:
                    raise

    if token is None:
        if parsed_url.netloc.startswith('api.anaconda.org'):
            netloc = 'anaconda.org'
        else:
            netloc = parsed_url.netloc
        hostparts = (parsed_url.scheme, netloc)
        msg = ('Sorry. Please try again ' + \
               '(go to %s://%s/account/forgot_password ' % hostparts + \
               'to reset your password)')
        raise errors.BinstarError(msg)

    return token
Esempio n. 26
0
def interactive_get_token(args, fail_if_already_exists=True):
    bs = get_server_api(args.token, args.site, args.log_level)
    config = get_config(remote_site=args.site)

    token = None
    # This function could be called from a totally different CLI, so we don't
    # know if the attribute hostname exists.
    hostname = getattr(args, 'hostname', platform.node())
    site = args.site or config.get('default_site')
    url = config.get('url', 'https://api.anaconda.org')

    auth_name = 'binstar_client:'
    if site and site != 'binstar':
        # For testing with binstar alpha site
        auth_name += '%s:' % site

    auth_name += '%s@%s' % (getpass.getuser(), hostname)

    bs.check_server()
    auth_type = bs.authentication_type()

    if auth_type == 'kerberos':
        token = try_replace_token(
            bs.krb_authenticate,
            application=auth_name,
            application_url=url,
            created_with=' '.join(sys.argv),
            fail_if_already_exists=fail_if_already_exists,
            hostname=hostname,
        )

        if token is None:
            raise errors.BinstarError(
                'Unable to authenticate via Kerberos. Try refreshing your '
                'authentication using `kinit`')

    else:

        if getattr(args, 'login_username', None):
            username = args.login_username
        else:
            username = input('Username: '******'login_password', None)

        for _ in range(3):
            try:
                sys.stderr.write("%s's " % username)

                if password is None:
                    password = getpass.getpass(stream=sys.stderr)

                token = try_replace_token(
                    bs.authenticate,
                    username=username,
                    password=password,
                    application=auth_name,
                    application_url=url,
                    created_with=' '.join(sys.argv),
                    fail_if_already_exists=fail_if_already_exists,
                    hostname=hostname,
                )
                break

            except errors.Unauthorized:
                log.error(
                    'Invalid Username password combination, please try again')
                password = None
                continue

        if token is None:
            parsed_url = urlparse(url)
            if parsed_url.netloc.startswith('api.anaconda.org'):
                netloc = 'anaconda.org'
            else:
                netloc = parsed_url.netloc
            hostparts = (parsed_url.scheme, netloc)
            msg = ('Sorry. Please try again ' + \
                   '(go to %s://%s/account/forgot_password ' % hostparts + \
                   'to reset your password)')
            raise errors.BinstarError(msg)

    return token
Esempio n. 27
0
def main(args):
    config = get_config(site=args.site)

    aserver_api = get_server_api(token=args.token,
                                 site=args.site,
                                 config=config)
    aserver_api.check_server()

    validate_username = True

    if args.user:
        username = args.user
    elif 'upload_user' in config:
        username = config['upload_user']
    else:
        validate_username = False
        user = aserver_api.user()
        username = user['login']

    logger.info('Using "%s" as upload username', username)

    if validate_username:
        try:
            aserver_api.user(username)
        except errors.NotFound:
            message = 'User "{}" does not exist'.format(username)
            logger.error(message)
            raise errors.BinstarError(message)

    uploaded_packages = []
    uploaded_projects = []

    # Flatten file list because of 'windows_glob' function
    files = [f for fglob in args.files for f in fglob]

    if args.all:
        files += get_convert_files(files)

    for filename in files:
        if not exists(filename):
            message = 'File "{}" does not exist'.format(filename)
            logger.error(message)
            raise errors.BinstarError(message)
        else:
            logger.info("Processing '%s'", filename)

        package_type = determine_package_type(filename, args)

        if package_type == 'project':
            uploaded_projects.append(upload_project(filename, args, username))
        else:
            if package_type == 'ipynb' and not args.mode == 'force':
                try:
                    nbformat.read(open(filename), nbformat.NO_CONVERT)
                except Exception as error:
                    logger.error("Invalid notebook file '%s': %s", filename,
                                 error)
                    logger.info("Use --force to upload the file anyways")
                    continue

            package_info = upload_package(filename,
                                          package_type=package_type,
                                          aserver_api=aserver_api,
                                          username=username,
                                          args=args)

            if package_info is not None and len(package_info) == 2:
                _package, _upload_info = package_info
                if _upload_info:
                    uploaded_packages.append(package_info)

    for package, upload_info in uploaded_packages:
        package_url = upload_info.get(
            'url', 'https://anaconda.org/%s/%s' % (username, package))
        logger.info("{} located at:\n{}\n".format(
            verbose_package_type(package_type), package_url))

    for project_name, url in uploaded_projects:
        logger.info("Project {} uploaded to {}.\n".format(project_name, url))
Esempio n. 28
0
def main(args):

    aserver_api = get_binstar(args)

    if args.user:
        username = args.user
    else:
        user = aserver_api.user()
        username = user['login']

    uploaded_packages = []

    # Flatten file list because of 'windows_glob' function
    files = [f for fglob in args.files for f in fglob]

    for filename in files:

        if not exists(filename):
            raise errors.BinstarError('file %s does not exist' % (filename))

        package_type = determine_package_type(filename, args)

        log.info('extracting package attributes for upload ...')
        sys.stdout.flush()
        try:
            package_attrs, release_attrs, file_attrs = get_attrs(package_type,
                                                                 filename, parser_args=args)
        except Exception:
            if args.show_traceback:
                raise
            raise errors.BinstarError('Trouble reading metadata from %r. Is this a valid %s package' % (filename, package_type))

        if args.build_id:
            file_attrs['attrs']['binstar_build'] = args.build_id

        log.info('done')

        package_name = get_package_name(args, package_attrs, filename, package_type)
        version = get_version(args, release_attrs, package_type)

        add_package(aserver_api, args, username, package_name, package_attrs, package_type)

        add_release(aserver_api, args, username, package_name, version, release_attrs)

        binstar_package_type = file_attrs.pop('binstar_package_type', package_type)

        with open(filename, 'rb') as fd:
            log.info('\nUploading file %s/%s/%s/%s ... ' % (username, package_name, version, file_attrs['basename']))
            sys.stdout.flush()

            if remove_existing_file(aserver_api, args, username, package_name, version, file_attrs):
                continue
            try:
                upload_info = aserver_api.upload(username, package_name, version, file_attrs['basename'],
                                             fd, binstar_package_type,
                                             args.description,
                                             dependencies=file_attrs.get('dependencies'),
                                             attrs=file_attrs['attrs'],
                                             channels=args.channels,
                                             callback=upload_print_callback(args))
            except errors.Conflict:
                full_name = '%s/%s/%s/%s' % (username, package_name, version, file_attrs['basename'])
                log.info('Distribution already exists. Please use the -i/--interactive or --force options or `anaconda remove %s`' % full_name)
                raise

            uploaded_packages.append([package_name, upload_info])
            log.info("\n\nUpload(s) Complete\n")


    for package, upload_info in uploaded_packages:
        package_url = upload_info.get('url', 'https://anaconda.org/%s/%s' % (username, package))
        log.info("Package located at:\n%s\n" % package_url)
Esempio n. 29
0
def check_output(args, cwd='.', raise_=True):
    try:
        return _check_output(args, cwd=cwd, env=os.environ).decode()
    except Exception as e:
        if raise_:
            raise errors.BinstarError('Failed on {}'.format(args))
Esempio n. 30
0
def upload_package(filename, package_type, aserver_api, username, args):
    logger.info('Extracting {} attributes for upload'.format(
        verbose_package_type(package_type)))

    try:
        package_attrs, release_attrs, file_attrs = get_attrs(package_type,
                                                             filename,
                                                             parser_args=args)
    except Exception:
        message = 'Trouble reading metadata from {}. Is this a valid {} package?'.format(
            filename, verbose_package_type(package_type))
        logger.error(message)

        if args.show_traceback:
            raise

        raise errors.BinstarError(message)

    if args.build_id:
        file_attrs['attrs']['binstar_build'] = args.build_id

    package_name = get_package_name(args, package_attrs, filename,
                                    package_type)
    version = get_version(args, release_attrs, package_type)

    logger.info('Creating package "%s"', package_name)

    package = add_package(aserver_api, args, username, package_name,
                          package_attrs, package_type)
    package_types = package.get('package_types', [])

    if package_types and package_type not in package_types:
        message = 'You already have a {} named \'{}\'. Use a different name for this {}.'.format(
            verbose_package_type(package_types[0] if package_types else ''),
            package_name,
            verbose_package_type(package_type),
        )
        logger.error(message)
        raise errors.BinstarError(message)

    logger.info('Creating release "%s"', version)

    add_release(aserver_api, args, username, package_name, version,
                release_attrs)
    binstar_package_type = file_attrs.pop('binstar_package_type', package_type)

    with open(filename, 'rb') as fd:
        logger.info('Uploading file "%s/%s/%s/%s"', username, package_name,
                    version, file_attrs['basename'])

        if remove_existing_file(aserver_api, args, username, package_name,
                                version, file_attrs):
            return None

        try:
            upload_info = aserver_api.upload(
                username,
                package_name,
                version,
                file_attrs['basename'],
                fd,
                binstar_package_type,
                args.description,
                dependencies=file_attrs.get('dependencies'),
                attrs=file_attrs['attrs'],
                channels=args.labels,
                callback=upload_print_callback(args))
        except errors.Conflict:
            logger.info(
                'Distribution already exists. Please use the -i/--interactive or --force options or `anaconda '
                'remove %s/%s/%s/%s', username, package_name, version,
                file_attrs['basename'])
            raise

        logger.info("Upload complete")

        return [package_name, upload_info]