public Builder fromInstance(Instance in) {
   return super.fromResource(in)
       .tags(in.getTags())
       .image(in.getImage())
       .machineType(in.getMachineType())
       .status(in.getStatus())
       .statusMessage(in.getStatusMessage().orNull())
       .zone(in.getZone())
       .networkInterfaces(in.getNetworkInterfaces())
       .disks(in.getDisks())
       .metadata(in.getMetadata())
       .serviceAccounts(in.getServiceAccounts());
 }
  public void testCreatePreemptibleNodeWithSsd() throws Exception {
    String group = this.group + "ssd";
    try {
      TemplateOptions options = client.templateOptions();

      options.as(GoogleComputeEngineTemplateOptions.class).bootDiskType("pd-ssd").preemptible(true);

      // create a node
      Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, options);
      assertEquals(nodes.size(), 1, "One node should have been created");

      // Verify the disk on the instance is an ssd.
      NodeMetadata node = Iterables.get(nodes, 0);
      GoogleComputeEngineApi api = client.getContext().unwrapApi(GoogleComputeEngineApi.class);
      Instance instance = api.instancesInZone(node.getLocation().getId()).get(node.getName());
      Disk disk =
          api.disksInZone(node.getLocation().getId()).get(toName(instance.disks().get(0).source()));
      assertTrue(disk.type().toString().endsWith("pd-ssd"));
      assertTrue(instance.scheduling().preemptible());

    } finally {
      client.destroyNodesMatching(NodePredicates.inGroup(group));
    }
  }
  @Override
  public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(
      String group, String name, Template template) {
    GoogleComputeEngineTemplateOptions options =
        GoogleComputeEngineTemplateOptions.class.cast(template.getOptions());

    checkNotNull(options.getNetworks(), "template options must specify a network");
    checkNotNull(template.getHardware().getUri(), "hardware must have a URI");
    checkNotNull(template.getImage().getUri(), "image URI is null");

    List<AttachDisk> disks = Lists.newArrayList();
    disks.add(AttachDisk.newBootDisk(template.getImage().getUri()));

    Iterator<String> networks = options.getNetworks().iterator();

    URI network = URI.create(networks.next());
    assert !networks.hasNext() : "Error: Options should specify only one network";

    // Add tags from template
    ArrayList<String> tags = new ArrayList<String>(options.getTags());

    // Add tags for firewalls
    FirewallTagNamingConvention naming = firewallTagNamingConvention.get(group);
    List<String> ports = simplifyPorts(options.getInboundPorts());
    if (ports != null) {
      tags.add(naming.name(ports));
    }

    NewInstance newInstance =
        new NewInstance.Builder(
                name,
                template.getHardware().getUri(), // machineType
                network,
                disks)
            .description(group)
            .tags(Tags.create(null, ImmutableList.copyOf(tags)))
            .serviceAccounts(options.serviceAccounts())
            .build();

    // Add metadata from template and for ssh key and image id
    newInstance.metadata().putAll(options.getUserMetadata());

    LoginCredentials credentials = resolveNodeCredentials(template);
    if (options.getPublicKey() != null) {
      newInstance
          .metadata()
          .put(
              "sshKeys",
              format(
                  "%s:%s %s@localhost",
                  credentials.getUser(), options.getPublicKey(), credentials.getUser()));
    }

    String zone = template.getLocation().getId();
    InstanceApi instanceApi = api.instancesInZone(zone);
    Operation create = instanceApi.create(newInstance);

    // We need to see the created instance so that we can access the newly created disk.
    AtomicReference<Instance> instance =
        Atomics.newReference(
            Instance.create( //
                "0000000000000000000", // id can't be null, but isn't available until provisioning
                                       // is done.
                null, // creationTimestamp
                create.targetLink(), // selfLink
                newInstance.name(), // name
                newInstance.description(), // description
                newInstance.tags(), // tags
                newInstance.machineType(), // machineType
                Instance.Status.PROVISIONING, // status
                null, // statusMessage
                create.zone(), // zone
                null, // canIpForward
                null, // networkInterfaces
                null, // disks
                newInstance.metadata(), // metadata
                newInstance.serviceAccounts(), // serviceAccounts
                Scheduling.create(OnHostMaintenance.MIGRATE, true) // scheduling
                ));
    checkState(instanceVisible.apply(instance), "instance %s is not api visible!", instance.get());

    // Add lookup for InstanceToNodeMetadata
    diskToSourceImage.put(instance.get().disks().get(0).source(), template.getImage().getUri());

    return new NodeAndInitialCredentials<Instance>(
        instance.get(), instance.get().selfLink().toString(), credentials);
  }