# Glance: the OpenStack service that stores and serves virtual machine images

> Glance is the OpenStack Image Service, the component that stores, browses, shares and distributes bootable disk images along with their metadata. It is an Apache-2.0 licensed Python service built on the Oslo libraries, with a pluggable flow system for imports, a policy enforcer, a cache and a set of optional configuration namespaces.

**openstack/glance** — OpenStack Image Management (Glance). Mirror of code maintained at opendev.org.

- Repository: https://github.com/openstack/glance
- Website: https://opendev.org/openstack/glance
- Stars: 534 · Forks: 529
- Language: Python
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/openstack-glance

## What the service is responsible for

Glance is an OpenStack project that provides services and associated libraries to store, browse, share, distribute and manage bootable disk images, other data closely associated with initializing compute resources, and metadata definitions. That sentence is the whole scope, and it is worth reading closely because the third element is often forgotten. An image service does not only hold disk images, it also holds the data needed to initialise a compute resource and the definitions of metadata properties, so the service is a catalogue as much as a blob store. The repository here is a mirror of the code maintained at opendev.org, which is the standard arrangement for the OpenStack projects, since the authoritative home is the Gerrit instance on opendev and the GitHub copy is there for convenience and for issue and pull request traffic. The primary language is Python, the licence is Apache-2.0, the project is not archived, and the last push to the repository was on 2026-10-15. There are no GitHub releases, which is consistent with the OpenStack release process where versions are cut as tagged branches and the release notes live in a separate site rather than in GitHub releases.

## The four audiences the README addresses

The README is organised by audience rather than by topic, which is a good sign for a service with more than one kind of reader. The API section points at the Image Service API reference hosted on the OpenStack documentation site, which is where a consumer of the REST interface should start. The developers section points at the CONTRIBUTING.rst file in the repository for how to contribute, states that any new code must follow the development guidelines detailed in HACKING.rst, and must pass all unit tests, then links the official Glance documentation and the official client documentation. That last pair is worth separating, because the service and the client are different things with different documentation and different release cadences, and a reader looking for how to call Glance from Python wants the second one. The operators section points at the same main documentation for deployment and configuration, and gives the bug tracker for raising bugs. The release notes section points at the release notes site for new features, optimisations and changes between versions. The last section explains the planning process, saying that during each design summit the community agrees on what to focus on for the upcoming release, with the image service plans published as specs. That is a useful thing to know, because it tells you where a Glance feature request actually has to go to have any chance.

## Configuration is delivered through the Oslo config entry points

The packaging manifest shows how the service exposes its configuration, and the mechanism is the Oslo config plugin system rather than a bespoke config file parser. The project registers several option groups through the oslo.config.opts entry point, with separate namespaces for the API, the scrubber, the cache, the manage command and the image import.

```toml
[project.entry-points."oslo.config.opts"]
"glance.api"  = "glance.opts:list_api_opts"
"glance.scrubber" = "glance.opts:list_scrubber_opts"
"glance.cache" = "glance.opts:list_cache_opts"
"glance.manage" = "glance.opts:list_manage_opts"
"glance" = "glance.opts:list_image_import_opts"
```

There is also a defaults entry point that supplies the default values for the API namespace specifically, and the naming makes the design clear. Each option group has a list function, and the service reads them at startup, so an operator's configuration file is assembled from several independent groups rather than one flat file. The practical effect is that a deployment can enable only the pieces it needs. The scrubber is the one worth understanding, since scrubbing is the periodic removal of expired and pending image records rather than the deletion of the image data itself, and it is configured on its own schedule with its own options, which is the right design for a background task that can run at a different cadence from the API. The cache group is likewise separate, and the manage group covers the administrative command, and the image import group covers importing images, which is a separate operation from uploading them.

## Imports run through a pluggable flow system

The most interesting entry point in the manifest is the glance.flows group, which registers the import workflows by name.

```toml
[project.entry-points."glance.flows"]
api_image_import = "glance.async_.flows.api_image_import:get_flow"
import = "glance.async_.flows.base_import:get_flow"
location_import = "glance.async_.flows.location_import:get_flow"
```

So there are three import flows, and the names describe the shape of each. A location import fetches an image from a URL or a location, an import is the base flow, and an API image import is the one triggered through the service interface. The fact that these are separate entry points means a new import path can be added by a deployment or a downstream project without patching the core, which is the point of the flow abstraction. The dependency list shows what the flows are built on, with taskflow at 4.0.0 or newer providing the generic flow engine and oslo.concurrency, oslo.context and oslo.messaging providing the surrounding infrastructure for running work in the background and reporting on it. The word asynchronous in the module path is the giveaway, since the flows live under an asynchronous package, which matches the fact that importing an image from a slow remote location is a long operation that should not hold an API request open. The policy enforcer is registered the same way, through an entry point that returns the enforcer and one that lists the rules.

```toml
[project.entry-points."oslo.policy.enforcer"]
glance = "glance.api.policy:get_enforcer"

[project.entry-points."oslo.policy.policies"]
glance = "glance.policies:list_rules"
```

That pair is how authorisation works in an OpenStack service, with the policy rules loaded by name rather than hard coded, so an operator can override them in their own policy file without editing Glance.

## The dependency list tells you what the service is built on

The requirements file is a good map of the architecture, and it is annotated with each dependency's licence, which is the kind of care a project with a legal review process shows. The web stack is PasteDeploy, Routes and WebOb, which is the classic Paste Deploy stack of a WSGI application with a routes based URL dispatcher, and Paste is there as the server. The data layer is SQLAlchemy at 1.3.14 or newer with alembic for schema migrations, and the oslo.db wrapper on top. The service API is WSME, the web service markup engine, which gives the REST interface its declarative typing, with jsonschema for validation, httplib2 and requests for outbound calls, defusedxml for parsing untrusted XML, and PrettyTable for formatted console output in the administrative command. The identity side is keystoneauth1 for talking to Keystone, python-keystoneclient, and keystonemiddleware so that the service sits behind the standard authentication and authorisation pipeline. The messaging and reporting layer is oslo.messaging, oslo.reports and oslo.log, with osprofiler for tracing, which is how a request can be followed through the service when something is slow. The image storage is glance-store at 5.3.0 or newer, separated out as its own project so the storage backends can change without the service changing. The configuration and utility libraries are the usual Oslo set, oslo.config, oslo.utils, oslo.i18n, oslo.context, oslo.upgradecheck, oslo.limit for rate limiting, oslo.middleware, oslo.concurrency, oslo.service with the threading extra and debtcollector for deprecation warnings. The cryptography package handles the signing of image locations, and castellan provides the key management integration, with cursive for terminal formatting and stevedore for the plugin loading that the entry points above depend on.

## Packaging and the shape of the repository

The build is deliberately conventional, and the manifest says so explicitly. The build system requires pbr at 6.1.1 or newer with pbr.build as the backend, and the setup.py file is a thin shim that sets setup_requires and turns on pbr, so the real metadata lives in the pyproject.toml rather than in the setup file, and the setup file itself is a thin shim.

```python
import setuptools

setuptools.setup(
    setup_requires=['pbr>=2.0.0'],
    pbr=True)
``` The project metadata names the distribution glance with the description OpenStack Image Service, lists OpenStack as the author with the openstack-discuss mailing list as the contact, declares the Apache-2.0 licence, and marks both the version and the dependencies as dynamic, which is the pbr convention of deriving them from git tags and the requirements files. The development status classifier says Production/Stable, the operating system is POSIX Linux, and the Python classifiers cover 3.11, 3.12, 3.13 and 3.14, with requires-python set to 3.11 or newer. The repository layout follows the usual OpenStack arrangement, with the api-ref/ directory holding the API specification source, the doc/ directory for the project documentation, etc/ for configuration templates, glance/ for the package itself, httpd/ for the WSGI application, playbooks/ for deployment automation, releasenotes/ for the release notes that are rendered on the site, rally-jobs/ for performance benchmarking, tools/ for development scripts, and test-requirements.txt, tox.ini and .stestr.conf for the test harness. The .zuul.yaml file is the gate configuration for the continuous integration jobs, and .gitreview tells you where to push changes, which for an OpenStack project is a Gerrit review rather than a pull request.

## Where Glance is the wrong choice

The first limit is scope, and it is the limit that decides most evaluations. This is an image service for a cloud, with a catalogue of metadata definitions, a policy system, a background scrubber and asynchronous import flows, and if your problem is keeping a hundred disk images in a bucket then all of that is overhead, because an object store with a small database in front of it will do the job for a fraction of the effort. The second is the operational weight that comes with the OpenStack umbrella, since a Glance deployment means Keystone for identity, the Oslo libraries for configuration and messaging, a SQL database with alembic migrations, and typically a shared message bus for the asynchronous flows, and each of those is something to run and upgrade. The third is the policy model, which is powerful and indirect, since authorisation is a set of rules loaded by name and overridable by an operator, and the cost of that flexibility is that reasoning about who can do what requires reading a policy file rather than reading code. The fourth is the dependency floor, since the package requires Python 3.11 or newer and tests against four interpreter versions, and a deployment on an older distribution release is not a supported configuration. The fifth is the split between the service and its parts, since the storage backends live in a separate glance-store project and the Python client lives in another, and a change in one of them can affect the behaviour of the others without any change to this repository.

## Conclusion

Adopt Glance if you run OpenStack and need an image service, since it is the standard component for that job and it exposes a documented REST API and a separate client library. Skip it if you only need somewhere to keep a handful of disk images, since a plain object store will do. Verify first which Python versions your deployment targets, since the package requires 3.11 or newer and is tested against 3.11 through 3.14, and which configuration namespaces your installation actually uses, since the service exposes a set of separate option groups that are each optional in effect.

## FAQ

### What does the OpenStack Glance service do?

Glance is an OpenStack project that provides services and associated libraries to store, browse, share, distribute and manage bootable disk images, other data closely associated with initializing compute resources, and metadata definitions. It is also the standard place where OpenStack images are catalogued, and the REST interface is documented separately as the Image Service API.

### How is Glance configured, and what are the separate option groups for?

Configuration is registered through the Oslo config plugin system, with separate entry point namespaces for the API, the scrubber, the cache, the manage command and the image import, and a defaults entry point that supplies the API defaults. The scrubber in particular is configured on its own schedule, which suits a background task that removes expired and pending image records on a different cadence from the API.

### How do image imports and authorisation work in Glance?

Imports run through pluggable flows registered under the glance.flows entry point, with separate flows for an API triggered import, a base import and a location import that fetches from a URL or location. Authorisation is handled through Oslo policy, with the enforcer and the rule list registered as entry points, so an operator can override the rules in their own policy file without modifying Glance itself.

## Sources

- [Issues](https://github.com/openstack/glance/issues)
- [License: Apache-2.0](https://github.com/openstack/glance/blob/master/LICENSE)
- [openstack/glance on GitHub](https://github.com/openstack/glance)
- [Project website](https://opendev.org/openstack/glance)
- [README](https://github.com/openstack/glance/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/openstack-glance
