1+ // Copyright 2022 Google LLC
2+ //
3+ // Licensed under the Apache License, Version 2.0 (the "License");
4+ // you may not use this file except in compliance with the License.
5+ // You may obtain a copy of the License at
6+ //
7+ // http://www.apache.org/licenses/LICENSE-2.0
8+ //
9+ // Unless required by applicable law or agreed to in writing, software
10+ // distributed under the License is distributed on an "AS IS" BASIS,
11+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ // See the License for the specific language governing permissions and
13+ // limitations under the License.
14+
15+ package compute .windows .osimage ;
16+
17+ // [START compute_windows_image_create]
18+
19+ import com .google .cloud .compute .v1 .Disk ;
20+ import com .google .cloud .compute .v1 .DisksClient ;
21+ import com .google .cloud .compute .v1 .Image ;
22+ import com .google .cloud .compute .v1 .ImagesClient ;
23+ import com .google .cloud .compute .v1 .InsertImageRequest ;
24+ import com .google .cloud .compute .v1 .Instance ;
25+ import com .google .cloud .compute .v1 .InstancesClient ;
26+ import com .google .cloud .compute .v1 .Operation ;
27+ import java .io .IOException ;
28+ import java .util .Arrays ;
29+ import java .util .HashMap ;
30+ import java .util .Map ;
31+ import java .util .concurrent .ExecutionException ;
32+ import java .util .concurrent .TimeUnit ;
33+ import java .util .concurrent .TimeoutException ;
34+
35+ public class CreateWindowsOsImage {
36+
37+ public static void main (String [] args )
38+ throws IOException , ExecutionException , InterruptedException , TimeoutException {
39+ // TODO(developer): Replace these variables before running the sample.
40+
41+ // Project ID or project number of the Cloud project you use.
42+ String project = "your-project-id" ;
43+ // Zone of the disk you copy from.
44+ String zone = "europe-central2-b" ;
45+ // Name of the source disk you copy from.
46+ String sourceDiskName = "source-disk-name" ;
47+ // Name of the image you want to create.
48+ String imageName = "your-image-name" ;
49+ // Storage location for the image. If the value is undefined,
50+ // function will store the image in the multi-region closest to your image's source location.
51+ String storageLocation = "eu" ;
52+ // Create the image even if the source disk is attached to a running instance.
53+ boolean forceCreate = false ;
54+
55+ createWindowsOsImage (project , zone , sourceDiskName , imageName , storageLocation , forceCreate );
56+ }
57+
58+ // Creates a new Windows image from the specified source disk.
59+ public static void createWindowsOsImage (String project , String zone , String sourceDiskName ,
60+ String imageName , String storageLocation , boolean forceCreate )
61+ throws IOException , ExecutionException , InterruptedException , TimeoutException {
62+
63+ try (ImagesClient imagesClient = ImagesClient .create ();
64+ InstancesClient instancesClient = InstancesClient .create ();
65+ DisksClient disksClient = DisksClient .create ()) {
66+
67+ Disk disk = disksClient .get (project , zone , sourceDiskName );
68+
69+ // Getting instances where source disk is attached.
70+ for (String fullInstanceName : disk .getUsersList ()) {
71+ Map <String , String > instanceInfo = parseInstanceName (fullInstanceName );
72+ Instance instance = instancesClient .get (instanceInfo .get ("instanceProjectId" ),
73+ instanceInfo .get ("instanceZone" ), instanceInfo .get ("instanceName" ));
74+
75+ // Сhecking whether the instances is stopped.
76+ if (!Arrays .asList ("TERMINATED" , "STOPPED" ).contains (instance .getStatus ())
77+ && !forceCreate ) {
78+ throw new IllegalStateException (
79+ String .format (
80+ "Instance %s should be stopped. Please stop the instance using GCESysprep command or set forceCreate parameter to true (not recommended). More information here: https://cloud.google.com/compute/docs/instances/windows/creating-windows-os-image#api." ,
81+ instanceInfo .get ("instanceName" )));
82+ }
83+ }
84+
85+ if (forceCreate ) {
86+ System .out .println (
87+ "Warning: forceCreate option compromise the integrity of your image. "
88+ + "Stop the instance before you create the image if possible." );
89+ }
90+
91+ // Create Image.
92+ Image image = Image .newBuilder ()
93+ .setName (imageName )
94+ .setSourceDisk (String .format ("/zones/%s/disks/%s" , zone , sourceDiskName ))
95+ .addStorageLocations (storageLocation .isEmpty () ? "" : storageLocation )
96+ .build ();
97+
98+ InsertImageRequest insertImageRequest = InsertImageRequest .newBuilder ()
99+ .setProject (project )
100+ .setForceCreate (forceCreate )
101+ .setImageResource (image )
102+ .build ();
103+
104+ Operation response = imagesClient .insertAsync (insertImageRequest ).get (3 , TimeUnit .MINUTES );
105+
106+ if (response .hasError ()) {
107+ System .out .println ("Windows OS Image creation failed ! ! " + response );
108+ return ;
109+ }
110+
111+ System .out .println ("Image created." );
112+ }
113+ }
114+
115+
116+ public static Map <String , String > parseInstanceName (String name ) {
117+ String [] parsedName = name .split ("/" );
118+ int splitLength = parsedName .length ;
119+
120+ if (splitLength < 5 ) {
121+ throw new IllegalArgumentException (
122+ "Provide correct instance name in the following format: "
123+ + "https://www.googleapis.com/compute/v1/projects/PROJECT/zones/ZONE/instances/INSTANCE_NAME" );
124+ }
125+
126+ return new HashMap <>() {
127+ {
128+ put ("instanceName" , parsedName [splitLength - 1 ]);
129+ put ("instanceZone" , parsedName [splitLength - 3 ]);
130+ put ("instanceProjectId" , parsedName [splitLength - 5 ]);
131+ }
132+ };
133+ }
134+
135+ }
136+ // [END compute_windows_image_create]
0 commit comments