OpenStack: server (VM)

Get VM data

openstack server show -c name -c id -c addresses -c OS-EXT-SRV-ATTR:host ${SERVER_ID}
nova interface-list ${SERVER_ID}
nova migration-list --instance-uuid ${SERVER_ID} | grep -v "2019-"

Create VM
https://docs.openstack.org/python-openstackclient/latest/cli/command-objects/server.html#server-create

openstack server create u2204-vm1 \
  --image "Ubuntu 22.04" \
  --flavor m1.small \
  --key-name foo-key \
  --network foo-net \
  --security-group default \
  --availability-zone=eu1-az1

CLI

# Delete instance
openstack server delete ${SERVER_ID}
 
# list all servers from all projects
openstack server list --all-projects
 
# search VM by IP wildcard
openstack server list --ip 10.0.10 [--all-projects]
 
# get IDs only from server
openstack server list -c ID -f value
 
# get all servers using windows images
for IMAGE in $(openstack image list --long --os-cloud=prod-admin -c ID -c Name -f value | grep -i "Windows" | cut -d" " -f 1); do
    openstack server list --long --all-projects --os-cloud=prod-admin --image ${IMAGE} 
done
 
# Add floating IP
openstack server add floating ip ${SERVER_ID} \
  $(openstack floating ip create public -c floating_ip_address -f value)
 
# resize
openstack server resize ...
openstack server resize --confirm ${SERVER_ID}
 
# attach port to VM
openstack server add port VM1 NET1-PORT1
 
# list instances / server
openstack server list
openstack console log show foo-vm1
 
# get hypervisor
openstack server list
ssh compute1 ps axf | grep ${SERVER_ID}
 
# Show console URL
openstack console url show ${SERVER_ID}
 
# Reboot
openstack server reboot --hard  ${SERVER_ID}
 
# get server ports
nova interface-list  ${SERVER_ID}
 
# set VM properties
openstack server set --property "sysadmin=foo" --property "os=Ubuntu" ${SERVER_ID}
 
# remove VM property
openstack server unset --property os ${SERVER_ID}
 
# Update / fix server status
openstack server set --state active ${SEVER_ID}
openstack server show -c id -c name -c status -c OS-EXT-SRV-ATTR:hypervisor_hostname ${SEVER_ID}
 
# allow SSH incomming access
SECURITY_GROUP_ID=$(openstack server show -c security_groups -f value ${SERVER_ID}  | cut -d "'" -f2)
openstack security group rule create --protocol tcp --dst-port 22:22 --remote-ip 0.0.0.0/0  ${SECURITY_GROUP_ID}
 
# allow HTTP(s) incomming access
SERVER_NAME=vm1
PROJECT_ID=$(openstack server show ${SERVER_NAME} -c project_id -f value)
SECURITY_GROUP_ID=$(openstack security group list --project ${PROJECT_ID} -c ID -f value)
openstack security group rule create --protocol tcp --dst-port 80:80 --remote-ip 0.0.0.0/0  ${SECURITY_GROUP_ID}
openstack security group rule create --protocol tcp --dst-port 443:443 --remote-ip 0.0.0.0/0 ${SECURITY_GROUP_ID}
 
# rename VM
openstack server set --name vm1-old ${SERVER_ID}
 
# connect to SSH (by floating IP)
openstack server ssh --login ubuntu --public ${SERVER_ID}

Snapshot and restore
https://clouddocs.web.cern.ch/using_openstack/backups.html

# backup
openstack server image create --name vm1-snap1 vm1
openstack image list
openstack server rebuild --image vm1-snap1 vm1
openstack server show vm1 -c name -c status
 
# restore
openstack server rebuild --image ab317678-638d-481e-9249-831d68d854d5 vm1

Install qemu-guest-agent (run inside of a VM)
https://www.sebastien-han.fr/blog/2015/02/09/openstack-perform-consistent-snapshots-with-qemu-guest-agent/

apt install -y qemu-guest-agent
# hw_qemu_guest_agent=yes

Get instance meta data
https://docs.openstack.org/nova/latest/user/metadata.html

curl http://169.254.169.254/openstack/latest/meta_data.json | jq
curl http://169.254.169.254/openstack/latest/network_data.json | jq
 
# get flavor
curl http://169.254.169.254/latest/meta-data/instance-type
 
# get security-groups
curl http://169.254.169.254/latest/meta-data/security-groups
 
# get availability-zone
curl http://169.254.169.254/latest/meta-data/placement/availability-zone

List VMs

# list VMs and  tenants
nova list --all-tenants
nova list --all-tenants --fields tenant_id
 
openstack server list --all --long --sort-column Name -f json
openstack server list --all --long --sort-column Name --name foo
 
# show all deleted VMs
openstack server list --deleted --all

Fix task_state "powering-on"

for SERVER_ID in $(openstack server list --all -c ID -f value); do
    openstack server show ${SERVER_ID} -c id -c OS-EXT-STS:task_state -f value | paste - - | grep -v None
done
 
openstack server set --state active ${SERVER_ID}
openstack server reboot ${SERVER_ID} [--hard]https://docs.openstack.org/cinder/latest/cli/cli-manage-volumes.html
openstack console url show ${SERVER_ID}

search for VM on all compute nodes

SERVER_ID=xxxx-xxxx-xxxx-xxxx
for NODE in $(openstack compute service list --service nova-compute -c Host -f value); do
    echo ${NODE}
    ssh ${NODE} ps axf | grep ${SERVER_ID}
    ssh ${NODE} docker exec -i nova_libvirt virsh dominfo ${SERVER_ID}
done

Event

# list events
openstack server event list ${SERVER_ID}
 
# server event show
openstack server event show ${SERVER_ID} ${REQUEST_ID}

Get server / tanent data

SERVER_IDS="
07111f96-c752-4faa-b9dd-1ec962c7b6dc
b41c7bfb-0411-48c9-b133-6ee95c4dc20e
894abf55-2257-469f-b102-987a90342abe
"
 
for SERVER_ID in ${SERVER_IDS}; do
    SERVER_JSON=$(openstack server show ${SERVER_ID} -f json)
    SERVER_NAME=$(echo ${SERVER_JSON} | jq -r .name)
 
    PROJECT_ID=$(echo ${SERVER_JSON} | jq -r .project_id)
    PROJECT_JSON=$(openstack project show ${PROJECT_ID} -f json)
    PROJECT_NAME=$(echo ${PROJECT_JSON} | jq -r .name)
 
    DOMAIN_ID=$(echo ${PROJECT_JSON} | jq -r .domain_id)
    DOMAIN_JSON=$(openstack domain show ${DOMAIN_ID} -f json)
    DOMAIN_NAME=$(echo ${DOMAIN_JSON} | jq -r .name)
 
    echo "${SERVER_ID}  ${SERVER_NAME}  ${DOMAIN_NAME}  ${PROJECT_NAME}"
done

Transfer VM
https://docs.openstack.org/cinder/latest/cli/cli-manage-volumes.html

openstack volume list --all-projects --name docs1-dev
openstack volume transfer request create  4aef794d-9f79-4d24-a220-211dc4863424

Fix "Cannot 'start' instance while it is in vm_state resized" / "Instance has not been resized."

openstack server list --all --status VERIFY_RESIZE
 
# openstack server start ${SERVER_ID}
Cannot 'start' instance af46d773-841f-4774-8bdd-29face6a3757 while it is in vm_state resized (HTTP 409) (Request-ID: req-ccb5d5a8-8a1a-427e-a55a-8f72e3d9216d)
 
# openstack server resize confirm ${SERVER_ID}
Instance has not been resized. (HTTP 400) (Request-ID: req-ccf5b1c4-c0bd-4778-b8e4-bd17845c4355)
 
openstack server set --state active ${SERVER_ID}
openstack server stop ${SERVER_ID}

Snippets

openstack server list --all-projects --name dummy -c ID -f value | xargs -L1 openstack server show -c project_id -f value | sort -u

List all soft-deleted VMs
https://raymii.org/s/articles/Openstack_Soft_Delete_-_recover_deleted_instances.html

# find SOFT_DELETED server as admin
openstack server list --deleted --all-projects --status SOFT_DELETED
 
# find SOFT_DELETED server (as unprivileged user)
PORT_IDS=$(openstack port list --long  -f json | jq -r '.[] | select(."Device Owner" | contains("compute")) .ID')
for PORT_ID in ${PORT_IDS}; do
    SERVER_ID=$(openstack port show ${PORT_ID} -c device_id -f value)
    SOFT_DELETED_SERVER_ID=$(openstack server show ${SERVER_ID} -f json | jq -r '. | select(.status == "SOFT_DELETED") .id')
    echo ${SOFT_DELETED_SERVER_ID}
 
    echo openstack server delete --force ${SOFT_DELETED_SERVER_ID}
done

Force remove volume attachment from nova

select * from nova.block_device_mapping where deleted_at is NULL and attachment_id is NOT NULL and volume_id = '${VOLUME_ID}'\G
 
BEGIN;
UPDATE nova.block_device_mapping SET deleted=id, deleted_at=NOW() WHERE id='${ID}' LIMIT 1;
COMMIT;
 
select * from cinder.volume_attachment where deleted <> '1' and volume_id = '${VOLUME_ID}'\G

List server volumes

SERVER_IDS="
bd23500a-494d-4916-87a6-4124b34f91d3
54aa5d05-d1fa-46c7-bd3d-885e5aaf3bd8
3b61c090-6ffd-4eb0-b7ba-f9b9a9629613
"
 
for SERVER_ID in ${SERVER_IDS}; do
    echo "SERVER_ID: ${SERVER_ID}"
 
    FLAVOR_ID=$(openstack server show ${SERVER_ID} -c flavor -f value | cut -d "(" -f2 | cut -d")" -f1)
    FLAVOR_DISK=$(openstack flavor show ${FLAVOR_ID} -c disk -f value)
    echo "FLAVOR_DISK: ${FLAVOR_DISK}"
 
    VOLUME_IDS=$(openstack server show ${SERVER_ID} -c volumes_attached -f json | jq -r .volumes_attached[].id)
    for VOLUME_IDS in ${VOLUME_IDS}; do
        VOLUME_SIZE=$(openstack volume show ${VOLUME_IDS} -c size -f value)
        echo "VOLUME_SIZE: ${VOLUME_SIZE}"
    done
 
    echo 
done

Links
https://docs.openstack.org/python-openstackclient/latest/cli/command-objects/server.html