Openstack - 根据某些标准有选择地删除图像?

Openstack - Selectively deleting images based on some criteria?

我们正在使用 Packer 每晚创建 openstack 镜像。我们想保留我们创建的最后 5 个并自动删除其余的。 (理想情况下,只有在它们没有基于它们的实例 运行 时才删除它们,但如果不可能,则不加区别地删除它们是可以的)。

我一直在查看各种 Openstack API 的文档,但我似乎无法找到一种巧妙的方法来做到这一点。

我想的是 运行 nova image-list 并用 bash 解析它,但这似乎有点挑剔,而且当我们谈论自动删除。

bash 脚本看起来像这样:

交叉引用这个:

nova image-list | grep "CentOS-7-x86_64 " | cut -d'|' -f 2

有了这个:

nova list | grep "ACTIVE" | cut -d'|' -f 2 | while read -r line ; do nova show "$line" ; done

但是这已经非常笨拙了,它甚至还没有做任何事情....

我的问题是,有没有我错过的更好的方法?

谢谢。

我会使用 Python API 来解决这个问题,而不是尝试使用 CLI 工具来解决这个问题。下面是一些代码,可以让您获得必要的 keystone、nova 和 glance 客户端:

#!/usr/bin/python

import os

import keystoneclient.auth.identity as keystone_identity
import keystoneclient.session as keystone_session
import keystoneclient.client as keystone_client
import novaclient.client as nova_client
import glanceclient.client as glance_client

auth = keystone_identity.v2.Password(auth_url=os.environ['OS_AUTH_URL'],
                   username=os.environ['OS_USERNAME'],
                   password=os.environ['OS_PASSWORD'],
                   tenant_name=os.environ['OS_TENANT_NAME'])

# establish a keystone session
sess = keystone_session.Session(auth=auth)

# get a keystone client
kc = keystone_client.Client('2',
                            session=sess,
                            auth_url=sess.auth.auth_url)

# and authenticate it
kc.authenticate(token=sess.get_token(),
                project_id=sess.get_project_id(),
                tenant_id=sess.get_project_id())

# get a nova client
nc = nova_client.Client('2', session=sess)

# get a glance client
gc = glance_client.Client('2',
                          endpoint=kc.service_catalog.url_for(
                              service_type='image',
                              endpoint_type='publicURL'),
                          token=sess.get_token())

假设您有可用的图像,您将首先获得符合您条件的可用图像列表:

images = [img for img in gc.images.list()
          if 'CentOS-7-x86_64 'in img.name]

然后获取要删除的图片列表:

to_delete = images[5:]

然后获取正在使用的图像列表:

in_use = []
for server in nc.servers.list():
    in_use.append(server.image['id'])

然后删除所有未使用的内容:

for img in to_delete:
    if img['id'] not in in_use:
        gc.images.delete(img['id'])