Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
55cb9a9
Update gate jobs as per the 2025.1 cycle testing runtime
Oct 22, 2024
0db9a32
Remove default override for config options policy_file
Nov 11, 2024
99d93c8
reno: Update master for unmaintained/2023.1
openstackadmin Nov 13, 2024
768c671
Merge "Remove default override for config options policy_file"
Nov 22, 2024
896ef7f
Merge "Update gate jobs as per the 2025.1 cycle testing runtime"
Dec 2, 2024
5df5277
Replace deprecated datetime.utcnow()
takanattie Sep 28, 2024
7ed419f
Support Nova ephemeral disks in flavor-based reservations
Dec 6, 2024
92cba0c
Add secure RBAC role as new default
Jan 29, 2025
762dacb
Merge "Replace deprecated datetime.utcnow()"
Feb 6, 2025
dbdf1b8
Fix host randomization
Mark-Powers Feb 17, 2025
199f69b
Update master for stable/2025.1
openstackadmin Mar 13, 2025
2fc005e
Remove unnecessary +x mode
kajinamit Apr 16, 2025
5123462
Fix lease date
thomasgoirand May 12, 2025
3ccbf2e
Add wsgi module to blazar
priteau May 13, 2025
f00448f
Fix JSON api examples
winiciusallan May 16, 2025
dc106c7
Merge "Fix lease date"
May 22, 2025
d91fac6
Merge "Support Nova ephemeral disks in flavor-based reservations"
Jun 12, 2025
3b235ba
Remove support for Python 3.8 and 3.9
priteau Jun 12, 2025
db0680a
Remove Jammy job
gmaanos Jun 12, 2025
e5832f2
Merge "Remove support for Python 3.8 and 3.9"
Jun 26, 2025
c2ced40
sqlalchemy: Use built-in declarative
kajinamit Jun 30, 2025
71455b3
Merge "sqlalchemy: Use built-in declarative"
Jul 10, 2025
e407e8d
Fix owner policy enforcement
MoteHue Aug 14, 2025
7524403
Drop description for ZeroMQ
kajinamit Aug 24, 2025
e15db25
Merge "Drop description for ZeroMQ"
Aug 26, 2025
85d6566
Update master for stable/2025.2
openstackadmin Sep 11, 2025
a96d93e
Remove url tags from README
anfimovir Sep 13, 2025
5a9baa5
tox: Drop basepython
anfimovir Sep 13, 2025
e65316e
reno: Update master for unmaintained/2024.1
openstackadmin Oct 31, 2025
8b9332b
Merge "tox: Drop basepython"
Nov 13, 2025
1c175fe
feat(blazar): Extending the payload of a notification, to send the en…
nitin2989 Oct 31, 2025
3e7cf24
Remove pylint
anfimovir Jan 8, 2026
48d3239
Fix updating amount in active instance leases
MoteHue Jan 14, 2026
b1cab52
Add flavor-based reservations to API reference
MoteHue Jan 15, 2026
068a3c5
Remove note about old pip's behavior
kajinamit Jan 22, 2026
929ecf5
Add support for Python 3.13
anfimovir Jan 8, 2026
174d2e8
Merge "Add support for Python 3.13"
Jan 26, 2026
23338c3
Merge "Fix updating amount in active instance leases"
Jan 26, 2026
cbb8776
Add support for traits in flavor plugin
Mark-Powers Jul 18, 2025
92d7cbb
Merge "Add flavor-based reservations to API reference"
Feb 5, 2026
125f5f7
Merge "Add support for traits in flavor plugin"
Feb 5, 2026
bca58dd
Remove MANIFEST.in
kajinamit Feb 7, 2026
084a678
Raise exception in updating flavor:instance leases
MoteHue Jan 15, 2026
5ffbc85
Merge "Raise exception in updating flavor:instance leases"
Mar 5, 2026
78eb2a7
Update master for stable/2026.1
openstackadmin Mar 11, 2026
a87b537
Merge branch 'stackhpc/master' into upstream/master-2026-06-03
Alex-Welsh Jun 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions MANIFEST.in

This file was deleted.

9 changes: 3 additions & 6 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
Team and repository tags
========================
======
Blazar
======

.. image:: https://governance.openstack.org/tc/badges/blazar.svg
:target: https://governance.openstack.org/tc/reference/tags/index.html

.. Change things from this point on

Blazar
======

Blazar is a resource reservation service for OpenStack. Blazar enables users
to reserve a specific type/amount of resources for a specific time period and
it leases these resources to users based on their reservations.
Expand Down
73 changes: 73 additions & 0 deletions api-ref/source/v1/leases.inc
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ Parameters for Instance Reservation
The following parameters are returned for instance reservation. All parameters
are in the ``reservation`` object.

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
- reservation.vcpus: reservation_vcpus
- reservation.memory_mb: reservation_memory_mb
- reservation.disk_gb: reservation_disk_gb
- reservation.affinity : reservation_affinity
- reservation.resource_properties: reservation_resource_properties
- reservation.flavor_id: reservation_flavor_id
- reservation.server_group_id: reservation_server_group_id
- reservation.aggregate_id: reservation_aggregate_id

Parameters for Flavor-based Instance Reservation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following parameters are returned for flavor-based instance reservation.
All parameters are in the ``reservation`` object.

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
Expand Down Expand Up @@ -161,6 +179,19 @@ are in the ``reservation`` object.
- reservation.affinity : reservation_affinity
- reservation.resource_properties: reservation_resource_properties

Parameters for Flavor-based Instance Reservation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The following parameters are required for flavor-based instance reservation.
All parameters are in the ``reservation`` object.

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
- reservation.flavor_id: reservation_flavor_id
- reservation.affinity : reservation_affinity
- reservation.resource_properties: reservation_resource_properties

**Example of Create Lease Request**

.. literalinclude:: ../../../doc/api_samples/leases/lease-create-req.json
Expand Down Expand Up @@ -225,6 +256,21 @@ Parameters for Instance Reservation
The following parameters are returned for instance reservation. All parameters
are in the ``reservation`` object.

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
- reservation.vcpus: reservation_vcpus
- reservation.memory_mb: reservation_memory_mb
- reservation.disk_gb: reservation_disk_gb
- reservation.affinity : reservation_affinity
- reservation.resource_properties: reservation_resource_properties
- reservation.flavor_id: reservation_flavor_id
- reservation.server_group_id: reservation_server_group_id
- reservation.aggregate_id: reservation_aggregate_id

Parameters for Flavor-based Instance Reservation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
Expand Down Expand Up @@ -326,6 +372,21 @@ Parameters for Instance Reservation
The following parameters are returned for instance reservation. All parameters
are in the ``reservation`` object.

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
- reservation.vcpus: reservation_vcpus
- reservation.memory_mb: reservation_memory_mb
- reservation.disk_gb: reservation_disk_gb
- reservation.affinity : reservation_affinity
- reservation.resource_properties: reservation_resource_properties
- reservation.flavor_id: reservation_flavor_id
- reservation.server_group_id: reservation_server_group_id
- reservation.aggregate_id: reservation_aggregate_id

Parameters for Flavor-based Instance Reservation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. rest_parameters:: parameters.yaml

- reservation.amount: reservation_amount
Expand Down Expand Up @@ -406,6 +467,12 @@ are in the ``reservation`` object.
- reservation.affinity : reservation_affinity_optional
- reservation.resource_properties: reservation_resource_properties_optional

Parameters for Flavor-based Instance Reservation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Lease updates are not currently supported for flavor-based instance
reservations.

**Example of Update Lease Request**

.. literalinclude:: ../../../doc/api_samples/leases/lease-update-req.json
Expand Down Expand Up @@ -482,6 +549,12 @@ are in the ``reservation`` object.
- reservation.server_group_id: reservation_server_group_id
- reservation.aggregate_id: reservation_aggregate_id

Parameters for Flavor-based Instance Reservation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Lease updates are not currently supported for flavor-based instance
reservations.

**Example of Update Lease Response**

.. literalinclude:: ../../../doc/api_samples/leases/lease-update-resp.json
Expand Down
20 changes: 1 addition & 19 deletions blazar/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,14 @@

from oslo_config import cfg
from oslo_log import log as logging
from oslo_policy import opts


cli_opts = [
cfg.HostAddressOpt('host', default='0.0.0.0',
help='Name of this node. This can be an opaque '
'identifier. It is not necessarily a hostname, '
'FQDN, or IP address. However, the node name must '
'be valid within an AMQP key, and if using '
'ZeroMQ (will be removed in the Stein release), a '
'valid hostname, FQDN, or IP address'),
'be valid within an AMQP key.'),
cfg.BoolOpt('log_exchange', default=False,
help='Log request/response exchange details: environ, '
'headers and bodies'),
Expand Down Expand Up @@ -91,18 +88,3 @@
CONF.register_opts(api_opts)
CONF.register_opts(lease_opts)
logging.register_options(cfg.CONF)


def set_lib_defaults():
"""Update default value for configuration options from other namespace.

Example, oslo lib config options. This is needed for
config generator tool to pick these default value changes.
https://docs.openstack.org/oslo.config/latest/cli/
generator.html#modifying-defaults-from-other-namespaces
"""

# TODO(gmann): Remove setting the default value of config policy_file
# once oslo_policy change the default value to 'policy.yaml'.
# https://github.com/openstack/oslo.policy/blob/a626ad12fe5a3abd49d70e3e5b95589d279ab578/oslo_policy/opts.py#L49
opts.set_defaults(CONF, 'policy.yaml')
Empty file.
4 changes: 2 additions & 2 deletions blazar/db/sqlalchemy/model_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
# limitations under the License.

from oslo_db.sqlalchemy import models
from sqlalchemy.ext import declarative
from sqlalchemy.orm import attributes
from sqlalchemy.orm import declarative_base


class _BlazarBase(models.ModelBase, models.TimestampMixin):
Expand Down Expand Up @@ -49,4 +49,4 @@ def datetime_to_str(dct, attr_name):
dct[attr_name] = dct[attr_name].isoformat(' ')


BlazarBase = declarative.declarative_base(cls=_BlazarBase)
BlazarBase = declarative_base(cls=_BlazarBase)
17 changes: 14 additions & 3 deletions blazar/manager/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from oslo_config import cfg
from oslo_log import log as logging
from oslo_utils.excutils import save_and_reraise_exception
from oslo_utils import timeutils
from stevedore import enabled

from blazar import context
Expand Down Expand Up @@ -236,7 +237,7 @@ def _process_events(self):
sort_dir='asc',
filters={'status': status.event.UNDONE,
'time': {'op': 'le',
'border': datetime.datetime.utcnow()}}
'border': timeutils.utcnow()}}
)

for batch in self._select_for_execution(events):
Expand All @@ -252,7 +253,7 @@ def _exec_event(self, event):
try:
event_fn(lease_id=event['lease_id'], event_id=event['id'])
except common_ex.InvalidStatus:
now = datetime.datetime.utcnow()
now = timeutils.utcnow()
if now < event['time'] + datetime.timedelta(
seconds=CONF.manager.event_max_retries * 10):
# Set the event status UNDONE for retrying the event
Expand Down Expand Up @@ -284,7 +285,7 @@ def _date_from_string(self, date_string, date_format=LEASE_DATE_FORMAT):
return date

def _parse_lease_dates(self, start_date, end_date):
now = datetime.datetime.utcnow()
now = timeutils.utcnow()
now = datetime.datetime(now.year,
now.month,
now.day,
Expand Down Expand Up @@ -508,6 +509,13 @@ def _add_resource_type(self, reservations, existing_reservations):

return reservations

def _handle_resource_type_exception(self, lease):
for reservation in lease['reservations']:
if reservation['resource_type'] == 'flavor:instance':
raise exceptions.NotImplemented(
error="Updating leases for 'flavor:instance' type "
"reservations is not yet supported.")

@status.lease.lease_status(
transition=status.lease.UPDATING,
result_in=status.lease.STABLE,
Expand All @@ -534,6 +542,9 @@ def update_lease(self, lease_id, values):
return db_api.lease_get(lease_id)

lease = db_api.lease_get(lease_id)

self._handle_resource_type_exception(lease)

start_date = values.get(
'start_date',
datetime.datetime.strftime(lease['start_date'], LEASE_DATE_FORMAT))
Expand Down
10 changes: 9 additions & 1 deletion blazar/notification/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ def format_lease_payload(lease):
'lease_id': lease['id'],
'user_id': lease['user_id'],
'project_id': lease['project_id'],
'trust_id': lease['trust_id'],
'start_date': lease['start_date'],
'end_date': lease['end_date']
'end_date': lease['end_date'],
'status': lease['status'],
'reservations': lease['reservations'],
'events': lease['events'],
'name': lease.get('name'),
'created_at': lease.get('created_at'),
'updated_at': lease.get('updated_at'),
'degraded': lease.get('degraded')
}
35 changes: 35 additions & 0 deletions blazar/plugins/flavor/flavor_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,42 @@ def _query_available_hosts(self, start_date, end_date,
end_date + datetime.timedelta(minutes=CONF.cleaning_time),
[])

placement_rps_matching_traits = None
# Only query placement if we have traits to match
if resource_traits:
traits_list = []
for trait, value in resource_traits.items():
# We've already validated resource_traits at this point
if value == "required":
traits_list.append(trait)
elif value == "forbidden":
# prefix forbidden traits with `!`
traits_list.append(f"!{trait}")
required_string = ",".join(traits_list)
placement_rps_matching_traits = \
self._placement_client.list_resource_providers(
query=f"required={required_string}",
microversion="1.22",
)
placement_rps_matching_traits_hostnames = {
rp['name'] for rp in placement_rps_matching_traits
} if placement_rps_matching_traits else set()

available_hosts = []
for host_info in (reserved_hosts + free_hosts):
hypervisor_hostname = host_info['host']['hypervisor_hostname']
if (
resource_traits and
(
hypervisor_hostname
not in placement_rps_matching_traits_hostnames
)
):
LOG.debug(
"Placement filtered out host %s based on traits",
hypervisor_hostname
)
continue
# check how many instances can fit on this host
hosts_list = self._get_hosts_list(host_info, resource_request)
available_hosts.extend(hosts_list)
Expand Down Expand Up @@ -391,6 +425,7 @@ def _create_flavor(self, instance_reservation):
'vcpus': source_flavor['vcpus'],
'ram': source_flavor['ram'],
'disk': source_flavor['disk'],
'ephemeral': source_flavor.get('OS-FLV-EXT-DATA:ephemeral', 0),
'is_public': False
}
# create flavor using admin access
Expand Down
3 changes: 2 additions & 1 deletion blazar/plugins/floatingips/floatingip_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from oslo_utils.excutils import save_and_reraise_exception
from oslo_utils import netutils
from oslo_utils import strutils
from oslo_utils import timeutils

from blazar import context
from blazar.db import api as db_api
Expand Down Expand Up @@ -422,7 +423,7 @@ def query_fip_allocations(self, fips, detail=None, lease_id=None,
]
}.
"""
start = datetime.datetime.utcnow()
start = timeutils.utcnow()
end = datetime.date.max

reservations = db_utils.get_reservation_allocations_by_fip_ids(
Expand Down
9 changes: 5 additions & 4 deletions blazar/plugins/instances/instance_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from oslo_log import log as logging
from oslo_utils import strutils
from oslo_utils.strutils import bool_from_string
from oslo_utils import timeutils

from blazar import context
from blazar.db import api as db_api
Expand Down Expand Up @@ -167,7 +168,7 @@ def query_allocations(self, hosts, lease_id=None, reservation_id=None):
]
}.
"""
start = datetime.datetime.utcnow()
start = timeutils.utcnow()
end = datetime.date.max

# To reduce overhead, this method only executes one query
Expand Down Expand Up @@ -549,7 +550,8 @@ def update_reservation(self, reservation_id, new_values):
return

if (reservation['status'] == 'active' and
any([k in updatable[:-1] for k in new_values.keys()])):
any([k in updatable for k in new_values.keys()
if k != 'amount'])):
msg = "An active reservation only accepts to update amount."
raise mgr_exceptions.InvalidStateUpdate(msg)

Expand Down Expand Up @@ -770,8 +772,7 @@ def _heal_reservation(self, reservation, host_ids):
def _select_host(self, reservation, lease):
"""Returns the alternative host id or None if not found."""
values = {}
values['start_date'] = max(datetime.datetime.utcnow(),
lease['start_date'])
values['start_date'] = max(timeutils.utcnow(), lease['start_date'])
values['end_date'] = lease['end_date']
specs = ['vcpus', 'memory_mb', 'disk_gb', 'affinity', 'amount',
'resource_properties']
Expand Down
Loading
Loading