Пример #1
0
    def test_add_list_delete_list(self):
        """
        We test the following:

            0. Verify no public images in index
            1. Add a public image with a location attr
               and no image data
            2. Check that image exists in index
            3. Delete the image
            4. Verify no longer in index
        """
        self.cleanup()
        self.start_servers()

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        # 1. Add public image
        cmd = "bin/glance --port=%d add is_public=True name=MyImage" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('Added new image with ID: 1', out.strip())

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertEqual(1, len(lines))
        self.assertTrue('MyImage' in lines[0])

        # 3. Delete the image
        cmd = "bin/glance --port=%d --force delete 1" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('Deleted image 1', out.strip())

        # 4. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        self.stop_servers()
Пример #2
0
    def test_exception_not_eaten_from_registry_to_api(self):
        """
        A test for LP bug #704854 -- Exception thrown by registry
        server is consumed by API server.

        We start both servers daemonized.

        We then use curl to try adding an image that does not
        meet validation requirements on the registry server and test
        that the error returned from the API server to curl is appropriate
        """
        self.cleanup()
        self.start_servers()

        api_port = self.api_port

        cmd = "curl -g http://127.0.0.1:%d/v1/images" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('{"images": []}', out.strip())

        cmd = ("curl -X POST -H 'Content-Type: application/octet-stream' "
               "-H 'X-Image-Meta-Name: ImageName' "
               "-H 'X-Image-Meta-Disk-Format: Invalid' "
               "http://127.0.0.1:%d/v1/images" % api_port)
        ignored, out, err = execute(cmd)

        self.assertTrue('Invalid disk format' in out,
                        "Could not find 'Invalid disk format' "
                        "in output: %s" % out)

        self.stop_servers()
Пример #3
0
    def start_servers(self, **kwargs):
        """
        Starts the authentication and admin servers (keystone-auth and
        keystone-admin) on unused ports, in addition to the Glance API
        and Registry servers.

        Any kwargs passed to this method will override the
        configuration value in the conf file used in starting the
        servers.
        """
        # Start with the Glance servers
        super(KeystoneTests, self).start_servers(**kwargs)

        # Set up the data store
        keystone_conf = self.auth_server.write_conf(**kwargs)
        datafile = os.path.join(os.path.dirname(__file__), "data", "keystone_data.py")
        execute("python %s -c %s" % (datafile, keystone_conf))

        # Start keystone-auth
        exitcode, out, err = self.auth_server.start(**kwargs)

        self.assertEqual(0, exitcode, "Failed to spin up the Auth server. " "Got: %s" % err)
        self.assertTrue("Starting keystone-auth with" in out)

        # Now keystone-admin
        exitcode, out, err = self.admin_server.start(**kwargs)

        self.assertEqual(0, exitcode, "Failed to spin up the Admin server. " "Got: %s" % err)
        self.assertTrue("Starting keystone-admin with" in out)

        self.wait_for_keystone_servers()
Пример #4
0
    def _setup_database(self):
        sql_connection = 'sqlite:////%s/tests.sqlite' % self.test_dir
        self.config(connection=sql_connection, group='database')
        glance.db.sqlalchemy.api.clear_db_env()
        glance_db_env = 'GLANCE_DB_TEST_SQLITE_FILE'
        if glance_db_env in os.environ:
            # use the empty db created and cached as a tempfile
            # instead of spending the time creating a new one
            db_location = os.environ[glance_db_env]
            test_utils.execute('cp %s %s/tests.sqlite'
                               % (db_location, self.test_dir))
        else:
            glance.db.sqlalchemy.migration.db_sync()

            # copy the clean db to a temp location so that it
            # can be reused for future tests
            (osf, db_location) = tempfile.mkstemp()
            os.close(osf)
            test_utils.execute('cp %s/tests.sqlite %s'
                               % (self.test_dir, db_location))
            os.environ[glance_db_env] = db_location

            # cleanup the temp file when the test suite is
            # complete
            def _delete_cached_db():
                try:
                    os.remove(os.environ[glance_db_env])
                except Exception:
                    glance_tests.logger.exception(
                        "Error cleaning up the file %s" %
                        os.environ[glance_db_env])
            atexit.register(_delete_cached_db)
Пример #5
0
    def test_api_treats_size_as_a_normal_property(self):
        """
        A test for LP bug #825024 -- glance client currently
        treats size as a normal property.
        """

        self.cleanup()
        self.start_servers()

        # 1. POST /images with public image named Image1
        # attribute and no custom properties. Verify a 200 OK is returned
        with tempfile.NamedTemporaryFile() as image_file:
            image_file.write("XXX")
            image_file.flush()
            image_file_name = image_file.name
            cmd = "bin/glance --port=%d add is_public=True name=MyImage "\
                  "size=12345 < %s" % (self.api_port, image_file_name)

            exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue('Found non-settable field size. Removing.' in out)
        self.assertTrue('Added new image with ID: 1' in out)

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d show %d" % (self.api_port, 1)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertFalse("12345" in out)

        self.stop_servers()
Пример #6
0
    def test_killed_image_not_in_index(self):
        """
        We test conditions that produced LP Bug #768969, where an image
        in the 'killed' status is displayed in the output of glance index,
        and the status column is not displayed in the output of
        glance show <ID>.

            Start servers with Swift backend and a bad auth URL, and then:
            0. Verify no public images in index
            1. Attempt to add an image
            2. Verify the image does NOT appear in the index output
        """
        self.cleanup()

        # Start servers with a Swift backend and a bad auth URL
        override_options = {
            'default_store': 'swift',
            'swift_store_auth_address': 'badurl',
        }
        options = self.__dict__.copy()
        options.update(override_options)
        self.start_servers(**options)

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        # 1. Attempt to add an image
        with tempfile.NamedTemporaryFile() as image_file:
            image_file.write("XXX")
            image_file.flush()
            image_file_name = image_file.name
            cmd = ("bin/glance --port=%d add name=Jonas is_public=True "
                   "disk_format=qcow2 container_format=bare < %s"
                   % (api_port, image_file_name))

            exitcode, out, err = execute(cmd, raise_error=False)

            self.assertNotEqual(0, exitcode)
            self.assertTrue('Failed to add image.' in out)

        # 2. Verify image does not appear as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        self.stop_servers()
Пример #7
0
    def _sync_db(self):
        with open(self.conf_filepath, 'wb') as conf_file:
            conf_file.write('[DEFAULT]\n')
            conf_file.write(self.connection)
            conf_file.flush()

        cmd = ('%s -m glance.cmd.manage --config-file %s db sync' %
               (sys.executable, self.conf_filepath))
        execute(cmd, raise_error=True)
Пример #8
0
    def test_add_with_location_and_id(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        image_id = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"

        # 1a. Add public image
        cmd = minimal_add_command(api_port,
                                  'MyImage',
                                  'id=%s' % image_id,
                                  'location=http://example.com')
        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        expected = 'Added new image with ID: %s' % image_id
        self.assertTrue(expected in out)

        # 1b. Add public image with non-uuid id
        cmd = minimal_add_command(api_port,
                                  'MyImage',
                                  'id=12345',
                                  'location=http://example.com')
        exitcode, out, err = execute(cmd, expected_exitcode=1)

        self.assertEqual(1, exitcode)
        self.assertTrue('Invalid image id format' in out)

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertEqual(1, len(lines))

        line = lines[0]

        image_id, name, disk_format, container_format, size = \
            [c.strip() for c in line.split()]
        self.assertEqual('MyImage', name)

        self.assertEqual('0', size, "Expected image to be 0 bytes in size, "
                                    "but got %s. " % size)

        self.stop_servers()
Пример #9
0
    def _sync_db(self, auto_create):
        with open(self.conf_filepath, 'wb') as conf_file:
            conf_file.write('[DEFAULT]\n')
            conf_file.write('db_auto_create = %r\n' % auto_create)
            conf_file.write(self.connection)
            conf_file.flush()

        cmd = ('bin/glance-manage db_sync --config-file %s' %
               self.conf_filepath)
        execute(cmd, raise_error=True)
Пример #10
0
    def _do_test_update_external_source(self, source):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        setup_http(self)

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add public image with no image content
        headers = {'X-Image-Meta-Name': 'MyImage',
                   'X-Image-Meta-disk_format': 'raw',
                   'X-Image-Meta-container_format': 'ovf',
                   'X-Image-Meta-Is-Public': 'True'}
        path = "http://%s:%d/v1/images" % ("0.0.0.0", api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', headers=headers)
        self.assertEqual(response.status, 201)
        data = json.loads(content)
        self.assertEqual(data['image']['name'], 'MyImage')
        image_id = data['image']['id']

        # 2. Update image with external source
        source = '%s=%s' % (source, get_http_uri(self, 'foobar'))
        cmd = "bin/glance update %s %s -p %d" % (image_id, source, api_port)
        exitcode, out, err = execute(cmd, raise_error=False)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().endswith('Updated image %s' % image_id))

        # 3. Verify image is now active and of the correct size
        cmd = "bin/glance --port=%d show %s" % (api_port, image_id)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)

        expected_lines = [
            'URI: http://0.0.0.0:%s/v1/images/%s' % (api_port, image_id),
            'Id: %s' % image_id,
            'Public: Yes',
            'Name: MyImage',
            'Status: active',
            'Size: 5120',
            'Disk format: raw',
            'Container format: ovf',
            'Minimum Ram Required (MB): 0',
            'Minimum Disk Required (GB): 0',
        ]
        lines = out.split("\n")
        self.assertTrue(set(lines) >= set(expected_lines))

        self.stop_servers()
Пример #11
0
    def _do_test_update_external_source(self, source):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        setup_http(self)

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add public image with no image content
        headers = {
            "X-Image-Meta-Name": "MyImage",
            "X-Image-Meta-disk_format": "raw",
            "X-Image-Meta-container_format": "ovf",
            "X-Image-Meta-Is-Public": "True",
        }
        path = "http://%s:%d/v1/images" % ("0.0.0.0", api_port)
        http = httplib2.Http()
        response, content = http.request(path, "POST", headers=headers)
        self.assertEqual(response.status, 201)
        data = json.loads(content)
        self.assertEqual(data["image"]["name"], "MyImage")
        image_id = data["image"]["id"]

        # 2. Update image with external source
        source = "%s=%s" % (source, get_http_uri(self, "foobar"))
        cmd = "bin/glance update %s %s -p %d" % (image_id, source, api_port)
        exitcode, out, err = execute(cmd, raise_error=False)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().endswith("Updated image %s" % image_id))

        # 3. Verify image is now active and of the correct size
        cmd = "bin/glance --port=%d show %s" % (api_port, image_id)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)

        expected_lines = [
            "URI: http://0.0.0.0:%s/v1/images/%s" % (api_port, image_id),
            "Id: %s" % image_id,
            "Public: Yes",
            "Name: MyImage",
            "Status: active",
            "Size: 5120",
            "Disk format: raw",
            "Container format: ovf",
            "Minimum Ram Required (MB): 0",
            "Minimum Disk Required (GB): 0",
        ]
        lines = out.split("\n")
        self.assertTrue(set(lines) >= set(expected_lines))
Пример #12
0
    def test_show_image_format(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add public image
        with tempfile.NamedTemporaryFile() as image_file:
            image_file.write("XXX")
            image_file.flush()
            image_file_name = image_file.name
            suffix = ' --silent-upload < %s' % image_file_name
            cmd = minimal_add_command(api_port, 'MyImage', suffix)

            exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        image_id = out.strip().rsplit(' ', 1)[1]

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d show %s" % (api_port, image_id)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[:-1]

        expected_lines = [
            'URI: http://0.0.0.0:%s/v1/images/%s' % (api_port, image_id),
            'Id: %s' % image_id,
            'Public: Yes',
            'Name: MyImage',
            'Status: active',
            'Size: 3',
            'Disk format: raw',
            'Container format: ovf',
            'Minimum Ram Required (MB): 0',
            'Minimum Disk Required (GB): 0',
        ]

        self.assertTrue(set(lines) >= set(expected_lines))

        # 3. Delete the image
        cmd = "bin/glance --port=%d --force delete %s" % (api_port, image_id)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('Deleted image %s' % image_id, out.strip())

        self.stop_servers()
Пример #13
0
    def test_add_clear(self):
        """
        We test the following:

            1. Add a couple images with metadata
            2. Clear the images
            3. Verify no public images found
            4. Run SQL against DB to verify no undeleted properties
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add some images
        for i in range(1, 5):
            cmd = minimal_add_command(api_port,
                                      'MyImage',
                                      'foo=bar')
            exitcode, out, err = execute(cmd)

            self.assertEqual(0, exitcode)
            self.assertTrue(out.strip().find('Added new image with ID:') > -1)

        # 2. Clear all images
        cmd = "bin/glance --port=%d --force clear" % api_port
        exitcode, out, err = execute(cmd)
        self.assertEqual(0, exitcode)

        # 3. Verify no public images are found
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")
        first_line = lines[0]
        self.assertEqual('', first_line)

        # 4. Lastly we manually verify with SQL that image properties are
        # also getting marked as deleted.
        sql = "SELECT COUNT(*) FROM image_properties WHERE deleted = 0"
        recs = self.run_sql_cmd(sql)
        for rec in recs:
            self.assertEqual(0, rec[0])

        self.stop_servers()
Пример #14
0
    def test_add_with_location_and_stdin(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        # 1. Add public image
        with tempfile.NamedTemporaryFile() as image_file:
            image_file.write("XXX")
            image_file.flush()
            file_name = image_file.name
            cmd = minimal_add_command(api_port,
                                     'MyImage',
                                     'location=http://localhost:0 < %s' %
                                     file_name)
            exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertEqual(1, len(lines))

        line = lines[0]

        img_info = [c.strip() for c in line.split()]
        image_id, name, disk_format, container_format, size = img_info
        self.assertEqual('MyImage', name)

        self.assertEqual('0', size, "Expected image to be 0 bytes in size, "
                                    "but got %s. " % size)

        self.stop_servers()
Пример #15
0
    def test_cache_index(self):
        """
        Test that cache index command works
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # Verify no cached images
        cmd = "bin/glance-cache-manage --port=%d list-cached" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue('No cached images' in out.strip())

        ids = {}

        # Add a few images and cache the second one of them
        # by GETing the image...
        for x in xrange(0, 4):
            ids[x] = self.add_image("Image%s" % x)

        path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", api_port,
                                              ids[1])
        http = httplib2.Http()
        response, content = http.request(path, 'GET')
        self.assertEqual(response.status, 200)

        self.assertTrue(self.is_image_cached(ids[1]),
                        "%s is not cached." % ids[1])

        self.stop_servers()
    def test_scrubber_app(self):
        """
        test that the glance-scrubber script runs successfully when not in
        daemon mode
        """
        self.cleanup()
        self.start_servers(delayed_delete=True, daemon=False)

        headers = {
            'x-image-meta-name': 'test_image',
            'x-image-meta-is_public': 'true',
            'x-image-meta-disk_format': 'raw',
            'x-image-meta-container_format': 'ovf',
            'content-type': 'application/octet-stream',
        }
        path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', body='XXX',
                                         headers=headers)
        self.assertEqual(response.status, 201)
        image = json.loads(content)['image']
        self.assertEqual('active', image['status'])
        image_id = image['id']

        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port,
                                              image_id)
        http = httplib2.Http()
        response, content = http.request(path, 'DELETE')
        self.assertEqual(response.status, 200)

        response, content = http.request(path, 'HEAD')
        self.assertEqual(response.status, 200)
        self.assertEqual('pending_delete', response['x-image-meta-status'])

        # wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # scrub images and make sure they get deleted
        cmd = ("bin/glance-scrubber --config-file %s" %
               self.scrubber_daemon.conf_file_name)
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        # NOTE(jkoelker) The build servers sometimes take longer than
        #                15 seconds to scrub. Give it up to 5 min, checking
        #                checking every 15 seconds. When/if it flips to
        #                deleted, bail immediatly.
        for _ in xrange(3):
            time.sleep(5)

            response, content = http.request(path, 'HEAD')
            if (response['x-image-meta-status'] == 'deleted' and
                response['x-image-meta-deleted'] == 'True'):
                break
            else:
                continue
        else:
            self.fail('image was never scrubbed')

        self.stop_servers()
Пример #17
0
 def _assert_table_exists(self, db_table):
     cmd = ("sqlite3 {0} \"SELECT name FROM sqlite_master WHERE "
            "type='table' AND name='{1}'\"").format(self.db_filepath,
                                                    db_table)
     exitcode, out, err = execute(cmd, raise_error=True)
     msg = "Expected table {0} was not found in the schema".format(db_table)
     self.assertEqual(out.rstrip().decode("utf-8"), db_table, msg)
Пример #18
0
    def test_add_location_without_checksum(self):
        """
        We test the following:

            1. Add an image with location and no checksum
            2. Run SQL against DB to verify checksum is NULL
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add public image
        cmd = minimal_add_command(api_port,
                                 'MyImage',
                                 'location=http://example.com')
        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        image_id = out.split(":")[1].strip()

        sql = 'SELECT checksum FROM images WHERE id = "%s"' % image_id
        recs = self.run_sql_cmd(sql)

        self.assertEqual(None, recs.first()[0])

        self.stop_servers()
Пример #19
0
 def _get_children(self):
     api_pid = open(self.api_server.pid_file).read().strip()
     cmd = ("ps --no-headers --ppid %s -o pid,cmd | "
            "grep python | "  # NOTE(markwash): ignore non-python procs
            "awk '{print $1; print >> \"/dev/stderr\"}'" % api_pid)
     _, out, err = execute(cmd, raise_error=True)
     return out.strip().split('\n')
Пример #20
0
    def start(self, **kwargs):
        """
        Starts the server.

        Any kwargs passed to this method will override the configuration
        value in the conf file used in starting the servers.
        """
        if self.conf_file:
            raise RuntimeError("Server configuration file already exists!")
        if not self.conf_base:
            raise RuntimeError("Subclass did not populate config_base!")

        conf_override = self.__dict__.copy()
        if kwargs:
            conf_override.update(**kwargs)

        # A config file to use just for this test...we don't want
        # to trample on currently-running Glance servers, now do we?

        conf_file = tempfile.NamedTemporaryFile()
        conf_file.write(self.conf_base % conf_override)
        conf_file.flush()
        self.conf_file = conf_file
        self.conf_file_name = conf_file.name

        cmd = "./bin/glance-control %(server_name)s start " "%(conf_file_name)s --pid-file=%(pid_file)s" % self.__dict__
        return execute(cmd)
Пример #21
0
 def _reset_database(self, conn_string):
     conn_pieces = urlparse.urlparse(conn_string)
     if conn_string.startswith("sqlite"):
         # We can just delete the SQLite database, which is
         # the easiest and cleanest solution
         db_path = conn_pieces.path.strip("/")
         if db_path and os.path.exists(db_path):
             os.unlink(db_path)
         # No need to recreate the SQLite DB. SQLite will
         # create it for us if it's not there...
     elif conn_string.startswith("mysql"):
         # We can execute the MySQL client to destroy and re-create
         # the MYSQL database, which is easier and less error-prone
         # than using SQLAlchemy to do this via MetaData...trust me.
         database = conn_pieces.path.strip("/")
         loc_pieces = conn_pieces.netloc.split("@")
         host = loc_pieces[1]
         auth_pieces = loc_pieces[0].split(":")
         user = auth_pieces[0]
         password = ""
         if len(auth_pieces) > 1:
             if auth_pieces[1].strip():
                 password = "******" % auth_pieces[1]
         sql = ("drop database if exists %(database)s; " "create database %(database)s;") % locals()
         cmd = ("mysql -u%(user)s %(password)s -h%(host)s " '-e"%(sql)s"') % locals()
         exitcode, out, err = execute(cmd)
         self.assertEqual(0, exitcode)
Пример #22
0
 def stop(self):
     """
     Spin down the server.
     """
     cmd = ("%(server_control)s %(server_name)s stop "
            "%(conf_file_name)s --pid-file=%(pid_file)s" % self.__dict__)
     return execute(cmd, no_venv=self.no_venv, exec_env=self.exec_env)
 def _reset_databases(self):
     for key, engine in self.engines.items():
         conn_string = TestMigrations.TEST_DATABASES[key]
         conn_pieces = urlparse.urlparse(conn_string)
         if conn_string.startswith('sqlite'):
             # We can just delete the SQLite database, which is
             # the easiest and cleanest solution
             db_path = conn_pieces.path.strip('/')
             if os.path.exists(db_path):
                 os.unlink(db_path)
             # No need to recreate the SQLite DB. SQLite will
             # create it for us if it's not there...
         elif conn_string.startswith('mysql'):
             # We can execute the MySQL client to destroy and re-create
             # the MYSQL database, which is easier and less error-prone
             # than using SQLAlchemy to do this via MetaData...trust me.
             database = conn_pieces.path.strip('/')
             loc_pieces = conn_pieces.netloc.split('@')
             host = loc_pieces[1]
             auth_pieces = loc_pieces[0].split(':')
             user = auth_pieces[0]
             password = ""
             if len(auth_pieces) > 1:
                 if auth_pieces[1].strip():
                     password = "******" % auth_pieces[1]
             sql = ("drop database if exists %(database)s; "
                    "create database %(database)s;") % locals()
             cmd = ("mysql -u%(user)s %(password)s -h%(host)s "
                    "-e\"%(sql)s\"") % locals()
             exitcode, out, err = utils.execute(cmd)
             self.assertEqual(0, exitcode)
    def test_cache_index(self):
        """
        Test that cache index command works
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port

        # Verify no cached images
        exe_cmd = "%s -m glance.cmd.cache_manage" % sys.executable
        cmd = "%s --port=%d list-cached" % (exe_cmd, api_port)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertIn("No cached images", out.strip())

        ids = {}

        # Add a few images and cache the second one of them
        # by GETing the image...
        for x in range(4):
            ids[x] = self.add_image("Image%s" % x)

        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", api_port, ids[1])
        http = httplib2.Http()
        response, content = http.request(path, "GET")
        self.assertEqual(200, response.status)

        self.assertTrue(self.is_image_cached(ids[1]), "%s is not cached." % ids[1])

        self.assertTrue(self.iso_date(ids[1]))

        self.stop_servers()
Пример #25
0
 def _assert_table_exists(self, db_table):
     cmd = ("sqlite3 {0} \"SELECT name FROM sqlite_master WHERE "
            "type='table' AND name='{1}'\"").format(self.db_filepath,
                                                    db_table)
     exitcode, out, err = execute(cmd, raise_error=True)
     msg = "Expected table {0} was not found in the schema".format(db_table)
     self.assertEqual(out.rstrip(), db_table, msg)
Пример #26
0
    def test_timeout(self):
        self.cleanup()

        keep_sleeping = True

        #start a simple HTTP server in a thread that hangs for a bit
        class RemoteImageHandler(BaseHTTPServer.BaseHTTPRequestHandler):
            def do_GET(self):
                cnt = 1
                while (keep_sleeping):
                    cnt += 1
                    time.sleep(0.1)
                    if cnt > 100:
                        break

        server_class = BaseHTTPServer.HTTPServer
        local_server = server_class(('127.0.0.1', 0), RemoteImageHandler)
        local_ip, local_port = local_server.server_address

        def serve_requests(httpd):
            httpd.serve_forever()

        thread.start_new_thread(serve_requests, (local_server,))

        cmd = ("bin/glance --port=%d index --timeout=1") % local_port
        exitcode, out, err = execute(cmd, raise_error=False)

        keep_sleeping = False
        local_server.shutdown()
        self.assertNotEqual(0, exitcode)
        self.assertTrue("timed out" in out)
Пример #27
0
    def test_add_location_without_checksum(self):
        """
        We test the following:

            1. Add an image with location and no checksum
            2. Run SQL against DB to verify checksum is NULL
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add public image
        cmd = minimal_add_command(api_port, 'MyImage',
                                  'location=http://example.com')
        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        image_id = out.split(":")[1].strip()

        sql = 'SELECT checksum FROM images WHERE id = "%s"' % image_id
        recs = self.run_sql_cmd(sql)

        self.assertEqual(None, recs.first()[0])

        self.stop_servers()
Пример #28
0
    def test_scrubber_app_queue_errors_not_daemon(self):
        """
        test that the glance-scrubber exits with an exit code > 0 when it
        fails to lookup images, indicating a configuration error when not
        in daemon mode.

        Related-Bug: #1548289
        """
        # Don't start the registry server to cause intended failure
        # Don't start the api server to save time
        exitcode, out, err = self.scrubber_daemon.start(
            delayed_delete=True, daemon=False)
        self.assertEqual(0, exitcode,
                         "Failed to spin up the Scrubber daemon. "
                         "Got: %s" % err)

        # Run the Scrubber
        exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
        cmd = ("%s --config-file %s" %
               (exe_cmd, self.scrubber_daemon.conf_file_name))
        exitcode, out, err = execute(cmd, raise_error=False)

        self.assertEqual(1, exitcode)
        self.assertIn('Can not get scrub jobs from queue', str(err))

        self.stop_server(self.scrubber_daemon)
Пример #29
0
    def test_scrubber_app_against_swift(self):
        """
        test that the glance-scrubber script runs successfully against a swift
        backend when not in daemon mode
        """
        config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF')
        if not config_path:
            msg = "GLANCE_TEST_SWIFT_CONF environ not set."
            self.skipTest(msg)

        raw_config = read_config(config_path)
        swift_config = parse_config(raw_config)

        self.cleanup()
        self.start_servers(delayed_delete=True, daemon=False,
                           default_store='swift', **swift_config)

        # add an image
        headers = {
            'x-image-meta-name': 'test_image',
            'x-image-meta-is_public': 'true',
            'x-image-meta-disk_format': 'raw',
            'x-image-meta-container_format': 'ovf',
            'content-type': 'application/octet-stream',
        }
        path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', body='XXX',
                                         headers=headers)
        # ensure the request was successful and the image is active
        self.assertEqual(response.status, 201)
        image = json.loads(content)['image']
        self.assertEqual('active', image['status'])
        image_id = image['id']

        # delete the image
        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port,
                                              image_id)
        http = httplib2.Http()
        response, content = http.request(path, 'DELETE')
        self.assertEqual(response.status, 200)

        # ensure the image is marked pending delete
        response, content = http.request(path, 'HEAD')
        self.assertEqual(response.status, 200)
        self.assertEqual('pending_delete', response['x-image-meta-status'])

        # wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # call the scrubber to scrub images
        cmd = ("bin/glance-scrubber --config-file %s" %
               self.scrubber_daemon.conf_file_name)
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        # ensure the image has been successfully deleted
        wait_for_scrub(path)

        self.stop_servers()
Пример #30
0
    def test_timeout(self):
        self.cleanup()

        keep_sleeping = True

        #start a simple HTTP server in a thread that hangs for a bit
        class RemoteImageHandler(BaseHTTPServer.BaseHTTPRequestHandler):
            def do_GET(self):
                cnt = 1
                while (keep_sleeping):
                    cnt += 1
                    time.sleep(0.1)
                    if cnt > 100:
                        break

        server_class = BaseHTTPServer.HTTPServer
        local_server = server_class(('127.0.0.1', 0), RemoteImageHandler)
        local_ip, local_port = local_server.server_address

        def serve_requests(httpd):
            httpd.serve_forever()

        thread.start_new_thread(serve_requests, (local_server, ))

        cmd = ("bin/glance --port=%d index --timeout=1") % local_port
        exitcode, out, err = execute(cmd, raise_error=False)

        keep_sleeping = False
        local_server.shutdown()
        self.assertNotEqual(0, exitcode)
        self.assertTrue("timed out" in out)
    def test_cache_index(self):
        """
        Test that cache index command works
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # Verify no cached images
        cmd = "bin/glance-cache-manage --port=%d list-cached" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue('No cached images' in out.strip())

        ids = {}

        # Add a few images and cache the second one of them
        # by GETing the image...
        for x in xrange(0, 4):
            ids[x] = self.add_image("Image%s" % x)

        path = "http://%s:%d/v1/images/%s" % ("0.0.0.0", api_port,
                                              ids[1])
        http = httplib2.Http()
        response, content = http.request(path, 'GET')
        self.assertEqual(response.status, 200)

        self.assertTrue(self.is_image_cached(ids[1]),
                        "%s is not cached." % ids[1])

        self.stop_servers()
Пример #32
0
    def test_scrubber_app_queue_errors_not_daemon(self):
        """
        test that the glance-scrubber exits with an exit code > 0 when it
        fails to lookup images, indicating a configuration error when not
        in daemon mode.

        Related-Bug: #1548289
        """
        # Don't start the registry server to cause intended failure
        # Don't start the api server to save time
        exitcode, out, err = self.scrubber_daemon.start(
            delayed_delete=True, daemon=False, registry_port=28890)
        self.assertEqual(0, exitcode,
                         "Failed to spin up the Scrubber daemon. "
                         "Got: %s" % err)

        # Run the Scrubber
        exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
        cmd = ("%s --config-file %s" %
               (exe_cmd, self.scrubber_daemon.conf_file_name))
        exitcode, out, err = execute(cmd, raise_error=False)

        self.assertEqual(1, exitcode)
        self.assertIn('Can not get scrub jobs from queue', err)

        self.stop_server(self.scrubber_daemon, 'Scrubber daemon')
Пример #33
0
 def _reset_databases(self):
     for key, engine in self.engines.items():
         conn_string = TestMigrations.TEST_DATABASES[key]
         conn_pieces = urlparse.urlparse(conn_string)
         if conn_string.startswith('sqlite'):
             # We can just delete the SQLite database, which is
             # the easiest and cleanest solution
             db_path = conn_pieces.path.strip('/')
             if os.path.exists(db_path):
                 os.unlink(db_path)
             # No need to recreate the SQLite DB. SQLite will
             # create it for us if it's not there...
         elif conn_string.startswith('mysql'):
             # We can execute the MySQL client to destroy and re-create
             # the MYSQL database, which is easier and less error-prone
             # than using SQLAlchemy to do this via MetaData...trust me.
             database = conn_pieces.path.strip('/')
             loc_pieces = conn_pieces.netloc.split('@')
             host = loc_pieces[1]
             auth_pieces = loc_pieces[0].split(':')
             user = auth_pieces[0]
             password = ""
             if len(auth_pieces) > 1:
                 if auth_pieces[1].strip():
                     password = "******" % auth_pieces[1]
             sql = ("drop database if exists %(database)s; "
                    "create database %(database)s;") % locals()
             cmd = ("mysql -u%(user)s %(password)s -h%(host)s "
                    "-e\"%(sql)s\"") % locals()
             exitcode, out, err = utils.execute(cmd)
             self.assertEqual(0, exitcode)
Пример #34
0
    def test_scrubber_app(self):
        """
        test that the glance-scrubber script runs successfully when not in
        daemon mode
        """
        self.cleanup()
        self.start_servers(delayed_delete=True, daemon=False)

        headers = {
            'x-image-meta-name': 'test_image',
            'x-image-meta-is_public': 'true',
            'x-image-meta-disk_format': 'raw',
            'x-image-meta-container_format': 'ovf',
            'content-type': 'application/octet-stream',
        }
        path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', body='XXX',
                                         headers=headers)
        self.assertEqual(response.status, 201)
        image = json.loads(content)['image']
        self.assertEqual('active', image['status'])
        image_id = image['id']

        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port,
                                              image_id)
        http = httplib2.Http()
        response, content = http.request(path, 'DELETE')
        self.assertEqual(response.status, 200)

        response, content = http.request(path, 'HEAD')
        self.assertEqual(response.status, 200)
        self.assertEqual('pending_delete', response['x-image-meta-status'])

        # wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # scrub images and make sure they get deleted
        cmd = ("bin/glance-scrubber --config-file %s" %
               self.scrubber_daemon.conf_file_name)
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        # NOTE(jkoelker) The build servers sometimes take longer than
        #                15 seconds to scrub. Give it up to 5 min, checking
        #                checking every 15 seconds. When/if it flips to
        #                deleted, bail immediatly.
        for _ in xrange(3):
            time.sleep(5)

            response, content = http.request(path, 'HEAD')
            if (response['x-image-meta-status'] == 'deleted' and
                response['x-image-meta-deleted'] == 'True'):
                break
            else:
                continue
        else:
            self.fail('image was never scrubbed')

        self.stop_servers()
Пример #35
0
    def test_scrubber_app_against_swift(self):
        """
        test that the glance-scrubber script runs successfully against a swift
        backend when not in daemon mode
        """
        config_path = os.environ.get('GLANCE_TEST_SWIFT_CONF')
        if not config_path:
            msg = "GLANCE_TEST_SWIFT_CONF environ not set."
            self.skipTest(msg)

        raw_config = read_config(config_path)
        swift_config = parse_config(raw_config)

        self.cleanup()
        self.start_servers(delayed_delete=True, daemon=False,
                           default_store='swift', **swift_config)

        # add an image
        headers = {
            'x-image-meta-name': 'test_image',
            'x-image-meta-is_public': 'true',
            'x-image-meta-disk_format': 'raw',
            'x-image-meta-container_format': 'ovf',
            'content-type': 'application/octet-stream',
        }
        path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', body='XXX',
                                         headers=headers)
        # ensure the request was successful and the image is active
        self.assertEqual(response.status, 201)
        image = json.loads(content)['image']
        self.assertEqual('active', image['status'])
        image_id = image['id']

        # delete the image
        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port,
                                              image_id)
        http = httplib2.Http()
        response, content = http.request(path, 'DELETE')
        self.assertEqual(response.status, 200)

        # ensure the image is marked pending delete
        response, content = http.request(path, 'HEAD')
        self.assertEqual(response.status, 200)
        self.assertEqual('pending_delete', response['x-image-meta-status'])

        # wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # call the scrubber to scrub images
        cmd = ("glance-scrubber --config-file %s" %
               self.scrubber_daemon.conf_file_name)
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        # ensure the image has been successfully deleted
        self.wait_for_scrub(path)

        self.stop_servers()
Пример #36
0
    def test_add_clear(self):
        """
        We test the following:

            1. Add a couple images with metadata
            2. Clear the images
            3. Verify no public images found
            4. Run SQL against DB to verify no undeleted properties
        """
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 1. Add some images
        for i in range(1, 5):
            cmd = "bin/glance --port=%d add is_public=True name=MyName " \
                  " foo=bar" % api_port
            exitcode, out, err = execute(cmd)

            self.assertEqual(0, exitcode)
            self.assertTrue(out.strip().find('Added new image with ID:') > -1)

        # 2. Clear all images
        cmd = "bin/glance --port=%d --force clear" % api_port
        exitcode, out, err = execute(cmd)
        self.assertEqual(0, exitcode)

        # 3. Verify no public images are found
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")
        first_line = lines[0]
        self.assertEqual('', first_line)

        # 4. Lastly we manually verify with SQL that image properties are
        # also getting marked as deleted.
        sql = "SELECT COUNT(*) FROM image_properties WHERE deleted = 0"
        recs = self.run_sql_cmd(sql)
        for rec in recs:
            self.assertEqual(0, rec[0])

        self.stop_servers()
Пример #37
0
    def test_scrubber_delete_handles_exception(self):
        """
        Test that the scrubber handles the case where an
        exception occurs when _delete() is called. The scrubber
        should not write out queue files in this case.
        """

        # Start servers.
        self.cleanup()
        kwargs = self.__dict__.copy()
        kwargs['use_user_token'] = True
        self.start_servers(delayed_delete=True,
                           daemon=False,
                           default_store='file',
                           **kwargs)

        # Check that we are using a file backend.
        self.assertEqual(self.api_server.default_store, 'file')

        # add an image
        path = "http://%s:%d/v2/images" % ("127.0.0.1", self.api_port)
        response, content = self._send_create_image_http_request(path)
        self.assertEqual(http_client.CREATED, response.status)
        image = jsonutils.loads(content)
        self.assertEqual('queued', image['status'])

        file_path = "%s/%s/file" % (path, image['id'])
        response, content = self._send_upload_image_http_request(file_path,
                                                                 body='XXX')
        self.assertEqual(http_client.NO_CONTENT, response.status)

        path = "%s/%s" % (path, image['id'])
        response, content = self._send_http_request(path, 'GET')
        image = jsonutils.loads(content)
        self.assertEqual('active', image['status'])
        # delete the image
        response, content = self._send_http_request(path, 'DELETE')
        self.assertEqual(http_client.NO_CONTENT, response.status)
        # ensure the image is marked pending delete.
        image = self._get_pending_delete_image(image['id'])
        self.assertEqual('pending_delete', image['status'])

        # Remove the file from the backend.
        file_path = os.path.join(self.api_server.image_dir, image['id'])
        os.remove(file_path)

        # Wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # run the scrubber app, and ensure it doesn't fall over
        exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
        cmd = ("%s --config-file %s" %
               (exe_cmd, self.scrubber_daemon.conf_file_name))
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        self.wait_for_scrub(image['id'])

        self.stop_servers()
Пример #38
0
    def test_add_with_location_and_stdin(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        # 1. Add public image
        with tempfile.NamedTemporaryFile() as image_file:
            image_file.write("XXX")
            image_file.flush()
            file_name = image_file.name
            cmd = minimal_add_command(
                api_port, 'MyImage',
                'location=http://example.com < %s' % file_name)
            exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertEqual(1, len(lines))

        line = lines[0]

        img_info = [c.strip() for c in line.split()]
        image_id, name, disk_format, container_format, size = img_info
        self.assertEqual('MyImage', name)

        self.assertEqual(
            '0', size, "Expected image to be 0 bytes in size, "
            "but got %s. " % size)
Пример #39
0
    def _assert_tables(self):
        cmd = "sqlite3 %s '.schema'" % self.db_filepath
        exitcode, out, err = execute(cmd, raise_error=True)

        self.assertTrue('CREATE TABLE images' in out)
        self.assertTrue('CREATE TABLE image_tags' in out)
        self.assertTrue('CREATE TABLE image_members' in out)
        self.assertTrue('CREATE TABLE image_properties' in out)
Пример #40
0
    def _assert_tables(self):
        cmd = "sqlite3 %s '.schema'" % self.db_filepath
        exitcode, out, err = execute(cmd, raise_error=True)

        self.assertTrue('CREATE TABLE images' in out)
        self.assertTrue('CREATE TABLE image_tags' in out)
        self.assertTrue('CREATE TABLE image_members' in out)
        self.assertTrue('CREATE TABLE image_properties' in out)
Пример #41
0
 def stop(self):
     """
     Spin down the server.
     """
     cmd = ("%(server_control)s %(server_name)s stop "
            "%(conf_file_name)s --pid-file=%(pid_file)s"
            % self.__dict__)
     return execute(cmd, no_venv=self.no_venv, exec_env=self.exec_env)
Пример #42
0
 def stop(self):
     """
     Spin down the server.
     """
     cmd = ("./bin/glance-control %(server_name)s stop "
            "%(conf_file_name)s --pid-file=%(pid_file)s"
            % self.__dict__)
     return execute(cmd)
Пример #43
0
    def test_scrubber_app_with_trustedauth_registry(self):
        """
        test that the glance-scrubber script runs successfully when not in
        daemon mode and with a registry that operates in trustedauth mode
        """
        self.cleanup()
        self.api_server.deployment_flavor = 'noauth'
        self.registry_server.deployment_flavor = 'trusted-auth'
        self.start_servers(delayed_delete=True, daemon=False,
                           metadata_encryption_key='',
                           send_identity_headers=True)
        base_headers = {
            'X-Identity-Status': 'Confirmed',
            'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96',
            'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e',
            'X-Tenant-Id': 'deae8923-075d-4287-924b-840fb2644874',
            'X-Roles': 'admin',
        }
        headers = {
            'x-image-meta-name': 'test_image',
            'x-image-meta-is_public': 'true',
            'x-image-meta-disk_format': 'raw',
            'x-image-meta-container_format': 'ovf',
            'content-type': 'application/octet-stream',
        }
        headers.update(base_headers)
        path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', body='XXX',
                                         headers=headers)
        self.assertEqual(http_client.CREATED, response.status)
        image = jsonutils.loads(content)['image']
        self.assertEqual('active', image['status'])
        image_id = image['id']

        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port,
                                              image_id)
        http = httplib2.Http()
        response, content = http.request(path, 'DELETE', headers=base_headers)
        self.assertEqual(http_client.OK, response.status)

        response, content = http.request(path, 'HEAD', headers=base_headers)
        self.assertEqual(http_client.OK, response.status)
        self.assertEqual('pending_delete', response['x-image-meta-status'])

        # wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # scrub images and make sure they get deleted
        exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
        cmd = ("%s --config-file %s" %
               (exe_cmd, self.scrubber_daemon.conf_file_name))
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        self.wait_for_scrub(path, headers=base_headers)

        self.stop_servers()
Пример #44
0
    def test_scrubber_app_with_trustedauth_registry(self):
        """
        test that the glance-scrubber script runs successfully when not in
        daemon mode and with a registry that operates in trustedauth mode
        """
        self.cleanup()
        self.api_server.deployment_flavor = 'noauth'
        self.registry_server.deployment_flavor = 'trusted-auth'
        self.start_servers(delayed_delete=True, daemon=False,
                           metadata_encryption_key='',
                           send_identity_headers=True)
        base_headers = {
            'X-Identity-Status': 'Confirmed',
            'X-Auth-Token': '932c5c84-02ac-4fe5-a9ba-620af0e2bb96',
            'X-User-Id': 'f9a41d13-0c13-47e9-bee2-ce4e8bfe958e',
            'X-Tenant-Id': 'deae8923-075d-4287-924b-840fb2644874',
            'X-Roles': 'admin',
        }
        headers = {
            'x-image-meta-name': 'test_image',
            'x-image-meta-is_public': 'true',
            'x-image-meta-disk_format': 'raw',
            'x-image-meta-container_format': 'ovf',
            'content-type': 'application/octet-stream',
        }
        headers.update(base_headers)
        path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
        http = httplib2.Http()
        response, content = http.request(path, 'POST', body='XXX',
                                         headers=headers)
        self.assertEqual(http_client.CREATED, response.status)
        image = jsonutils.loads(content)['image']
        self.assertEqual('active', image['status'])
        image_id = image['id']

        path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", self.api_port,
                                              image_id)
        http = httplib2.Http()
        response, content = http.request(path, 'DELETE', headers=base_headers)
        self.assertEqual(http_client.OK, response.status)

        response, content = http.request(path, 'HEAD', headers=base_headers)
        self.assertEqual(http_client.OK, response.status)
        self.assertEqual('pending_delete', response['x-image-meta-status'])

        # wait for the scrub time on the image to pass
        time.sleep(self.api_server.scrub_time)

        # scrub images and make sure they get deleted
        exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
        cmd = ("%s --config-file %s" %
               (exe_cmd, self.scrubber_daemon.conf_file_name))
        exitcode, out, err = execute(cmd, raise_error=False)
        self.assertEqual(0, exitcode)

        self.wait_for_scrub(path, headers=base_headers)

        self.stop_servers()
Пример #45
0
    def test_add_copying_from(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        setup_http(self)

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        # 1. Add public image
        suffix = 'copy_from=%s' % get_http_uri(self, 'foobar')
        cmd = minimal_add_command(api_port, 'MyImage', suffix)
        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertEqual(1, len(lines))

        line = lines[0]

        image_id, name, disk_format, container_format, size = \
            [c.strip() for c in line.split()]
        self.assertEqual('MyImage', name)

        self.assertEqual(
            '5120', size, "Expected image to be 5120 bytes "
            " in size, but got %s. " % size)

        self.stop_servers()
Пример #46
0
 def _test_content():
     exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
     cmd = ("%s --config-file %s --restore %s" %
            (exe_cmd, self.scrubber_daemon.conf_file_name, image['id']))
     exitcode, out, err = execute(cmd, raise_error=False)
     self.assertEqual(1, exitcode)
     self.assertIn(
         'cannot restore the image from active to active '
         '(wanted from_state=pending_delete)', str(err))
Пример #47
0
    def _db_command(self, db_method):
        with open(self.conf_filepath, 'w') as conf_file:
            conf_file.write('[DEFAULT]\n')
            conf_file.write(self.connection)
            conf_file.flush()

        cmd = ('%s -m glance.cmd.manage --config-file %s db %s' %
               (sys.executable, self.conf_filepath, db_method))
        return execute(cmd, raise_error=True)
Пример #48
0
    def iso_date(self, image_id):
        """
        Return True if supplied image ID is cached, False otherwise
        """
        cmd = "glance-cache-manage --port=%d list-cached" % self.api_port

        exitcode, out, err = execute(cmd)

        return datetime.datetime.utcnow().strftime("%Y-%m-%d") in out
Пример #49
0
    def test_index_with_https(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        cmd = ("bin/glance -N https://auth/ --port=%d index") % self.api_port
        exitcode, out, err = execute(cmd, raise_error=False)

        self.assertNotEqual(0, exitcode)
        self._assertNotIn('SSL23_GET_SERVER_HELLO', out)
Пример #50
0
    def test_scrubber_restore_image_with_daemon_raise_error(self):

        exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
        cmd = ("%s --daemon --restore fake_image_id" % exe_cmd)
        exitcode, out, err = execute(cmd, raise_error=False)

        self.assertEqual(1, exitcode)
        self.assertIn('The restore and daemon options should not be set '
                      'together', str(err))
Пример #51
0
    def _verify_owner(self, owner, image_id):
        cmd = "bin/glance --port=%d show %s" % (self.api_port, image_id)
        exitcode, out, err = execute(cmd)
        self.assertEqual(0, exitcode)

        # verify expected owner as first class attribute
        self.assertTrue(('Owner: %s' % owner) in out)
        # ensure owner does not appear as a custom property
        self.assertFalse("Property 'owner':" in out)
Пример #52
0
    def _create_by_admin(self, owner):
        # ownership set by admin user (defaults as such due to no-auth)
        cmd = minimal_add_command(self.api_port, 'MyImage',
                                  '--silent-upload owner=%s' % owner)
        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        return out.strip().replace('Added new image with ID: ', '')
 def test_compare(self):
     # Test for issue: https://bugs.launchpad.net/glance/+bug/1598928
     cmd = ('%s -m glance.cmd.replicator '
            'compare az1:9292 az2:9292 --debug' %
            (sys.executable,))
     exitcode, out, err = execute(cmd, raise_error=False)
     self.assertIn(
         'Request: GET http://az1:9292/v1/images/detail?is_public=None',
         err
     )
Пример #54
0
 def _test_content():
     scrubber = functional.ScrubberDaemon(self.test_dir,
                                          self.policy_file)
     scrubber.write_conf(daemon=False)
     scrubber.needs_database = True
     scrubber.create_database()
     exe_cmd = "%s -m glance.cmd.scrubber" % sys.executable
     cmd = ("%s --config-file %s --restore fake_image_id" %
            (exe_cmd, scrubber.conf_file_name))
     return execute(cmd, raise_error=False)
Пример #55
0
    def iso_date(self, image_id):
        """
        Return True if supplied image ID is cached, False otherwise
        """
        exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
        cmd = "%s --port=%d list-cached" % (exe_cmd, self.api_port)

        exitcode, out, err = execute(cmd)

        return datetime.datetime.utcnow().strftime("%Y-%m-%d") in out
    def is_image_cached(self, image_id):
        """
        Return True if supplied image ID is cached, False otherwise
        """
        cmd = "bin/glance-cache-manage --port=%d list-cached" % self.api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        return image_id in out
Пример #57
0
    def test_add_no_name(self):
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        api_port = self.api_port
        registry_port = self.registry_port

        # 0. Verify no public images
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertEqual('', out.strip())

        # 1. Add public image
        # Can't use minimal_add_command since that uses
        # name...
        cmd = ("bin/glance --port=%d add is_public=True"
               " disk_format=raw container_format=ovf"
               " %s" % (api_port, 'location=http://localhost:0'))
        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        self.assertTrue(out.strip().startswith('Added new image with ID:'))

        # 2. Verify image added as public image
        cmd = "bin/glance --port=%d index" % api_port

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        lines = out.split("\n")[2:-1]
        self.assertEqual(1, len(lines))

        line = lines[0]

        image_id, name, disk_format, container_format, size = \
            [c.strip() for c in line.split()]
        self.assertEqual('None', name)

        self.stop_servers()
Пример #58
0
    def is_image_cached(self, image_id):
        """
        Return True if supplied image ID is cached, False otherwise
        """
        exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
        cmd = "%s --port=%d list-cached" % (exe_cmd, self.api_port)

        exitcode, out, err = execute(cmd)

        self.assertEqual(0, exitcode)
        return image_id in out
Пример #59
0
    def test_big_int_mapping(self):
        """Ensure BigInteger not mapped to BIGINT"""
        self.cleanup()
        self.start_servers(**self.__dict__.copy())

        cmd = 'sqlite3 tests.sqlite ".schema"'
        exitcode, out, err = execute(cmd, raise_error=True)

        self.assertNotIn('BIGINT', out)

        self.stop_servers()