47
45
has documentation about the system. This implementation is following that
49
47
https://github.com/shankerbalan/cloudstack-scripts/blob/master/cloud-set-guest-password-debian
51
The CloudStack password server is, essentially, a broken HTTP
52
server. It requires us to provide a valid HTTP request (including a
53
DomU_Request header, which is the meat of the request), but just
54
writes the text of its response on to the socket, without a status
55
line or any HTTP headers. This makes HTTP libraries sad, which
56
explains the screwiness of the implementation of this class.
58
This should be fixed in CloudStack by commit
59
a72f14ea9cb832faaac946b3cf9f56856b50142a in December 2014.
62
50
def __init__(self, virtual_router_address):
63
51
self.virtual_router_address = virtual_router_address
65
53
def _do_request(self, domu_request):
66
# We have to provide a valid HTTP request, but a valid HTTP
67
# response is not returned. This means that getresponse() chokes,
68
# so we use the socket directly to read off the response.
69
# Because we're reading off the socket directly, we can't re-use the
71
conn = http_client.HTTPConnection(self.virtual_router_address, 8080)
73
conn.request('GET', '', headers={'DomU_Request': domu_request})
74
conn.sock.settimeout(30)
75
output = conn.sock.recv(1024).decode('utf-8').strip()
54
# The password server was in the past, a broken HTTP server, but is now
55
# fixed. wget handles this seamlessly, so it's easier to shell out to
56
# that rather than write our own handling code.
57
output, _ = util.subp([
58
'wget', '--quiet', '--tries', '3', '--timeout', '20',
59
'--output-document', '-', '--header',
60
'DomU_Request: {0}'.format(domu_request),
61
'{0}:8080'.format(self.virtual_router_address)
80
65
def get_password(self):
81
66
password = self._do_request('send_my_password')