openstack flavors - dianaclarke/openstack-notes GitHub Wiki

OpenStack Flavors

{
    "flavor": {
        "name": "flavortest",
        "ram": 1024,
        "vcpus": 2,
        "disk": 10,
        "id": "100",
        "rxtx_factor": 2.0
    }
}

{
    "flavor": {
        "OS-FLV-DISABLED:disabled": false,
        "disk": 10,
        "OS-FLV-EXT-DATA:ephemeral": 0,
        "os-flavor-access:is_public": true,
        "id": "100",
        "links": [
            {
                "href": "http://openstack.example.com/v2.1/flavors/100",
                "rel": "self"
            },
            {
                "href": "http://openstack.example.com/flavors/100",
                "rel": "bookmark"
            }
        ],
        "name": "flavortest",
        "ram": 1024,
        "rxtx_factor": 2.0,
        "swap": "",
        "vcpus": 2
    }
}
  • Default flavours:
$ nova flavor-list
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 42 | m1.nano   | 64        | 0    | 0         |      | 1     | 1.0         | True      |
| 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
| 84 | m1.micro  | 128       | 0    | 0         |      | 1     | 1.0         | True      |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+

MariaDB [nova]> describe instance_types;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| created_at   | datetime     | YES  |     | NULL    |                |
| updated_at   | datetime     | YES  |     | NULL    |                |
| deleted_at   | datetime     | YES  |     | NULL    |                |
| name         | varchar(255) | YES  | MUL | NULL    |                |
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| memory_mb    | int(11)      | NO   |     | NULL    |                |
| vcpus        | int(11)      | NO   |     | NULL    |                |
| swap         | int(11)      | NO   |     | NULL    |                |
| vcpu_weight  | int(11)      | YES  |     | NULL    |                |
| flavorid     | varchar(255) | YES  | MUL | NULL    |                |
| rxtx_factor  | float        | YES  |     | NULL    |                |
| root_gb      | int(11)      | YES  |     | NULL    |                |
| ephemeral_gb | int(11)      | YES  |     | NULL    |                |
| disabled     | tinyint(1)   | YES  |     | NULL    |                |
| is_public    | tinyint(1)   | YES  |     | NULL    |                |
| deleted      | int(11)      | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

MariaDB [nova]> select * from instance_types order by id desc limit 1 \G
*************************** 1. row ***************************
  created_at: 2015-09-29 19:49:02
  updated_at: NULL
  deleted_at: NULL
        name: m1.micro
          id: 7
   memory_mb: 128
       vcpus: 1
        swap: 0
 vcpu_weight: NULL
    flavorid: 84
 rxtx_factor: 1
     root_gb: 0
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 0
  • Nova client help for flavor-create:
$ nova help flavor-create
usage: nova flavor-create [--ephemeral <ephemeral>] [--swap <swap>]
                          [--rxtx-factor <factor>] [--is-public <is-public>]
                          <name> <id> <ram> <disk> <vcpus>

Create a new flavor

Positional arguments:
  <name>                   Name of the new flavor
  <id>                     Unique ID (integer or UUID) for the new flavor. If
                           specifying 'auto', a UUID will be generated as id
  <ram>                    Memory size in MB
  <disk>                   Disk size in GB
  <vcpus>                  Number of vcpus

Optional arguments:
  --ephemeral <ephemeral>  Ephemeral space size in GB (default 0)
  --swap <swap>            Swap space size in MB (default 0)
  --rxtx-factor <factor>   RX/TX factor (default 1)
  --is-public <is-public>  Make flavor accessible to the public (default true)
$ nova flavor-create Jack jack 1024 10 2
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| jack | Jack | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+

MariaDB [nova]> select * from instance_types order by id desc limit 1\G
*************************** 1. row ***************************
  created_at: 2015-10-02 17:20:57
  updated_at: NULL
  deleted_at: NULL
        name: Jack
          id: 8
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 0
  • Can you delete a named flavor like "jack"?
$ nova help flavor-delete
usage: nova flavor-delete <flavor>

Delete a specific flavor

Positional arguments:
  <flavor>  Name or ID of the flavor to delete

$ nova flavor-delete jack
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| jack | Jack | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
  • And what does the database look like now?
MariaDB [nova]> select * from instance_types where name = 'Jack'\G
*************************** 1. row ***************************
  created_at: 2015-10-02 17:20:57
  updated_at: 2015-10-02 17:36:20
  deleted_at: 2015-10-02 17:36:20
        name: Jack
          id: 8
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 8          <===== changed from 0 to 8 (same as the id)
  • Doing the same for a numbered flavor:
$ nova flavor-create Numbered 999 1024 10 2
+-----+----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID  | Name     | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+-----+----------+-----------+------+-----------+------+-------+-------------+-----------+
| 999 | Numbered | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+-----+----------+-----------+------+-----------+------+-------+-------------+-----------+

$ nova flavor-delete 999 
+-----+----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID  | Name     | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+-----+----------+-----------+------+-----------+------+-------+-------------+-----------+
| 999 | Numbered | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+-----+----------+-----------+------+-----------+------+-------+-------------+-----------+

MariaDB [nova]> select * from instance_types where name = 'Numbered'\G
*************************** 1. row ***************************
  created_at: 2015-10-02 17:37:02
  updated_at: 2015-10-02 17:37:09
  deleted_at: 2015-10-02 17:37:09
        name: Numbered
          id: 9
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: 999
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 9          <==== changed from 0 to 9 (same as the id)
  • Try deleting an already deleted flavor:
]$ nova flavor-delete Bob
ERROR (NotFound): Flavor Bob could not be found. (HTTP 404) (Request-ID: req-e9f29eb5-93e3-4c81-95ba-f4016cac9583)
  • Hmmm... Create another "jack" flavour even though we already have a soft-deleted one.
[diana@reserved devstack]$ nova flavor-create Jack jack 1024 10 2
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| jack | Jack | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+

MariaDB [nova]> select * from instance_types where flavorid = 'jack'\G
*************************** 1. row ***************************
  created_at: 2015-10-02 17:51:51
  updated_at: NULL
  deleted_at: NULL
        name: Jack
          id: 11
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 0
*************************** 2. row ***************************
  created_at: 2015-10-02 17:20:57
  updated_at: 2015-10-02 17:36:20
  deleted_at: 2015-10-02 17:36:20
        name: Jack
          id: 8
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 8
  • Then try to delete it. Nope, still no error.
$ nova flavor-delete jack
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| jack | Jack | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+

MariaDB [nova]> select * from instance_types where flavorid = 'jack'\G
*************************** 1. row ***************************
  created_at: 2015-10-02 17:20:57
  updated_at: 2015-10-02 17:36:20
  deleted_at: 2015-10-02 17:36:20
        name: Jack
          id: 8
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 8
*************************** 2. row ***************************
  created_at: 2015-10-02 17:51:51
  updated_at: 2015-10-02 17:55:14
  deleted_at: 2015-10-02 17:55:14
        name: Jack
          id: 11
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 11
  • There can only be one active flavor at a time:
$ nova flavor-create Jack jack 1024 10 2
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| jack | Jack | 1024      | 10   | 0         |      | 2     | 1.0         | True      |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+

$ nova flavor-create Jack jack 1024 10 2
ERROR (Conflict): Flavor with name Jack already exists. (HTTP 409) (Request-ID: req-3631fed3-e093-4559-a886-af84328990f2)
  • What if you make the active flavor private?
MariaDB [nova]> select * from instance_types where id = 12\G       
*************************** 1. row ***************************
  created_at: 2015-10-02 18:00:43
  updated_at: NULL
  deleted_at: NULL
        name: Jack
          id: 12
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 1
     deleted: 0

MariaDB [nova]> update instance_types set is_public = 0 where id = 12;

MariaDB [nova]> select * from instance_types where id = 12\G       
*************************** 1. row ***************************
  created_at: 2015-10-02 18:00:43
  updated_at: NULL
  deleted_at: NULL
        name: Jack
          id: 12
   memory_mb: 1024
       vcpus: 2
        swap: 0
 vcpu_weight: NULL
    flavorid: jack
 rxtx_factor: 1
     root_gb: 10
ephemeral_gb: 0
    disabled: 0
   is_public: 0
     deleted: 0

$ nova flavor-list
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 42 | m1.nano   | 64        | 0    | 0         |      | 1     | 1.0         | True      |
| 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
| 84 | m1.micro  | 128       | 0    | 0         |      | 1     | 1.0         | True      |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+

$ nova flavor-list --all
+------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1    | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2    | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3    | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4    | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 42   | m1.nano   | 64        | 0    | 0         |      | 1     | 1.0         | True      |
| 5    | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
| 84   | m1.micro  | 128       | 0    | 0         |      | 1     | 1.0         | True      |
| jack | Jack      | 1024      | 10   | 0         |      | 2     | 1.0         | False     |
+------+-----------+-----------+------+-----------+------+-------+-------------+-----------+

Still no error... 

$ nova flavor-delete jack
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| ID   | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+
| jack | Jack | 1024      | 10   | 0         |      | 2     | 1.0         | False     |
+------+------+-----------+------+-----------+------+-------+-------------+-----------+

$ nova flavor-list --all
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 1  | m1.tiny   | 512       | 1    | 0         |      | 1     | 1.0         | True      |
| 2  | m1.small  | 2048      | 20   | 0         |      | 1     | 1.0         | True      |
| 3  | m1.medium | 4096      | 40   | 0         |      | 2     | 1.0         | True      |
| 4  | m1.large  | 8192      | 80   | 0         |      | 4     | 1.0         | True      |
| 42 | m1.nano   | 64        | 0    | 0         |      | 1     | 1.0         | True      |
| 5  | m1.xlarge | 16384     | 160  | 0         |      | 8     | 1.0         | True      |
| 84 | m1.micro  | 128       | 0    | 0         |      | 1     | 1.0         | True      |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
  • Is there anything interesting in the delete/destroy code paths?
nova/compute/flavors.py

def destroy(name):
    """Marks flavor as deleted."""
    try:
        if not name:
            raise ValueError()
        flavor = objects.Flavor(context=context.get_admin_context(), name=name)
        flavor.destroy()
    except (ValueError, exception.NotFound):
        LOG.exception(_LE('Instance type %s not found for deletion'), name)
        raise exception.FlavorNotFoundByName(flavor_name=name)

nova/objects/flavor.py

    @base.remotable
    def destroy(self):
        db.flavor_destroy(self._context, self.name)

nova/db/api.py

def flavor_destroy(context, name):
    """Delete an instance type."""
    return IMPL.flavor_destroy(context, name)

nova/db/sqlalchemy/api.py

def flavor_destroy(context, name):
    """Marks specific flavor as deleted."""
    session = get_session()
    with session.begin():
        ref = model_query(context, models.InstanceTypes, session=session,
                          read_deleted="no").\
                    filter_by(name=name).\
                    first()
        if not ref:
            raise exception.FlavorNotFoundByName(flavor_name=name)

        ref.soft_delete(session=session)
        model_query(context, models.InstanceTypeExtraSpecs,
                    session=session, read_deleted="no").\
                filter_by(instance_type_id=ref['id']).\
                soft_delete()
        model_query(context, models.InstanceTypeProjects,
                    session=session, read_deleted="no").\
                filter_by(instance_type_id=ref['id']).\
                soft_delete()
  • Default users, roles, etc in DevStack:
[diana@localhost devstack]$ openstack user list 
+----------------------------------+----------+
| ID                               | Name     |
+----------------------------------+----------+
| 6596128ca7b34cebb2658a53c34c0c6b | demo     |
| 768d454fad4e40e2b7069019e1b59461 | admin    |
| 9a1edb5e1ba740568a84e54328689eb2 | cinder   |
| aa214e44004342f4b27f63f0f7058ad3 | nova     |
| b4775cb242a5455083cab98db7292f2a | alt_demo |
| e9a0603f19514c43a7d219901908df8a | glance   |
+----------------------------------+----------+
[diana@localhost devstack]$ openstack role list
+----------------------------------+---------------+
| ID                               | Name          |
+----------------------------------+---------------+
| 51bdc9aaa52b447098aaea7a88301d17 | admin         |
| 7195c04edb4f41749aa36cd885ab783d | ResellerAdmin |
| 7e7c52fa906a4294bbcba5d7ddafcdd6 | service       |
| 8039635182c043ad91a068eea860d488 | Member        |
| 9fe2ff9ee4384b1894a90878d3e92bab | _member_      |
| a477cfd2c26448058393079f27d4477d | anotherrole   |
+----------------------------------+---------------+
[diana@localhost devstack]$ openstack project list
+----------------------------------+--------------------+
| ID                               | Name               |
+----------------------------------+--------------------+
| 3787a6e299fb4f28b4b8047e9f1cfe6a | admin              |
| 69d1aff1fc3d43b8bc18eb3c05042091 | demo               |
| bdac73c690444c6d89ab4e0b41f2aa7c | invisible_to_admin |
| c8a36f487cb34dc4aae06fb074607dd5 | alt_demo           |
| dc55c0e31fb24638909570408a4baa6c | service            |
+----------------------------------+--------------------+
[diana@localhost devstack]$ openstack role list --user demo

[diana@localhost devstack]$ openstack role list --user demo --project demo
+----------------------------------+-------------+---------+------+
| ID                               | Name        | Project | User |
+----------------------------------+-------------+---------+------+
| a477cfd2c26448058393079f27d4477d | anotherrole | demo    | demo |
| 8039635182c043ad91a068eea860d488 | Member      | demo    | demo |
+----------------------------------+-------------+---------+------+
[diana@localhost devstack]$ openstack role list --user admin --project demo
+----------------------------------+-------+---------+-------+
| ID                               | Name  | Project | User  |
+----------------------------------+-------+---------+-------+
| 51bdc9aaa52b447098aaea7a88301d17 | admin | demo    | admin |
+----------------------------------+-------+---------+-------+
  • Note that the demo/demo user cannot create flavors:
{
  "forbidden": {
    "code": 403,
    "message": "Policy doesn't allow os_compute_api:os-flavor-manage to be performed."
  }
}
  • Now add the admin role to the demo/demo user, and note that the demo/demo user can now create flavors.
[diana@localhost devstack]$ openstack role add --user demo --project demo admin
+-------+----------------------------------+
| Field | Value                            |
+-------+----------------------------------+
| id    | 51bdc9aaa52b447098aaea7a88301d17 |
| name  | admin                            |
+-------+----------------------------------+
[diana@localhost devstack]$ openstack role list --user demo --project demo
+----------------------------------+-------------+---------+------+
| ID                               | Name        | Project | User |
+----------------------------------+-------------+---------+------+
| 8039635182c043ad91a068eea860d488 | Member      | demo    | demo |
| a477cfd2c26448058393079f27d4477d | anotherrole | demo    | demo |
| 51bdc9aaa52b447098aaea7a88301d17 | admin       | demo    | demo |
+----------------------------------+-------------+---------+------+
  • Remove the admin role from the demo/demo user.
[diana@localhost devstack]$ openstack role remove --user demo --project demo admin
[diana@localhost devstack]$ openstack role list --user demo --project demo
+----------------------------------+-------------+---------+------+
| ID                               | Name        | Project | User |
+----------------------------------+-------------+---------+------+
| a477cfd2c26448058393079f27d4477d | anotherrole | demo    | demo |
| 8039635182c043ad91a068eea860d488 | Member      | demo    | demo |
+----------------------------------+-------------+---------+------+
  • Edit policy.json like the user did.
[diana@localhost nova]$ pwd
/etc/nova
[diana@localhost nova]$ diff policy.json policy.json.bak 
150c150
<     "compute_extension:flavormanage": "admin_or_owner",
---
>     "compute_extension:flavormanage": "rule:admin_api",
[diana@localhost nova]$ diff policy.json policy.json.bak 
356c356
<     "os_compute_api:os-flavor-manage": "rule:admin_or_owner",
---
>     "os_compute_api:os-flavor-manage": "rule:admin_api",
  • So... based on these results, I suspect the bug is that only admin users (not owners) can delete private flavors. Note the 404 response in that case (demo_100_delete.txt).

[diana@localhost devstack]$ cat admin_100_delete.txt 
GET - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
Flavor: m1.tiny
Flavor: m1.small
POST - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
{
  "flavor": {
    "OS-FLV-DISABLED:disabled": false, 
    "OS-FLV-EXT-DATA:ephemeral": 0, 
    "disk": 10, 
    "id": "Admin100", 
    "links": [
      {
        "href": "http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Admin100", 
        "rel": "self"
      }, 
      {
        "href": "http://192.168.122.218:8774/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Admin100", 
        "rel": "bookmark"
      }
    ], 
    "name": "Admin100", 
    "os-flavor-access:is_public": false, 
    "ram": 1024, 
    "rxtx_factor": 1.0, 
    "swap": "", 
    "vcpus": 1
  }
}
DELETE - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Admin100
<Response [202]>
GET - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
Flavor: m1.tiny
Flavor: m1.small
[diana@localhost devstack]$ cat demo_100_delete.txt 
GET - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
Flavor: m1.tiny
Flavor: m1.small
POST - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
{
  "flavor": {
    "OS-FLV-DISABLED:disabled": false, 
    "OS-FLV-EXT-DATA:ephemeral": 0, 
    "disk": 10, 
    "id": "Demo100", 
    "links": [
      {
        "href": "http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Demo100", 
        "rel": "self"
      }, 
      {
        "href": "http://192.168.122.218:8774/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Demo100", 
        "rel": "bookmark"
      }
    ], 
    "name": "Demo100", 
    "os-flavor-access:is_public": false, 
    "ram": 1024, 
    "rxtx_factor": 1.0, 
    "swap": "", 
    "vcpus": 1
  }
}
DELETE - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Demo100
<Response [404]>
GET - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
Flavor: m1.tiny
Flavor: m1.small
[diana@localhost devstack]$ cat demo_101_delete.txt 
GET - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
Flavor: m1.tiny
Flavor: m1.small
POST - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
{
  "flavor": {
    "OS-FLV-DISABLED:disabled": false, 
    "OS-FLV-EXT-DATA:ephemeral": 0, 
    "disk": 10, 
    "id": "Demo101", 
    "links": [
      {
        "href": "http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Demo101", 
        "rel": "self"
      }, 
      {
        "href": "http://192.168.122.218:8774/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Demo101", 
        "rel": "bookmark"
      }
    ], 
    "name": "Demo101", 
    "os-flavor-access:is_public": true, 
    "ram": 1024, 
    "rxtx_factor": 1.0, 
    "swap": "", 
    "vcpus": 1
  }
}
DELETE - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors/Demo101
<Response [202]>
GET - http://192.168.122.218:8774/v2.1/69d1aff1fc3d43b8bc18eb3c05042091/flavors
Flavor: m1.tiny
Flavor: m1.small
  • Nova API logs of a flavor create and delete:
2015-10-28 18:34:36.384 DEBUG nova.osapi_compute.wsgi.server [req-d2eeb7f8-1f91-45e9bec2-225d89e43cc7 admin admin] (13456) accepted ('192.168.122.8', 38550) from (pid=13456) server /usr/lib/python2.7/site-packages/eventlet/wsgi.py:826

2015-10-28 18:34:36.391 DEBUG keystoneclient.session [req-d2eeb7f8-1f91-45e9-bec2-225d89e43cc7 admin admin] REQ: curl -g -i --cacert "/opt/stack/data/ca-bundle.pem" -X GET http://192.168.122.8:35357/v3/auth/tokens -H "X-Subject-Token {SHA1}c70f3cf4955876023a502c878419ad84c0267a49" -H "User-Agent: python-keystoneclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}51f40bb3c846e9ab6ebe29f70feb326a2c4114a7" from (pid=13456) _http_log_request /usr/lib/python2.7/site-packages/keystoneclient/session.py:198

2015-10-28 18:34:36.483 DEBUG keystoneclient.session [req-d2eeb7f8-1f91-45e9-bec2-225d89e43cc7 admin admin] RESP: [200] Content-Length: 4844 X-Subject-Token {SHA1}c70f3cf4955876023a502c878419ad84c0267a49 Vary: X-Auth-Token Keep-Alive: timeout=5, max=100 Server: Apache/2.4.16 (Fedora) OpenSSL/1.0.1k-fips mod_wsgi/4.4.8 Python/2.7.10 Connection: Keep-Alive Date: Wed, 28 Oct 2015 18:34:36 GMT Content-Type: application/json x-openstack-request-id: req-d66198e7-6443-4cdc-ae11-5ba2978387bc RESP BODY: {"token": {"methods": ["password", "token"], "roles": [{"id": "e316ece62e834dd5a413224b8052ba9d", "name": "admin"}], "expires_at": "2015-10-28T19:34:36.000000Z", "project": {"domain": {"id": "default", "name": "Default"}, "id": "07e3db7cc3104b4e829affd65b64af53", "name": "admin"}, "catalog": "<removed>", "extras": {}, "user":{"domain": {"id": "default", "name": "Default"}, "id": "630c0267189a4561a5510c69d01ee6d5", "name": "admin"}, "audit_ids": ["JiTl9-EXTb-KelKNzRQg7g"], "issued_at": "2015-10-28T18:34:36.346203"}} from (pid=13456) _http_log_response /usr/lib/python2.7/site-packages/keystoneclient/session.py:216

2015-10-28 18:34:36.490 DEBUG nova.api.openstack.wsgi [req-63486963-9042-4225-9307-064e8edeabca admin admin] Calling method '<bound method VersionsController.show of <nova.api.openstack.compute.versionsV21.VersionsController object at 0x7fd35fcf4950>>' from (pid=13456) _process_stack /opt/stack/nova/nova/api/openstack/wsgi.py:792

2015-10-28 18:34:36.496 INFO nova.osapi_compute.wsgi.server [req-63486963-9042-4225-9307-064e8edeabca admin admin] 192.168.122.8 "GET /v2.1/ HTTP/1.1" status: 200 len: 655 time: 0.1099679

2015-10-28 18:34:36.640 DEBUG nova.api.openstack.wsgi [req-7d40bf0e-02fc-4b2d-abb9-3975398884ba admin admin] Action: 'create', calling method: <bound method FlavorManageController._create of <nova.api.openstack.compute.flavor_manage.FlavorManageController object at 0x7fd35fc3aa50>>, body: {"flavor": {"vcpus": 2, "disk": 10, "name": "Diana", "os-flavor-access:is_public": true, "rxtx_factor": 1.0, "OS-FLV-EXT-DATA:ephemeral": 0, "ram": 1024, "id": "Diana", "swap": 0}} from (pid=13456) _process_stack /opt/stack/nova/nova/api/openstack/wsgi.py:789

2015-10-28 18:34:36.668 INFO nova.osapi_compute.wsgi.server [req-7d40bf0e-02fc-4b2dabb9-3975398884ba admin admin] 192.168.122.8 "POST /v2.1/07e3db7cc3104b4e829affd65b64af53/flavors HTTP/1.1" status: 200 len: 706 time: 0.0304492

2015-10-28 18:34:49.451 DEBUG nova.osapi_compute.wsgi.server [req-f4138fb1-e5e2-4295a112-140ab2e989de admin admin] (13455) accepted ('192.168.122.8', 38553) from (pid=13455) server /usr/lib/python2.7/site-packages/eventlet/wsgi.py:826

2015-10-28 18:34:49.459 DEBUG keystoneclient.session [req-f4138fb1-e5e2-4295-a112-140ab2e989de admin admin] REQ: curl -g -i --cacert "/opt/stack/data/ca-bundle.pem" -X GET http://192.168.122.8:35357/v3/auth/tokens -H "X-Subject-Token: {SHA1}aa2a4d09ac49a888ebc65eedb5a8e827427a133d" -H "User-Agent: python-keystoneclient" -H "Accept: application/json" -H "X-Auth-Token: {SHA1}03d75e0cefb3c89dc1386111cbea9293b8649de5" from (pid=13455) _http_log_request /usr/lib/python2.7/site-packages/keystoneclient/session.py:198 2015-10-28 18:34:49.603 DEBUG keystoneclient.session [req-f4138fb1-e5e2-4295-a112-140ab2e989de admin admin] RESP: [200] Content-Length: 4844 X-Subject-Token {SHA1}aa2a4d09ac49a888ebc65eedb5a8e827427a133d Vary: X-Auth-Token Keep-Alive: timeout=5, max=100 Server: Apache/2.4.16 (Fedora) OpenSSL/1.0.1k-fips mod_wsgi/4.4.8 Python/2.7.10 Connection: Keep-Alive Date: Wed, 28 Oct 2015 18:34:49 GMT Content-Type: application/json x-openstack-request-id: req-f3c0a468-f9ca-4946-ab48-5256bcde53db RESP BODY: {"token": {"methods": ["password", "token"], "roles": [{"id": "e316ece62e834dd5a413224b8052ba9d", "name": "admin"}], "expires_at": "2015-10-28T19:34:49.000000Z", "project": {"domain": {"id": "default", "name": "Default"}, "id": "07e3db7cc3104b4e829affd65b64af53", "name": "admin"}, "catalog": "<removed>", "extras": {}, "user {"domain": {"id": "default", "name": "Default"}, "id": "630c0267189a4561a5510c69d01ee6d5", "name": "admin"}, "audit_ids": ["AmilqPT8Q824gmqHKcop_A"], "issued_at": "2015-10-28T18:34:49.429373"}} from (pid=13455) _http_log_response /usr/lib/python2.7/site-packages/keystoneclient/session.py:216

2015-10-28 18:34:49.612 DEBUG nova.api.openstack.wsgi [req-6472b1de-987b-4b79-bb95-5be9c6e4ab08 admin admin] Calling method '<bound method VersionsController.show of <nova.api.openstack.compute.versionsV21.VersionsController object at 0x7fd35fcf4950>>' from (pid=13455) _process_stack /opt/stack/nova/nova/api/openstack/wsgi.py:792

2015-10-28 18:34:49.617 INFO nova.osapi_compute.wsgi.server [req-6472b1de-987b-4b79 bb95-5be9c6e4ab08 admin admin] 192.168.122.8 "GET /v2.1/ HTTP/1.1" status: 200 len: 655 time: 0.1636190

2015-10-28 18:34:49.790 DEBUG nova.api.openstack.wsgi [req-fa04ea9e-2715-4f20-80a2-ba2e69e526cb admin admin] Calling method '<bound method FlavorsController.show of <nova.api.openstack.compute.flavors.FlavorsController object at 0x7fd35fef68d0>>' from (pid=13455) _process_stack /opt/stack/nova/nova/api/openstack/wsgi.py:792

2015-10-28 18:34:49.824 INFO nova.osapi_compute.wsgi.server [req-fa04ea9e-2715-4f20-80a2-ba2e69e526cb admin admin] 192.168.122.8 "GET /v2.1/07e3db7cc3104b4e829affd65b64af53/flavors/Diana HTTP/1.1" status: 200 len: 706 time: 0.0388250

2015-10-28 18:34:49.833 DEBUG nova.api.openstack.wsgi [req-65de2575-15aa-442e-bc45-3ca9729f4c8c admin admin] Calling method '<bound method FlavorManageController._delete of <nova.api.openstack.compute.flavor_manage.FlavorManageController object at 0x7fd35fc3aa50>>' from (pid=13455) _process_stack /opt/stack/nova/nova/api/openstack/wsgi.py:792

2015-10-28 18:34:49.939 INFO nova.osapi_compute.wsgi.server [req-65de2575-15aa-442e-bc45-3ca9729f4c8c admin admin] 192.168.122.8 "DELETE /v2.1/07e3db7cc3104b4e829affd65b64af53/flavors/Diana HTTP/1.1" status: 202 len: 272 time: 0.1139250
  • FINALLY! I can reproduce this: devstack stable/kilo (and not master), case-sensitivity issue of some kind, not at all related to permissions:
[diana@localhost devstack]$ nova flavor-create Capitalized Capitalized 31024 10 2
+-------------+-------------+-----------+------+-----------+------+-------+-------------+-----------+
| ID          | Name        | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+-------------+-------------+-----------+------+-----------+------+-------+-------------+-----------+
| Capitalized | Capitalized | 31024     | 10   | 0         |      | 2     | 1.0         | True      |
+-------------+-------------+-----------+------+-----------+------+-------+-------------+-----------+
[diana@localhost devstack]$ nova flavor-delete Capitalized
ERROR (BadRequest): The server could not comply with the request since it is either malformed or otherwise incorrect. (HTTP 400) (Request-ID: req-56aaa760-5f9a-4c0b-983e-cd8ec6b6c489)
[diana@localhost devstack]$ nova flavor-create lowercase lowercase 31024 10 2
+-----------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID        | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+-----------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| lowercase | lowercase | 31024     | 10   | 0         |      | 2     | 1.0         | True      |
+-----------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
[diana@localhost devstack]$ nova flavor-delete lowercase
+-----------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID        | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+-----------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| lowercase | lowercase | 31024     | 10   | 0         |      | 2     | 1.0         | True      |
+-----------+-----------+-----------+------+-----------+------+-------+-------------+-----------+
2015-10-28 20:01:44.433 ERROR nova.api.openstack.wsgi [req-56aaa760-5f9a-4c0b-983e-cd8ec6b6c489 admin admin]
 Exception handling resource: 'NoneType' object has no attribute '__getitem__'
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi Traceback (most recent call last):
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi   File "/opt/stack/nova/nova/api/openstack/wsgi.py", l
ine 710, in post_process_extensions
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi     **action_args)
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi   File "/opt/stack/nova/nova/api/openstack/compute/con
trib/flavor_access.py", line 90, in show
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi     self._extend_flavor(resp_obj.obj['flavor'], db_fla
vor)
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi   File "/opt/stack/nova/nova/api/openstack/compute/con
trib/flavor_access.py", line 82, in _extend_flavor
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi     flavor_rval[key] = flavor_ref['is_public']
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi TypeError: 'NoneType' object has no attribute '__getit
em__'
2015-10-28 20:01:44.433 TRACE nova.api.openstack.wsgi 
2015-10-28 20:02:14.856 INFO sqlalchemy.engine.base.Engine [req-046f1803-8f1e-4a75-98ba-75ec1b7ef32a admin admin] SELECT instance_types.created_at AS instance_types_created_at, instance_types.updated_at AS instance_types_updated_at, instance_types.deleted_at AS instance_types_deleted_at, instance_types.deleted AS instance_types_deleted, instance_types.id AS instance_types_id, instance_types.name AS instance_types_name, instance_types.memory_mb AS instance_types_memory_mb, instance_types.vcpus AS instance_types_vcpus, instance_types.root_gb AS instance_types_root_gb, instance_types.ephemeral_gb AS instance_types_ephemeral_gb, instance_types.flavorid AS instance_types_flavorid, instance_types.swap AS instance_types_swap, instance_types.rxtx_factor AS instance_types_rxtx_factor, instance_types.vcpu_weight AS instance_types_vcpu_weight, instance_types.disabled AS instance_types_disabled, instance_types.is_public AS instance_types_is_public 
FROM instance_types 
ce_types_root_gb AS anon_1_instance_types_root_gb, anon_1.instance_types_ephemeral_gb AS anon_1_instance_typ
es_ephemeral_gb, anon_1.instance_types_flavorid AS anon_1_instance_types_flavorid, anon_1.instance_types_swa
p AS anon_1_instance_types_swap, anon_1.instance_types_rxtx_factor AS anon_1_instance_types_rxtx_factor, ano
n_1.instance_types_vcpu_weight AS anon_1_instance_types_vcpu_weight, anon_1.instance_types_disabled AS anon_
1_instance_types_disabled, anon_1.instance_types_is_public AS anon_1_instance_types_is_public, instance_type
_extra_specs_1.created_at AS instance_type_extra_specs_1_created_at, instance_type_extra_specs_1.updated_at 
AS instance_type_extra_specs_1_updated_at, instance_type_extra_specs_1.deleted_at AS instance_type_extra_spe
cs_1_deleted_at, instance_type_extra_specs_1.deleted AS instance_type_extra_specs_1_deleted, instance_type_e
xtra_specs_1.id AS instance_type_extra_specs_1_id, instance_type_extra_specs_1.`key` AS instance_type_extra_
specs_1_key, instance_type_extra_specs_1.value AS instance_type_extra_specs_1_value, instance_type_extra_spe
cs_1.instance_type_id AS instance_type_extra_specs_1_instance_type_id 
FROM (SELECT instance_types.created_at AS instance_types_created_at, instance_types.updated_at AS instance_t
ypes_updated_at, instance_types.deleted_at AS instance_types_deleted_at, instance_types.deleted AS instance_
types_deleted, instance_types.id AS instance_types_id, instance_types.name AS instance_types_name, instance_
types.memory_mb AS instance_types_memory_mb, instance_types.vcpus AS instance_types_vcpus, instance_types.ro
ot_gb AS instance_types_root_gb, instance_types.ephemeral_gb AS instance_types_ephemeral_gb, instance_types.
flavorid AS instance_types_flavorid, instance_types.swap AS instance_types_swap, instance_types.rxtx_factor 
AS instance_types_rxtx_factor, instance_types.vcpu_weight AS instance_types_vcpu_weight, instance_types.disa
bled AS instance_types_disabled, instance_types.is_public AS instance_types_is_public 
FROM instance_types 
WHERE instance_types.flavorid = %s ORDER BY deleted ASC, id ASC 
 LIMIT %s) AS anon_1 LEFT OUTER JOIN instance_type_extra_specs AS instance_type_extra_specs_1 ON instance_ty
pe_extra_specs_1.instance_type_id = anon_1.instance_types_id AND instance_type_extra_specs_1.deleted = %s OR
DER BY deleted ASC, id ASC
2015-10-28 20:01:44.424 INFO sqlalchemy.engine.base.Engine [req-56aaa760-5f9a-4c0b-983e-cd8ec6b6c489 admin admin] ('capitalized', 1, 0)
⚠️ **GitHub.com Fallback** ⚠️