Page MenuHomePhabricator
Paste P52761

(An Untitled Masterwork)
ActivePublic

Authored by taavi on Sep 29 2023, 7:55 AM.
Tags
None
Referenced Files
F37934428: raw-paste-data.txt
Oct 3 2023, 8:50 PM
F37844043: raw-paste-data.txt
Sep 29 2023, 9:00 AM
F37843176: raw-paste-data.txt
Sep 29 2023, 8:35 AM
F37841734: raw-paste-data.txt
Sep 29 2023, 7:55 AM
Subscribers
None
import os
import sys
import argparse
import yaml
import keystoneauth1
from keystoneauth1.identity import v3
from keystoneauth1 import session as keystone_session
from keystoneclient.v3 import client as keystoneclient
from novaclient import client as novaclient
import glanceclient
import subprocess
import time
def keystone_session(project="cloudinfra"):
auth = v3.Password(
auth_url="https://openstack.eqiad1.wikimediacloud.org:25000/v3",
username="novaobserver",
password="Fs6Dq2RtG8KwmM2Z", # https://gerrit.wikimedia.org/g/operations/puppet/+/16906c693da99eacdf7be557cc19e110a30c96f1/hieradata/cloud/eqiad1.yaml#36
user_domain_name='Default',
project_domain_name='Default',
project_name=project,
)
return keystoneauth1.session.Session(auth=auth)
def fix_instance(vm_hypervisor, vm_libvirt_id, ip_address):
one_liner = f"( ip route get 208.80.154.224 | grep 172.16.0.1 ) || ( ip link set ens3 up; ip addr add {ip_address}/21 dev ens3; ip route add default via 172.16.0.1 )"
p = subprocess.Popen(
[
"/usr/bin/ssh",
# "-v",
"-tt",
# "-F/etc/cumin/ssh_config",
vm_hypervisor,
f"sudo virsh console {vm_libvirt_id} --force"
],
bufsize=0,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
# env={"SSH_AUTH_SOCK": "/run/keyholder/proxy.sock"}
)
for line in iter(p.stdout.readline, b''):
#print(" ", line, end="")
if "Escape character" in line:
time.sleep(0.5)
p.stdin.write("\r\n")
p.stdin.flush()
elif "root@" in line:
time.sleep(0.2)
p.stdin.write(one_liner)
p.stdin.flush()
time.sleep(0.2)
p.stdin.write("\r\n")
p.stdin.flush()
time.sleep(0.2)
p.kill()
break
def fix_project(project, broken_images):
nova = novaclient.Client("2.0", session=keystone_session(project))
servers = nova.servers.list(
detailed=True,
sort_keys=["display_name"],
sort_dirs=["asc"],
)
for server in servers:
if server.image["id"] not in broken_images:
continue
if server.status != "ACTIVE":
print(server.name, project, server.status, "SKIP")
continue
vm_info = server._info
vm_hypervisor = vm_info['OS-EXT-SRV-ATTR:hypervisor_hostname']
vm_libvirt_id = vm_info['OS-EXT-SRV-ATTR:instance_name']
for sdn, interfaces in server.addresses.items():
for interface in interfaces:
if interface["addr"].startswith("172.16."):
print(server.name, project, interface["addr"], vm_hypervisor, vm_libvirt_id)
fix_instance(vm_hypervisor, vm_libvirt_id, interface["addr"])
def get_broken_images():
glance = glanceclient.Client(
version="2",
session=keystone_session(),
interface="public",
)
broken = []
for image in glance.images.list():
if "bullseye" in image["name"]:
broken.append(image["id"])
return broken
def main():
broken_images = get_broken_images()
keystone = keystoneclient.Client(
session=keystone_session(),
interface="public",
timeout=2,
)
for project in keystone.projects.list(enabled=True, domain="default"):
if project.name.startswith("a") or project.name.startswith("b") or project.name.startswith("c"):
continue
print("*", project.name)
fix_project(project.name, broken_images)
if __name__ == "__main__":
main()