← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1463395] [NEW] Connection refused when Cloudstack get password

 

Public bug reported:

Hi,

Get "Connection refused" when cloud-init get password from Cloudstack. I
have a workaround:

class CloudStackPasswordServerClient(object):
    """
    Implements password fetching from the CloudStack password server.

    http://cloudstack-administration.readthedocs.org/en/latest/templates.html#adding-password-management-to-your-templates
    has documentation about the system.  This implementation is following that
    found at
    https://github.com/shankerbalan/cloudstack-scripts/blob/master/cloud-set-guest-password-debian

    The CloudStack password server is, essentially, a broken HTTP
    server. It requires us to provide a valid HTTP request (including a
    DomU_Request header, which is the meat of the request), but just
    writes the text of its response on to the socket, without a status
    line or any HTTP headers.  This makes HTTP libraries sad, which
    explains the screwiness of the implementation of this class.

    This should be fixed in CloudStack by commit
    a72f14ea9cb832faaac946b3cf9f56856b50142a in December 2014.
    """

    def __init__(self, virtual_router_address):
        self.virtual_router_address = virtual_router_address

    def _do_request(self, domu_request):
        # We have to provide a valid HTTP request, but a valid HTTP
        # response is not returned. This means that getresponse() chokes,
        # so we use the socket directly to read off the response.
        # Because we're reading off the socket directly, we can't re-use the
        # connection.
        conn = http_client.HTTPConnection(self.virtual_router_address, 8080)
        try:
            conn.request('GET', '', headers={'DomU_Request': domu_request})
            conn.sock.settimeout(30)
            output = conn.sock.recv(1024).decode('utf-8').strip()
        finally:
            conn.close()
        return output

    def get_password(self):
        password = self._do_request('send_my_password')
        if password in ['', 'saved_password']:
            return None
        if password == 'bad_request':
            raise RuntimeError('Error when attempting to fetch root password.')
        time.sleep(1)                                                                        <---- If put the sleep(1), the second http request success
        self._do_request('saved_password')
        return password

** Affects: cloud-init
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to cloud-init.
https://bugs.launchpad.net/bugs/1463395

Title:
  Connection refused when Cloudstack get password

Status in Init scripts for use on cloud images:
  New

Bug description:
  Hi,

  Get "Connection refused" when cloud-init get password from Cloudstack.
  I have a workaround:

  class CloudStackPasswordServerClient(object):
      """
      Implements password fetching from the CloudStack password server.

      http://cloudstack-administration.readthedocs.org/en/latest/templates.html#adding-password-management-to-your-templates
      has documentation about the system.  This implementation is following that
      found at
      https://github.com/shankerbalan/cloudstack-scripts/blob/master/cloud-set-guest-password-debian

      The CloudStack password server is, essentially, a broken HTTP
      server. It requires us to provide a valid HTTP request (including a
      DomU_Request header, which is the meat of the request), but just
      writes the text of its response on to the socket, without a status
      line or any HTTP headers.  This makes HTTP libraries sad, which
      explains the screwiness of the implementation of this class.

      This should be fixed in CloudStack by commit
      a72f14ea9cb832faaac946b3cf9f56856b50142a in December 2014.
      """

      def __init__(self, virtual_router_address):
          self.virtual_router_address = virtual_router_address

      def _do_request(self, domu_request):
          # We have to provide a valid HTTP request, but a valid HTTP
          # response is not returned. This means that getresponse() chokes,
          # so we use the socket directly to read off the response.
          # Because we're reading off the socket directly, we can't re-use the
          # connection.
          conn = http_client.HTTPConnection(self.virtual_router_address, 8080)
          try:
              conn.request('GET', '', headers={'DomU_Request': domu_request})
              conn.sock.settimeout(30)
              output = conn.sock.recv(1024).decode('utf-8').strip()
          finally:
              conn.close()
          return output

      def get_password(self):
          password = self._do_request('send_my_password')
          if password in ['', 'saved_password']:
              return None
          if password == 'bad_request':
              raise RuntimeError('Error when attempting to fetch root password.')
          time.sleep(1)                                                                        <---- If put the sleep(1), the second http request success
          self._do_request('saved_password')
          return password

To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-init/+bug/1463395/+subscriptions


Follow ups

References