Пример #1
0
def main():
    CONF.register_cli_opts(scrubber.scrubber_cmd_cli_opts)
    CONF.register_opts(scrubber.scrubber_cmd_opts)

    try:
        config.parse_args()
        log.setup('glance')

        glance_store.register_opts(config.CONF)
        glance_store.create_stores(config.CONF)
        glance_store.verify_default_store()

        app = scrubber.Scrubber(glance_store)

        if CONF.daemon:
            server = scrubber.Daemon(CONF.wakeup_time)
            server.start(app)
            systemd.notify_once()
            server.wait()
        else:
            import eventlet
            pool = eventlet.greenpool.GreenPool(1000)
            app.run(pool)
    except RuntimeError as e:
        sys.exit("ERROR: %s" % e)
Пример #2
0
    def test_store_delete_successful(self, mock_image_get):
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'

        scrub = scrubber.Scrubber(glance_store)
        with patch.object(glance_store, "delete_from_backend"):
            scrub._scrub_image(id, [(id, '-', uri)])
Пример #3
0
 def _scrubber_cleanup_with_store_delete_exception(self, ex):
     uri = 'file://some/path/%s' % uuid.uuid4()
     id = 'helloworldid'
     scrub = scrubber.Scrubber(glance_store)
     with patch.object(glance_store, "delete_from_backend") as _mock_delete:
         _mock_delete.side_effect = ex
         scrub._scrub_image(id, [(id, '-', uri)])
Пример #4
0
def main():
    CONF.register_cli_opt(
        cfg.BoolOpt('daemon',
                    short='D',
                    default=False,
                    help='Run as a long-running process. When not '
                    'specified (the default) run the scrub operation '
                    'once and then exits. When specified do not exit '
                    'and run scrub on wakeup_time interval as '
                    'specified in the config.'))
    CONF.register_opt(cfg.IntOpt('wakeup_time', default=300))

    try:

        config.parse_args()
        log.setup('glance')

        glance.store.create_stores()
        glance.store.verify_default_store()

        app = scrubber.Scrubber(glance.store)

        if CONF.daemon:
            server = scrubber.Daemon(CONF.wakeup_time)
            server.start(app)
            server.wait()
        else:
            import eventlet
            pool = eventlet.greenpool.GreenPool(1000)
            app.run(pool)
    except RuntimeError as e:
        sys.exit("ERROR: %s" % e)
Пример #5
0
 def _scrubber_cleanup_with_store_delete_exception(self, ex):
     uri = 'file://some/path/%s' % uuid.uuid4()
     id = 'helloworldid'
     scrub = scrubber.Scrubber(glance_store)
     self.mox.StubOutWithMock(glance_store, "delete_from_backend")
     glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndRaise(ex)
     self.mox.ReplayAll()
     scrub._scrub_image(id, [(id, '-', uri)])
     self.mox.VerifyAll()
Пример #6
0
 def test_scrubber_exits(self):
     # Checks for Scrubber exits when it is not able to fetch jobs from
     # the queue
     scrub_jobs = scrubber.ScrubDBQueue.get_all_locations
     scrub_jobs = mock.MagicMock()
     scrub_jobs.side_effect = exception.NotFound
     scrub = scrubber.Scrubber(glance_store)
     self.assertRaises(exception.FailedToGetScrubberJobs,
                       scrub._get_delete_jobs)
Пример #7
0
    def test_store_delete_successful(self, mock_image_get):
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'

        scrub = scrubber.Scrubber(glance_store)
        self.mox.StubOutWithMock(glance_store, "delete_from_backend")
        glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndReturn('')
        self.mox.ReplayAll()
        scrub._scrub_image(id, [(id, '-', uri)])
        self.mox.VerifyAll()
Пример #8
0
def main():
    # Used on Window, ensuring that a single scrubber can run at a time.
    mutex = None
    mutex_acquired = False

    try:
        if os.name == 'nt':
            # We can't rely on process names on Windows as there may be
            # wrappers with the same name.
            mutex = os_win_utilsfactory.get_mutex(
                name='Global\\glance-scrubber')
            mutex_acquired = mutex.acquire(timeout_ms=0)

        CONF.register_cli_opts(scrubber.scrubber_cmd_cli_opts)
        CONF.register_opts(scrubber.scrubber_cmd_opts)

        config.parse_args()
        logging.setup(CONF, 'glance')

        glance_store.register_opts(config.CONF)
        glance_store.create_stores(config.CONF)
        glance_store.verify_default_store()

        if CONF.restore and CONF.daemon:
            sys.exit("ERROR: The restore and daemon options should not be set "
                     "together. Please use either of them in one request.")

        app = scrubber.Scrubber(glance_store)

        if CONF.restore:
            if os.name == 'nt':
                scrubber_already_running = not mutex_acquired
            else:
                scrubber_already_running = scrubber_already_running_posix()

            if scrubber_already_running:
                already_running_msg = (
                    "ERROR: glance-scrubber is already running. "
                    "Please ensure that the daemon is stopped.")
                sys.exit(already_running_msg)

            app.revert_image_status(CONF.restore)
        elif CONF.daemon:
            server = scrubber.Daemon(CONF.wakeup_time)
            server.start(app)
            server.wait()
        else:
            app.run()
    except (exception.ImageNotFound, exception.Conflict) as e:
        sys.exit("ERROR: %s" % e)
    except RuntimeError as e:
        sys.exit("ERROR: %s" % e)
    finally:
        if mutex and mutex_acquired:
            mutex.release()
Пример #9
0
    def test_store_delete_notfound_exception(self, mock_image_get):
        # While scrubbing image data, NotFound exception is ignored and image
        # scrubbing succeeds
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'
        ex = glance_store.NotFound(message='random')

        scrub = scrubber.Scrubber(glance_store)
        with patch.object(glance_store, "delete_from_backend") as _mock_delete:
            _mock_delete.side_effect = ex
            scrub._scrub_image(id, [(id, '-', uri)])
Пример #10
0
    def test_scrubber_revert_image_status(self, mock_image_restore):
        scrub = scrubber.Scrubber(glance_store)
        scrub.revert_image_status('fake_id')

        mock_image_restore.side_effect = exception.ImageNotFound
        self.assertRaises(exception.ImageNotFound, scrub.revert_image_status,
                          'fake_id')

        mock_image_restore.side_effect = exception.Conflict
        self.assertRaises(exception.Conflict, scrub.revert_image_status,
                          'fake_id')
Пример #11
0
 def _scrubber_cleanup_with_store_delete_exception(self, ex):
     uri = 'file://some/path/%s' % uuid.uuid4()
     id = 'helloworldid'
     scrub = scrubber.Scrubber(glance_store)
     scrub.registry = self.mox.CreateMockAnything()
     scrub.registry.get_image(id).AndReturn({'status': 'pending_delete'})
     scrub.registry.update_image(id, {'status': 'deleted'})
     self.mox.StubOutWithMock(glance_store, "delete_from_backend")
     glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndRaise(ex)
     self.mox.ReplayAll()
     scrub._scrub_image(id, [(id, '-', uri)])
     self.mox.VerifyAll()
Пример #12
0
    def test_store_delete_notfound_exception(self, mock_image_get):
        # While scrubbing image data, NotFound exception is ignored and image
        # scrubbing succeeds
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'
        ex = glance_store.NotFound(message='random')

        scrub = scrubber.Scrubber(glance_store)
        self.mox.StubOutWithMock(glance_store, "delete_from_backend")
        glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndRaise(ex)
        self.mox.ReplayAll()
        scrub._scrub_image(id, [(id, '-', uri)])
        self.mox.VerifyAll()
Пример #13
0
    def test_store_delete_store_exceptions(self, mock_image_get):
        # While scrubbing image data, all store exceptions, other than
        # NotFound, cause image scrubbing to fail. Essentially, no attempt
        # would be made to update the status of image.

        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'
        ex = glance_store.GlanceStoreException()

        scrub = scrubber.Scrubber(glance_store)
        with patch.object(glance_store, "delete_from_backend") as _mock_delete:
            _mock_delete.side_effect = ex
            scrub._scrub_image(id, [(id, '-', uri)])
Пример #14
0
    def test_store_delete_store_exceptions(self, mock_image_get):
        # While scrubbing image data, all store exceptions, other than
        # NotFound, cause image scrubbing to fail. Essentially, no attempt
        # would be made to update the status of image.

        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'
        ex = glance_store.GlanceStoreException()

        scrub = scrubber.Scrubber(glance_store)
        self.mox.StubOutWithMock(glance_store, "delete_from_backend")
        glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndRaise(ex)
        self.mox.ReplayAll()
        scrub._scrub_image(id, [(id, '-', uri)])
        self.mox.VerifyAll()
Пример #15
0
    def _scrubber_cleanup_with_store_delete_exception(self, ex):
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'
        scrub = scrubber.Scrubber(glance.store)
        scrub.registry = self.mox.CreateMockAnything()
        scrub.registry.get_image(id).AndReturn({'status': 'pending_delete'})
        scrub.registry.update_image(id, {'status': 'deleted'})
        self.mox.StubOutWithMock(glance.store, "delete_from_backend")
        glance.store.delete_from_backend(mox.IgnoreArg(), uri).AndRaise(ex)
        self.mox.ReplayAll()
        scrub._scrub_image(eventlet.greenpool.GreenPool(1), id,
                           [(id, '-', uri)])
        self.mox.VerifyAll()

        q_path = os.path.join(self.data_dir, id)
        self.assertFalse(os.path.exists(q_path))
Пример #16
0
    def test_scrubber_exits(self):
        # Checks for Scrubber exits when it is not able to fetch jobs from
        # the queue
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'

        scrub = scrubber.Scrubber(glance_store)
        scrub.registry = self.mox.CreateMockAnything()
        scrub.registry.get_image(id).AndReturn({'status': 'pending_delete'})
        scrub.registry.update_image(id, {'status': 'deleted'})
        self.mox.StubOutWithMock(glance_store, "delete_from_backend")
        ex = glance_store.GlanceStoreException()
        glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndRaise(ex)
        self.mox.ReplayAll()
        self.assertRaises(exception.FailedToGetScrubberJobs,
                          scrub._get_delete_jobs)
Пример #17
0
    def test_store_delete_notfound_exception(self):
        # While scrubbing image data, NotFound exception is ignored and image
        # scrubbing succeeds
        uri = 'file://some/path/%s' % uuid.uuid4()
        id = 'helloworldid'
        ex = glance_store.NotFound(message='random')

        scrub = scrubber.Scrubber(glance_store)
        scrub.registry = self.mox.CreateMockAnything()
        scrub.registry.get_image(id).AndReturn({'status': 'pending_delete'})
        scrub.registry.update_image(id, {'status': 'deleted'})
        self.mox.StubOutWithMock(glance_store, "delete_from_backend")
        glance_store.delete_from_backend(uri, mox.IgnoreArg()).AndRaise(ex)
        self.mox.ReplayAll()
        scrub._scrub_image(id, [(id, '-', uri)])
        self.mox.VerifyAll()
Пример #18
0
def main():
    CONF.register_cli_opts(scrubber.scrubber_cmd_cli_opts)
    CONF.register_opts(scrubber.scrubber_cmd_opts)

    try:
        config.parse_args()
        logging.setup(CONF, 'glance')

        glance_store.register_opts(config.CONF)
        glance_store.create_stores(config.CONF)
        glance_store.verify_default_store()

        app = scrubber.Scrubber(glance_store)

        if CONF.daemon:
            server = scrubber.Daemon(CONF.wakeup_time)
            server.start(app)
            server.wait()
        else:
            app.run()
    except RuntimeError as e:
        sys.exit("ERROR: %s" % e)
Пример #19
0
def main():
    CONF.register_cli_opts(scrubber.scrubber_cmd_cli_opts)
    CONF.register_opts(scrubber.scrubber_cmd_opts)

    try:
        config.parse_args()
        logging.setup(CONF, 'glance')

        glance_store.register_opts(config.CONF)
        glance_store.create_stores(config.CONF)
        glance_store.verify_default_store()

        app = scrubber.Scrubber(glance_store)

        if CONF.restore and CONF.daemon:
            sys.exit("ERROR: The restore and daemon options should not be set "
                     "together. Please use either of them in one request.")
        if CONF.restore:
            # Try to check the glance-scrubber is running or not.
            # 1. Try to find the pid file if scrubber is controlled by
            #    glance-control
            # 2. Try to check the process name.
            error_str = ("ERROR: The glance-scrubber process is running under "
                         "daemon. Please stop it first.")
            pid_file = '/var/run/glance/glance-scrubber.pid'
            if os.path.exists(os.path.abspath(pid_file)):
                sys.exit(error_str)

            for glance_scrubber_name in ['glance-scrubber',
                                         'glance.cmd.scrubber']:
                cmd = subprocess.Popen(
                    ['/usr/bin/pgrep', '-f', glance_scrubber_name],
                    stdout=subprocess.PIPE, shell=False)
                pids, _ = cmd.communicate()

                # The response format of subprocess.Popen.communicate() is
                # diffderent between py2 and py3. It's "string" in py2, but
                # "bytes" in py3.
                if isinstance(pids, bytes):
                    pids = pids.decode()
                self_pid = os.getpid()

                if pids.count('\n') > 1 and str(self_pid) in pids:
                    # One process is self, so if the process number is > 1, it
                    # means that another glance-scrubber process is running.
                    sys.exit(error_str)
                elif pids.count('\n') > 0 and str(self_pid) not in pids:
                    # If self is not in result and the pids number is still
                    # > 0, it means that the another glance-scrubber process is
                    # running.
                    sys.exit(error_str)
            app.revert_image_status(CONF.restore)
        elif CONF.daemon:
            server = scrubber.Daemon(CONF.wakeup_time)
            server.start(app)
            server.wait()
        else:
            app.run()
    except (exception.ImageNotFound, exception.Conflict) as e:
        sys.exit("ERROR: %s" % e)
    except RuntimeError as e:
        sys.exit("ERROR: %s" % e)