Ejemplo n.º 1
0
def compose_preseed(preseed_type, node):
    """Put together preseed data for `node`.

    This produces preseed data for the node in different formats depending
    on the preseed_type.

    :param preseed_type: The type of preseed to compose.
    :type preseed_type: string
    :param node: The node to compose preseed data for.
    :type node: Node
    :return: Preseed data containing the information the node needs in order
        to access the metadata service: its URL and auth token.
    """
    # Circular import.
    from metadataserver.models import NodeKey

    token = NodeKey.objects.get_token_for_node(node)
    rack_controller = node.get_boot_rack_controller()
    base_url = rack_controller.url

    if preseed_type == PRESEED_TYPE.COMMISSIONING:
        return compose_commissioning_preseed(node, token, base_url)
    else:
        metadata_url = _get_metadata_url(preseed_type, base_url)

        try:
            return get_preseed_data(preseed_type, node, token, metadata_url)
        except NotImplementedError:
            # This is fine; it indicates that the OS does not specify
            # any special preseed data for this type of preseed.
            pass
        except NoSuchOperatingSystem:
            # Let a caller handle this. If rendered for presentation in the
            # UI, an explanatory error message could be displayed. If rendered
            # via the API, in response to cloud-init for example, the prudent
            # course of action might be to turn the node's power off, mark it
            # as broken, and notify the user.
            raise
        except NoConnectionsAvailable:
            # This means that the region is not in contact with the node's
            # cluster controller. In the UI this could be shown as an error
            # message. This is, however, a show-stopping problem when booting
            # or installing a node. A caller cannot turn the node's power off
            # via the usual methods because they rely on a connection to the
            # cluster. This /could/ generate a preseed that aborts the boot or
            # installation. The caller /could/ mark the node as broken. For
            # now, let the caller make the decision, which might be to retry.
            raise

        # There is no OS-specific preseed data.
        if preseed_type == PRESEED_TYPE.CURTIN:
            return compose_curtin_preseed(node, token, base_url)
        else:
            return compose_cloud_init_preseed(node, token, base_url)
Ejemplo n.º 2
0
 def test_returns_preseed_data(self):
     # The Windows driver is known to provide custom preseed data.
     rack = factory.make_RackController()
     node = factory.make_Node(interface=True, osystem="windows")
     boot_interface = node.get_boot_interface()
     boot_interface.vlan.dhcp_on = True
     boot_interface.vlan.primary_rack = rack
     boot_interface.vlan.save()
     self.useFixture(RunningClusterRPCFixture())
     preseed_data = get_preseed_data(
         PRESEED_TYPE.COMMISSIONING,
         node,
         token=NodeKey.objects.get_token_for_node(node),
         metadata_url=factory.make_url())
     self.assertThat(preseed_data, IsInstance(dict))
     self.assertNotIn("data", preseed_data)
     self.assertThat(preseed_data, Not(HasLength(0)))