Beispiel #1
0
def updates_tail(_context, request):
    logger.info("Tailing log file ...")
    sequence = request.matchdict.get('sequence')
    rollback = request.matchdict.get('rollback', '')
    logger.debug('admins.py ::: updates_tail - sequence = %s' % sequence)
    logger.debug('admins.py ::: updates_tail - rollback = %s' % rollback)

    if rollback == 'rollback' and request.db.updates.find_one({
            '_id': sequence
    }).get('rollback', 0) == 0:
        # Update mongo document
        request.db.updates.update_one({'_id': sequence}, {
            '$set': {
                'rollback': 1,
                'timestamp_rollback': int(time.time()),
                'rolluser': request.user['username']
            }
        })

        # Celery task
        script_runner.delay(request.user, sequence, rollback=True)

    return {
        'websockets_enabled': json.dumps(is_websockets_enabled()),
        'request': request,
        'sequence': sequence,
        'rollback': rollback
    }
Beispiel #2
0
    def save(self, update):
        settings = get_current_registry().settings
        update = update['local_file'] if update['local_file'] is not None else update['remote_file']
        sequence = re.match('^update-(\w+)\.zip$', update['filename']).group(1)
        logger.debug("forms.py ::: UpdateForm - sequence = %s" % sequence)
        # Updates directory: /opt/gecoscc/updates/<sequence>
        updatesdir = settings['updates.dir'] + sequence
        logger.debug("forms.py ::: UpdateForm - updatesdir = %s" % updatesdir)
        # Update zip file
        zipped = settings['updates.tmp'] + update['filename']
        logger.debug("forms.py ::: UpdateForm - zipped = %s" % zipped)
        try:
            # https://docs.python.org/2/library/shutil.html
            # The destination directory, named by dst, must not already exist; it will be created as well as missing parent directories
            # Checking copytree NFS
            shutil.copytree(update['decompress'], updatesdir)
            shutil.rmtree(update['decompress'])
            # Move zip file to updates dir
            shutil.move(zipped, updatesdir)

            # Decompress cookbook zipfile
            cookbookdir = settings['updates.cookbook'].format(sequence)
            logger.debug("forms.py ::: UpdateForm - cookbookdir = %s" % cookbookdir)
            for cookbook in os.listdir(cookbookdir):
                cookbook = cookbookdir + os.sep + cookbook
                logger.debug("forms.py ::: UpdateForm - cookbook = %s" % cookbook)
                if zipfile.is_zipfile(cookbook):
                    zip_ref = zipfile.ZipFile(cookbook,'r')
                    zip_ref.extractall(cookbookdir + os.sep + settings['chef.cookbook_name'])
                    zip_ref.close()
            # Insert update register
            self.request.db.updates.insert({'_id': sequence, 'name': update['filename'], 'path': updatesdir, 'timestamp': int(time.time()), 'rollback':0, 'user': self.request.user['username']})
            # Launching task for script execution
            script_runner.delay(self.request.user, sequence)
            link = '<a href="' +  self.request.route_url('updates_tail',sequence=sequence) + '">' + _("here") + '</a>'
            self.created_msg(_("Update log. %s") % link)
        except OSError as e:
                error = True
                if e.errno == errno.EACCES:
                    self.created_msg(_('Permission denied: %s') % updatesdir, 'danger')
                else:
                    self.created_msg(_('There was an error attempting to upload an update. Please contact an administrator'), 'danger')
        except (IOError, os.error) as e:
            pass
        except errors.DuplicateKeyError as e:
            logger.error('Duplicate key error')
            self.created_msg(_('There was an error attempting to upload an update. Please contact an administrator'), 'danger')
Beispiel #3
0
def updates_tail(_context, request):
    logger.info("Tailing log file ...")
    sequence = request.matchdict.get('sequence') 
    rollback = request.matchdict.get('rollback', '')
    logger.debug('admins.py ::: updates_tail - sequence = %s' % sequence)
    logger.debug('admins.py ::: updates_tail - rollback = %s' % rollback)

    if rollback == 'rollback' and request.db.updates.find_one({'_id': sequence}).get('rollback', 0) == 0:
        # Update mongo document
        request.db.updates.update({'_id':sequence},{'$set':{'rollback':1, 'timestamp_rollback': int(time.time()), 'rolluser': request.user['username']}})

        # Celery task
        script_runner.delay(request.user, sequence, rollback=True)

    return { 
        'websockets_enabled': json.dumps(is_websockets_enabled()),
        'request': request,
        'sequence': sequence,
        'rollback': rollback
    }
Beispiel #4
0
def updates_repeat(_context, request):
    settings = get_current_registry().settings
    sequence = request.matchdict.get('sequence')
    logger.debug('admins.py ::: updates_repeat - sequence = %s' % sequence)

    # Check sequence number
    to_repeat = request.db.updates.find_one({'_id': sequence})
    if to_repeat is None:
        logging.error('admins.py ::: updates_repeat: ' + \
                      'update not found with sequence=%s'%(sequence))
        raise HTTPNotFound()

    updatefile = os.path.join(to_repeat['path'], to_repeat['name'])
    if not os.path.isfile(updatefile):
        raise HTTPNotFound()

    if re.match(SERIALIZED_UPDATE_PATTERN, to_repeat['name']) is not None:
        logging.error('admins.py ::: updates_repeat: ' + \
                      'update %s is a serialized update!'%(sequence))
        raise HTTPBadRequest()

    if 'repetition' in to_repeat:
        logging.error('admins.py ::: updates_repeat: ' + \
                      'update %s is repetition!'%(sequence))
        raise HTTPBadRequest()

    try:
        # Calculate the next repetition number for this update
        count = request.db.updates.count_documents({
            'name': to_repeat['name'],
            'repetition': {
                '$exists': True
            }
        })

        nrep = 0
        if count > 0:
            cursor = request.db.updates.find(
                {
                    'name': to_repeat['name'],
                    'repetition': {
                        '$exists': True
                    }
                }, {
                    '_id': 1,
                    'repetition': 1
                }).sort('repetition', -1).limit(1)

            latest = int(cursor.next().get('repetition'))
            nrep = (latest + 1)

        logger.debug('admins.py ::: updates_repeat - repetition = %s' % nrep)

        # Copy the zip file
        separator = '_'
        rsequence = '%s%s%s' % (sequence, separator, nrep)
        updatesdir = settings['updates.dir'] + rsequence
        while os.path.exists(updatesdir):
            separator = separator + '_'
            rsequence = '%s%s%s' % (sequence, separator, nrep)
            updatesdir = settings['updates.dir'] + rsequence

        os.mkdir(updatesdir)
        shutil.copy(updatefile, os.path.join(updatesdir, to_repeat['name']))

        # Decompress zip file
        zip_ref = zipfile.ZipFile(updatefile, 'r')
        zip_ref.extractall(updatesdir)
        zip_ref.close()

        # Decompress cookbook zipfile
        cookbookdir = settings['updates.cookbook'].format(rsequence)
        logger.debug('admins.py ::: updates_repeat - ' + \
                     ' cookbookdir = %s' % cookbookdir)
        for cookbook in os.listdir(cookbookdir):
            cookbook = cookbookdir + os.sep + cookbook
            logger.debug("admins.py ::: updates_repeat - cookbook = %s" %
                         cookbook)
            if zipfile.is_zipfile(cookbook):
                zip_ref = zipfile.ZipFile(cookbook, 'r')
                zip_ref.extractall(
                    os.path.join(cookbookdir, settings['chef.cookbook_name']))
                zip_ref.close()

        # Insert update register
        request.db.updates.insert_one({
            '_id': rsequence,
            'name': to_repeat['name'],
            'path': updatesdir,
            'timestamp': int(time.time()),
            'rollback': 0,
            'user': request.user['username'],
            'repetition': nrep
        })

        # Launching task for script execution
        script_runner.delay(request.user, rsequence)

        messages.created_msg(request, _('The update has been repeated!'),
                             'success')

    except:
        e = sys.exc_info()[0]
        logger.error("admins.py ::: updates_repeat - " + \
            "error repeating update: %s"%(str(e)))
        logger.error("Traceback: %s" % (traceback.format_exc()))
        messages.created_msg(
            request, _('There was an error trying to repeat an update'),
            'danger')

    return HTTPFound(request.route_url('updates'))
Beispiel #5
0
    def save(self, update):
        settings = get_current_registry().settings
        update = update['local_file'] if update[
            'local_file'] is not None else update['remote_file']
        sequence = re.match(BASE_UPDATE_PATTERN, update['filename']).group(1)
        logger.debug("forms.py ::: UpdateForm - sequence = %s" % sequence)
        # Updates directory: /opt/gecoscc/updates/<sequence>
        updatesdir = settings['updates.dir'] + sequence
        logger.debug("forms.py ::: UpdateForm - updatesdir = %s" % updatesdir)
        # Update zip file
        zipped = settings['updates.tmp'] + update['filename']
        logger.debug("forms.py ::: UpdateForm - zipped = %s" % zipped)
        try:
            # https://docs.python.org/2/library/shutil.html
            # The destination directory, named by dst, must not already exist; it will be created as well as missing parent directories
            # Checking copytree NFS
            shutil.copytree(update['decompress'], updatesdir)
            shutil.rmtree(update['decompress'])
            # Move zip file to updates dir
            shutil.move(zipped, updatesdir)

            # Decompress cookbook zipfile
            cookbookdir = settings['updates.cookbook'].format(sequence)
            logger.debug("forms.py ::: UpdateForm - cookbookdir = %s" %
                         cookbookdir)
            for cookbook in os.listdir(cookbookdir):
                cookbook = cookbookdir + os.sep + cookbook
                logger.debug("forms.py ::: UpdateForm - cookbook = %s" %
                             cookbook)
                if zipfile.is_zipfile(cookbook):
                    zip_ref = zipfile.ZipFile(cookbook, 'r')
                    zip_ref.extractall(cookbookdir + os.sep +
                                       settings['chef.cookbook_name'])
                    zip_ref.close()
            # Insert update register
            self.request.db.updates.insert_one({
                '_id':
                sequence,
                'name':
                update['filename'],
                'path':
                updatesdir,
                'timestamp':
                int(time.time()),
                'rollback':
                0,
                'user':
                self.request.user['username']
            })
            # Launching task for script execution
            script_runner.delay(self.request.user, sequence)
            link = '<a href="' + self.request.route_url(
                'updates_tail', sequence=sequence) + '">' + _("here") + '</a>'
            self.created_msg(_("Update log. %s") % link)
        except OSError as e:
            if e.errno == errno.EACCES:
                self.created_msg(
                    _('Permission denied: %s') % updatesdir, 'danger')
            else:
                self.created_msg(
                    _('There was an error attempting to upload an update. Please contact an administrator'
                      ), 'danger')

            logger.error("forms.py ::: UpdateForm - - " + \
                "error saving update: %s"%(str(e)))
            logger.error("Traceback: %s" % (traceback.format_exc()))

        except (IOError, os.error) as e:
            logger.error("forms.py ::: UpdateForm - - " + \
                "error saving update: %s"%(str(e)))
            logger.error("Traceback: %s" % (traceback.format_exc()))

        except errors.DuplicateKeyError as e:
            logger.error('Duplicate key error')
            self.created_msg(
                _('There was an error attempting to upload an update. Please contact an administrator'
                  ), 'danger')