{
"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
}
}
$ 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",
- What do the various
policy.json
permissions mean?
- Revert the user's suggested policy change, and try this instead:
[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)