Esempio n. 1
0
    def sync_fs(self, verbose):
        #TODO: add progress bar into rsync somehow
        log.info("Starting Sync Process")

        exclude_list = ""
        if self.system_excludes != None and len(self.system_excludes) > 0:
            for exclude_item in self.system_excludes:
                exclude_list += '--exclude "%s" ' % (exclude_item)
        if self.user_excludes != None and len(self.user_excludes) > 0:
            for exclude_item in self.user_excludes:
                exclude_list += '--exclude "%s" ' % (exclude_item)
        # Let's not forget to add the --delete-exclude flag to rsync else
        # previously synced files which now match an exclude rule will not get
        # deleted and will stay in the synced image.
        if len(exclude_list) > 0:
            exclude_list += " --delete-excluded"

        flags = ''
        if verbose:
            flags += '--stats --progress ' 
        cmd = "rsync -a --sparse %s --delete %s / %s" % (flags, exclude_list, self.mountpoint)
        log.debug("%s" % cmd)
        p = subprocess.Popen(cmd, shell=True, env=config.get_restricted_env()).wait()
        if p:
            log.error("Rsync encountered an issue. return code: '%s'" % p)
            raise ImageUtilError("Rsync failed.  Aborting.")
        log.info("Sync Complete")
Esempio n. 2
0
    def __call__(self, args):
        # If you need to make a call to the repoman server, you can use the
        # self.get_repoman_client(args) method.

        log.info('foo subcommand called.')

        # TODO: Put your implementation code here...
        return
Esempio n. 3
0
 def delegator(self, args):
     log.info('repoman subcommand called: %s' % (self.command))
     log.debug('args: %s' % (args))
     # Validate CLI arguments first
     log.debug('Validating arguments...')
     self.validate_args(args)
     # Now we can delegate to the child class
     self.__call__(args)
Esempio n. 4
0
 def validate_args(self, args):
     if args.new_name and not re.match('^[a-zA-Z0-9_-]+$', args.new_name):
         raise InvalidArgumentError('Invalid group name syntax.  Please see "repoman help %s" for acceptable username syntax.' % (self.command))
     if args.permissions:
         for permission in args.permissions.split(','):
             if permission not in valid_permissions:
                 log.info('Invalid permission detected: %s' % (permission))
                 raise InvalidArgumentError('Invalid permission: %s\nPlease chose one or more permission from the following list:\n[%s]' % (permission, ', '.join(valid_permissions)))
Esempio n. 5
0
    def __call__(self, args):
        # Check if sudo...
        if os.getuid() != 0:
            raise SubcommandFailure(self, "Error.  This command requires root privileges, try again with sudo.")

        kwargs={}

        name = args.image
        # Check for proper Gzip extension (if needed)
        if args.gzip:
            if name and name.endswith('.gz'):
                pass
            else:
                log.info("Enforcing '.gz' extension.")
                name += '.gz'
                print ("WARNING: gzip option found, but your image name does not"
                       " end in '.gz'.  Modifying image name to enforce this.")
                print "New image name: '%s'" % (name)

        kwargs['name'] = name

        # Check to see if the image name has the '.gz' suffix and
        # compression not enabled.  Having uncompressed images named with
        # a '.gz' suffix will break things in Nimbus.
        if (not args.gzip) and name.endswith('.gz'):
            print ("WARNING: The image name you gave ends with '.gz' but you did not enable image compression with the --gzip command line argument.  Having uncompressed images with a '.gz' suffix to the image name can cause problems in some cloud frameworks.")
            if not yes_or_no('Do you want to continue? [yes]/[n]o: '):
                print "Aborting.  Please select a new image name or enable compression via the --gzip command line argument."
                return

        exists = False
        try:
            image = self.get_repoman_client(args).describe_image(name, args.owner)
            if image:
                log.info("Found existing image")
                exists = True
        except RepomanError,e:
            if e.status == 404:
                log.debug("Did not find an existing image in repository with same name.")
                pass
            else:
                log.error("Unexpected response occurred when testing if image exists.")
                log.error("%s" % e)
                raise SubcommandFailure(self, "Unexpected response from server occurred when testing if image exists.", e)
Esempio n. 6
0
    def download_image(self, image, dest=None):
        if not dest:
            dest = './%s' % image

        # Check to see if requested image existing in the repo.
        # This will raise an exception if it does not.
        log.info("Checking to see if image slot exists on repository before download")
        resp = self._get('/api/images/%s' % image)

        # Check to make sure destination is not an existing directory.
        if os.path.isdir(dest):
            raise RepomanError('Cannot create %s.  Specified destination already exist and is a directory.' % (dest))

        # If the destination already exists, make sure we can overwrite it.
        if os.path.isfile(dest):
            try:
                fp = open(dest, 'w')
            except IOError, e:
                if e.errno == errno.EACCES:
                    raise RepomanError('Cannot overwrite %s.  Specified destination already exist and you don\'t have permissions to write to it.' % (dest))
Esempio n. 7
0
    def uploaded_image_exist(self, image, owner, hypervisor='xen'):
        """
        This method will test if an image has an uploaded file for a given hypervisor.
        """
        log.info("Checking to see if image %s, owner %s, has an uploaded file for hypervisor %s" % (image, owner, hypervisor))
        if owner:
            resp = self._get('/api/images/%s/%s' % (owner, image))
        else:
            resp = self._get('/api/images/%s' % (image))
        if resp.status != 200:
            log.info("Image slot does not yet exist.")
            raise RepomanError('Image does not yet exist.', resp)

        if owner:
            url = 'https://' + config.host + '/api/images/raw/%s/%s/%s' % (owner, hypervisor, image)
        else:
            url = 'https://' + config.host + '/api/images/raw/%s/%s' % (hypervisor, image)
        try:
            cmd = ['curl',
                    '--cert', config.proxy,
                    '--insecure',
                    '--head',
                    url]
            log.debug(" ".join(cmd))
            p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=config.get_restricted_env())
            if not p:
                log.error("Error calling: %s" % (cmd))
                raise RepomanError("Error checking if image %s, owner %s, has an uploaded file for hypervisor %s" % (image, owner, hypervisor))
            log.info("Command complete")
            stdout = p.communicate()[0]
            log.debug(stdout)
            m = re.search('^HTTP/.+200 OK', stdout, flags=re.M)
            if m:
                log.info("Uploaded file exist for image %s, owner %s, hypervisor %s." % (image, owner, hypervisor))
                return True
            else:
                log.info("Uploaded file does not exist for image %s, owner %s, hypervisor %s." % (image, owner, hypervisor))
                return False
        except Exception, e:
            log.error("%s" % e)
            raise RepomanError(str(e))
Esempio n. 8
0
    def snapshot_system(self, start_fresh=False, verbose=False, clean=False):
        if verbose:
            ch = logging.StreamHandler()
            ch.setLevel(logging.INFO)
            formatter = logging.Formatter("%(levelname)s - %(message)s")
            ch.setFormatter(formatter)
            log.addHandler(ch)

        log.debug("Obtaining lock")
        if not self.obtain_lock():
            log.error("Unable to obtain lock")
            raise ImageUtilError("Unable to obtain lock")
        snapshot_success = False
        try:
            self._snapshot_system(start_fresh, verbose, clean)
            snapshot_success = True
        finally:
            log.debug("Releasing lock")
            self.destroy_lock()
            log.info("Unmounting Image")
            self.umount_image()
        if self.partition and snapshot_success:
                self.install_mbr(self.imagepath)
Esempio n. 9
0
    def _snapshot_system(self, start_fresh=False, verbose=False, clean=False):
        exists = self.image_exists()
        if clean:
            log.info("Cleaning existing snapshot first.")
            start_fresh=True
        elif not exists:
            log.info("No existing image found, creating a new one")
            start_fresh=True
        elif exists:
            log.info("Existing image found, attempting to use.")
            image_stats = self.stat(self.imagepath)
            log.debug("Image stats:\n%s" % (image_stats))
            if self.imagesize:
                # requested size does not match current size
                if self.imagesize != image_stats['size']:
                    log.warning("Requested size (%d) does not match current file (%d).  Starting from scratch." % (self.imagesize, image_stats['size']))
                    start_fresh = True
            else:
                # image size does not match partition size
                if image_stats['size'] != self.statvfs()['size']:
                    log.warning("Root partition size does not match image size.  Starting from scratch")
                    start_fresh = True

        if start_fresh:
            # makesure image is unmounted, then destroy and recreate image.
            log.info("Unmounting Image")
            self.umount_image()
            log.info("Destroying old files")
            self.destroy_files(self.imagepath, self.mountpoint)
            log.info("Creating new image")
            self.create_image(self.imagepath, self.imagesize)

 

        try:
            log.info("Syncing file system")
            self.mount_image()
            self.sync_fs(verbose)
            self.umount_image()
        except ImageUtilError, e:
            # Cleanup after failed sync
            self.umount_image()
            self.destroy_files(self.imagepath, self.mountpoint)
            raise e
Esempio n. 10
0
    def upload_image(self, image, owner, image_file, gzip=False, hypervisor='xen'):
        log.info("Checking to see if image slot exists on repository")
        if owner:
            resp = self._get('/api/images/%s/%s' % (owner, image))
        else:
            resp = self._get('/api/images/%s' % (image))

        if resp.status != 200:
            log.info("Image slot does not yet exist.")
            raise RepomanError('Image does not yet exist.  Create an image before uploading to it', resp)

        # Check if the source is a directory.  If it is, then raise an
        # exception.
        if os.path.isdir(image_file):
            raise RepomanError('Specified source is a directory: %s\nSource must be a file.' % (image_file))
           
        # Check if the source file exists.
        if not os.path.exists(image_file):
            raise RepomanError('Specified source not found: %s' % (image_file))
            
        if owner:
            url = 'https://' + config.host + '/api/images/raw/%s/%s/%s' % (owner, hypervisor, image)
        else:
            url = 'https://' + config.host + '/api/images/raw/%s/%s' % (hypervisor, image)

        try:
            if gzip:
                log.info("Performing gzip on image prior to upload")
                print "Gzipping image before upload"
                gzip_image = os.path.join(os.path.dirname(image_file), image)
                gzip = subprocess.Popen("gzip --stdout %s > %s" % (image_file, gzip_image),
                                        shell=True, env=config.get_restricted_env())
                gzip.wait()
                image_file = gzip_image
                log.info('Gzip complete')

            args = ['curl',
                    '--cert', config.proxy,
                    '--insecure',
                    '-T', image_file, url]
            cmd = " ".join(args)
            log.info("Running command: '%s'" % cmd)
            curl = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, env=config.get_restricted_env())
            for line in curl.stdout.readlines():
                print line
            log.info("Command complete")
            # Cleanup gzip file if needed.
            if gzip:
                try:
                    log.info("Cleaning up %s" % (image_file))
                    os.remove(image_file)
                except Exception, e:
                    pass
 
        except Exception, e:
            log.error("%s" % e)
            raise RepomanError(str(e))
Esempio n. 11
0
        resp = self._get('/api/images/%s' % image)

        # Check to make sure destination is not an existing directory.
        if os.path.isdir(dest):
            raise RepomanError('Cannot create %s.  Specified destination already exist and is a directory.' % (dest))

        # If the destination already exists, make sure we can overwrite it.
        if os.path.isfile(dest):
            try:
                fp = open(dest, 'w')
            except IOError, e:
                if e.errno == errno.EACCES:
                    raise RepomanError('Cannot overwrite %s.  Specified destination already exist and you don\'t have permissions to write to it.' % (dest))
            
        url = 'https://' + config.host + '/api/images/raw/%s' % image
        log.info("Downloading image From:'%s' To:'%s'" % (url, dest))
        try:
            args = ['curl',
                    '--cert', config.proxy,
                    '--insecure',
                    url, '>', dest]
            cmd = " ".join(args)
            log.info("Running Command: '%s'" % cmd)
            p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, env=config.get_restricted_env())
            for line in p.stdout.readlines():
                print line
            log.info("Command complete")
        except Exception, e:
            log.error("%s" % e)
            print e