Skip to content

Instantly share code, notes, and snippets.

@samgooi4189
Last active January 5, 2020 02:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samgooi4189/6aae9424108159cc823bda7270b6b8a3 to your computer and use it in GitHub Desktop.
Save samgooi4189/6aae9424108159cc823bda7270b6b8a3 to your computer and use it in GitHub Desktop.
Create preemptive compute engine with java
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.compute.Compute;
import com.google.api.services.compute.ComputeScopes;
import com.google.api.services.compute.model.*;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SomeClass {
/**
* Be sure to specify the name of your application. If the application name is {@code null} or
* blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0".
*/
private static final String APPLICATION_NAME = " ";
/** Set PROJECT_ID to your Project ID from the Overview pane in the Developers console. */
private static final String PROJECT_ID = " ";
/** Set Compute Engine zone. */
private static final String ZONE_NAME = " ";
/** Set the name of the sample VM instance to be created. */
private static final String INSTANCE_NAME = " ";
/** Set the path of the OS image for the sample VM instance to be created. */
private static final String SOURCE_IMAGE_PREFIX = "https://www.googleapis.com/compute/v1/projects/";
private static final String SOURCE_IMAGE_PATH =
"debian-cloud/global/images/debian-10-buster-v20191210";
/** Set the Network configuration values of the sample VM instance to be created. */
private static final String NETWORK_INTERFACE_CONFIG = "ONE_TO_ONE_NAT";
private static final String NETWORK_ACCESS_CONFIG = "External NAT";
/** Set the time out limit for operation calls to the Compute Engine API. */
private static final long OPERATION_TIMEOUT_MILLIS = 60 * 1000;
/** Global instance of the HTTP transport. */
private static HttpTransport httpTransport;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/**
* Create preemptive compute engine
* https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/compute/cmdline/src/main/java/ComputeEngineSample.java
*/
public static void main(String[] args) {
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
// Authenticate using Google Application Default Credentials.
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
if (credentials.createScopedRequired()) {
List<String> scopes = new ArrayList<>();
// Set Google Cloud Storage scope to Full Control.
scopes.add(ComputeScopes.DEVSTORAGE_FULL_CONTROL);
// Set Google Compute Engine scope to Read-write.
scopes.add(ComputeScopes.COMPUTE);
credentials = credentials.createScoped(scopes);
}
HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials);
// Create Compute Engine object for listing instances.
Compute compute =
new Compute.Builder(httpTransport, JSON_FACTORY, requestInitializer)
.setApplicationName(APPLICATION_NAME)
.build();
// List out instances, looking for the one created by this sample app.
boolean foundOurInstance = printInstances(compute);
Operation op;
if (foundOurInstance) {
op = deleteInstance(compute, INSTANCE_NAME);
} else {
op = startInstance(compute, INSTANCE_NAME);
}
// Call Compute Engine API operation and poll for operation completion status
System.out.println("Waiting for operation completion...");
Operation.Error error = blockUntilComplete(compute, op, OPERATION_TIMEOUT_MILLIS);
if (error == null) {
System.out.println("Success!");
} else {
System.out.println(error.toPrettyString());
}
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (Throwable t) {
t.printStackTrace();
}
//System.exit(1);
}
// [START list_instances]
/**
* Print available machine instances.
*
* @param compute The main API access point
* @return {@code true} if the instance created by this sample app is in the list
*/
public static boolean printInstances(Compute compute) throws IOException {
System.out.println("================== Listing Compute Engine Instances ==================");
Compute.Instances.List instances = compute.instances().list(PROJECT_ID, ZONE_NAME);
InstanceList list = instances.execute();
boolean found = false;
if (list.getItems() == null) {
System.out.println("No instances found. Sign in to the Google Developers Console and create "
+ "an instance at: https://console.developers.google.com/");
} else {
for (Instance instance : list.getItems()) {
System.out.println(instance.toPrettyString());
if (instance.getName().equals(INSTANCE_NAME)) {
found = true;
}
}
}
return found;
}
// [END list_instances]
// [START create_instances]
public static Operation startInstance(Compute compute, String instanceName) throws IOException {
System.out.println("================== Starting New Instance ==================");
// Create VM Instance object with the required properties.
Instance instance = new Instance();
instance.setName(instanceName);
instance.setMachineType(
"https://www.googleapis.com/compute/v1/projects/"
+ PROJECT_ID + "/zones/" + ZONE_NAME + "/machineTypes/n1-standard-1");
// Add Network Interface to be used by VM Instance.
NetworkInterface ifc = new NetworkInterface();
ifc.setNetwork("https://www.googleapis.com/compute/v1/projects/" + PROJECT_ID + "/global/networks/default");
List<AccessConfig> configs = new ArrayList<>();
AccessConfig config = new AccessConfig();
config.setType(NETWORK_INTERFACE_CONFIG);
config.setName(NETWORK_ACCESS_CONFIG);
configs.add(config);
ifc.setAccessConfigs(configs);
instance.setNetworkInterfaces(Collections.singletonList(ifc));
// Add attached Persistent Disk to be used by VM Instance.
AttachedDisk disk = new AttachedDisk();
disk.setBoot(true);
disk.setAutoDelete(true);
disk.setType("PERSISTENT");
AttachedDiskInitializeParams params = new AttachedDiskInitializeParams();
// Assign the Persistent Disk the same name as the VM Instance.
params.setDiskName(instanceName);
// Specify the source operating system machine image to be used by the VM Instance.
params.setSourceImage(SOURCE_IMAGE_PREFIX + SOURCE_IMAGE_PATH);
// Specify the disk type as Standard Persistent Disk
params.setDiskType("https://www.googleapis.com/compute/v1/projects/" + PROJECT_ID + "/zones/"
+ ZONE_NAME + "/diskTypes/pd-standard");
disk.setInitializeParams(params);
instance.setDisks(Collections.singletonList(disk));
// Initialize the service account to be used by the VM Instance and set the API access scopes.
ServiceAccount account = new ServiceAccount();
account.setEmail("default");
List<String> scopes = new ArrayList<>();
scopes.add("https://www.googleapis.com/auth/devstorage.full_control");
scopes.add("https://www.googleapis.com/auth/compute");
account.setScopes(scopes);
instance.setServiceAccounts(Collections.singletonList(account));
// Set preemptive
Scheduling scheduling = new Scheduling();
scheduling.setPreemptible(Boolean.TRUE);
instance.setScheduling(scheduling);
// Optional - Add a startup script to be used by the VM Instance.
Metadata meta = new Metadata();
Metadata.Items item = new Metadata.Items();
item.setKey("startup-script-url");
// If you put a script called "vm-startup.sh" in this Google Cloud Storage
// bucket, it will execute on VM startup. This assumes you've created a
// bucket named the same as your PROJECT_ID.
// For info on creating buckets see: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets
item.setValue("gs://" + PROJECT_ID + "/vm-startup.sh");
meta.setItems(Collections.singletonList(item));
instance.setMetadata(meta);
System.out.println(instance.toPrettyString());
Compute.Instances.Insert insert = compute.instances().insert(PROJECT_ID, ZONE_NAME, instance);
return insert.execute();
}
// [END create_instances]
private static Operation deleteInstance(Compute compute, String instanceName) throws Exception {
System.out.println(
"================== Deleting Instance " + instanceName + " ==================");
Compute.Instances.Delete delete =
compute.instances().delete(PROJECT_ID, ZONE_NAME, instanceName);
return delete.execute();
}
// [START wait_until_complete]
/**
* Wait until {@code operation} is completed.
* @param compute the {@code Compute} object
* @param operation the operation returned by the original request
* @param timeout the timeout, in millis
* @return the error, if any, else {@code null} if there was no error
* @throws InterruptedException if we timed out waiting for the operation to complete
* @throws IOException if we had trouble connecting
*/
public static Operation.Error blockUntilComplete(
Compute compute, Operation operation, long timeout) throws Exception {
long start = System.currentTimeMillis();
final long pollInterval = 5 * 1000;
String zone = operation.getZone(); // null for global/regional operations
if (zone != null) {
String[] bits = zone.split("/");
zone = bits[bits.length - 1];
}
String status = operation.getStatus();
String opId = operation.getName();
while (operation != null && !status.equals("DONE")) {
Thread.sleep(pollInterval);
long elapsed = System.currentTimeMillis() - start;
if (elapsed >= timeout) {
throw new InterruptedException("Timed out waiting for operation to complete");
}
System.out.println("waiting...");
if (zone != null) {
Compute.ZoneOperations.Get get = compute.zoneOperations().get(PROJECT_ID, zone, opId);
operation = get.execute();
} else {
Compute.GlobalOperations.Get get = compute.globalOperations().get(PROJECT_ID, opId);
operation = get.execute();
}
if (operation != null) {
status = operation.getStatus();
}
}
return operation == null ? null : operation.getError();
}
// [END wait_until_complete]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment