Create Skia GCE bots with ephemeral IPs and service token swarming auth

This is similar to https://skia-review.googlesource.com/c/18841/

Bug: skia:6611
Change-Id: Id650fd6b1effb5801e152a80aa6ba62fbb49f078
Reviewed-on: https://skia-review.googlesource.com/19499
Commit-Queue: Ravi Mistry <rmistry@google.com>
Reviewed-by: Eric Boren <borenet@google.com>
diff --git a/go/gce/gce.go b/go/gce/gce.go
index 219e6ce..6e528b9 100644
--- a/go/gce/gce.go
+++ b/go/gce/gce.go
@@ -59,6 +59,7 @@
 
 	SERVICE_ACCOUNT_DEFAULT         = "31977622648@project.gserviceaccount.com"
 	SERVICE_ACCOUNT_CHROME_SWARMING = "chrome-swarming-bots@skia-buildbots.google.com.iam.gserviceaccount.com"
+	SERVICE_ACCOUNT_CHROMIUM_SWARM  = "chromium-swarm-bots@skia-buildbots.google.com.iam.gserviceaccount.com"
 
 	SETUP_SCRIPT_KEY_LINUX  = "setup-script"
 	SETUP_SCRIPT_KEY_WIN    = "sysprep-oobe-script-ps1"
diff --git a/go/gce/swarming/setup-script-linux.sh b/go/gce/swarming/setup-script-linux.sh
index 805a0d5..88120e2 100644
--- a/go/gce/swarming/setup-script-linux.sh
+++ b/go/gce/swarming/setup-script-linux.sh
@@ -8,7 +8,7 @@
 
 sudo apt-get -y install mercurial mysql-client mysql-server libosmesa-dev npm nodejs-legacy libexpat1-dev:i386 clang-3.6 poppler-utils netpbm
 
-mysql -uroot -ptmp_pass -e "SET PASSWORD = PASSWORD('');" 
+mysql -uroot -ptmp_pass -e "SET PASSWORD = PASSWORD('');"
 
 sudo npm install -g npm@3.10.9
 sudo npm install -g bower@1.6.5
@@ -37,6 +37,8 @@
 sudo ln -s -f /usr/bin/llvm-cov-3.6 /usr/bin/llvm-cov
 sudo ln -s -f /usr/bin/llvm-profdata-3.6 /usr/bin/llvm-profdata
 
+# Get access token from metadata.
+TOKEN=`curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" | python -c "import sys, json; print json.load(sys.stdin)['access_token']"`
 # Bootstrap Swarming.
 sudo chmod 777 /b
 mkdir -p /b/s
@@ -44,5 +46,6 @@
 if [[ $(hostname) == *"-i-"* ]]; then
   SWARMING=https://chrome-swarming.appspot.com
 fi
-wget ${SWARMING}/bot_code -O /b/s/swarming_bot.zip
+HOSTNAME=`hostname`
+curl ${SWARMING}/bot_code?bot_id=$HOSTNAME -H "Authorization":"Bearer $TOKEN" -o /b/s/swarming_bot.zip
 ln -sf /b/s /b/swarm_slave
diff --git a/go/gce/swarming/swarming_vm.go b/go/gce/swarming/swarming_vm.go
index ac26a89..4212c7a 100644
--- a/go/gce/swarming/swarming_vm.go
+++ b/go/gce/swarming/swarming_vm.go
@@ -27,7 +27,6 @@
 	GS_URL_GITCONFIG = "gs://skia-buildbots/artifacts/bots/.gitconfig"
 	GS_URL_NETRC     = "gs://skia-buildbots/artifacts/bots/.netrc"
 
-	IP_ADDRESS_TMPL = "104.154.112.%d"
 	USER_CHROME_BOT = "chrome-bot"
 )
 
@@ -46,7 +45,7 @@
 	workdir        = flag.String("workdir", ".", "Working directory.")
 )
 
-// Base config for Swarming GCE instances.
+// Base configs for Swarming GCE instances.
 func Swarming20170523(name, ipAddress string) *gce.Instance {
 	return &gce.Instance{
 		BootDisk: &gce.Disk{
@@ -75,6 +74,36 @@
 	}
 }
 
+func Swarming20170615(name, serviceAccount string) *gce.Instance {
+	return &gce.Instance{
+		BootDisk: &gce.Disk{
+			Name:        name,
+			SourceImage: "skia-swarming-v3",
+			Type:        gce.DISK_TYPE_PERSISTENT_STANDARD,
+		},
+		DataDisk: &gce.Disk{
+			Name:   fmt.Sprintf("%s-data", name),
+			SizeGb: 300,
+			Type:   gce.DISK_TYPE_PERSISTENT_STANDARD,
+		},
+		Gpu:               *gpu,
+		GSDownloads:       map[string]string{},
+		MachineType:       gce.MACHINE_TYPE_STANDARD_16,
+		Metadata:          map[string]string{},
+		MetadataDownloads: map[string]string{},
+		Name:              name,
+		Os:                gce.OS_LINUX,
+		ServiceAccount:    serviceAccount,
+		Scopes: []string{
+			auth.SCOPE_FULL_CONTROL,
+			auth.SCOPE_USERINFO_EMAIL,
+			auth.SCOPE_PUBSUB,
+		},
+		Tags: []string{"use-swarming-auth"},
+		User: USER_CHROME_BOT,
+	}
+}
+
 // Configs for Linux GCE instances.
 func AddLinuxConfigs(vm *gce.Instance) *gce.Instance {
 	vm.GSDownloads["/home/chrome-bot/.gitconfig"] = GS_URL_GITCONFIG
@@ -87,26 +116,26 @@
 }
 
 // Linux GCE instances.
-func LinuxSwarmingBot(num int, ipAddress string) *gce.Instance {
-	return AddLinuxConfigs(Swarming20170523(fmt.Sprintf("skia-vm-%03d", num), ipAddress))
+func LinuxSwarmingBot(num int) *gce.Instance {
+	return AddLinuxConfigs(Swarming20170615(fmt.Sprintf("skia-gce-%03d", num), gce.SERVICE_ACCOUNT_CHROMIUM_SWARM))
 }
 
 // Internal Linux GCE instances.
-func InternalLinuxSwarmingBot(num int, ipAddress string) *gce.Instance {
-	vm := AddLinuxConfigs(Swarming20170523(fmt.Sprintf("skia-i-vm-%03d", num), ipAddress))
+func InternalLinuxSwarmingBot(num int) *gce.Instance {
+	vm := AddLinuxConfigs(Swarming20170615(fmt.Sprintf("skia-i-gce-%03d", num), gce.SERVICE_ACCOUNT_CHROME_SWARMING))
 	vm.MetadataDownloads["/home/chrome-bot/.gitcookies"] = fmt.Sprintf(metadata.METADATA_URL, "project", "gitcookies_skia-internal_chromium")
 	return vm
 }
 
 // Skia CT bots.
-func SkiaCTBot(num int, ipAddress string) *gce.Instance {
-	vm := AddLinuxConfigs(Swarming20170523(fmt.Sprintf("skia-ct-vm-%03d", num), ipAddress))
+func SkiaCTBot(num int) *gce.Instance {
+	vm := AddLinuxConfigs(Swarming20170615(fmt.Sprintf("skia-ct-gce-%03d", num), gce.SERVICE_ACCOUNT_CHROMIUM_SWARM))
 	vm.DataDisk.SizeGb = 3000
 	return vm
 }
 
 // Configs for Windows GCE instances.
-func AddWinConfigs(vm *gce.Instance, ipAddress, pw, setupScriptPath, startupScriptPath, chromebotScript string) *gce.Instance {
+func AddWinConfigs(vm *gce.Instance, pw, setupScriptPath, startupScriptPath, chromebotScript string) *gce.Instance {
 	vm.BootDisk.SizeGb = 300
 	vm.BootDisk.SourceImage = "projects/google.com:windows-internal/global/images/windows-server-2008-r2-ent-internal-v20150310"
 	vm.BootDisk.Type = gce.DISK_TYPE_PERSISTENT_SSD
@@ -123,15 +152,15 @@
 }
 
 // Windows GCE instances.
-func WinSwarmingBot(num int, ipAddress, pw, setupScriptPath, startupScriptPath, chromebotScript string) *gce.Instance {
-	vm := Swarming20170523(fmt.Sprintf("skia-vm-%03d", num), ipAddress)
-	return AddWinConfigs(vm, ipAddress, pw, setupScriptPath, startupScriptPath, chromebotScript)
+func WinSwarmingBot(num int, pw, setupScriptPath, startupScriptPath, chromebotScript string) *gce.Instance {
+	vm := Swarming20170615(fmt.Sprintf("skia-gce-%03d", num), gce.SERVICE_ACCOUNT_CHROMIUM_SWARM)
+	return AddWinConfigs(vm, pw, setupScriptPath, startupScriptPath, chromebotScript)
 }
 
 // Internal Windows GCE instances.
-func InternalWinSwarmingBot(num int, ipAddress, pw, setupScriptPath, startupScriptPath, chromebotScript string) *gce.Instance {
-	vm := Swarming20170523(fmt.Sprintf("skia-i-vm-%03d", num), ipAddress)
-	return AddWinConfigs(vm, ipAddress, pw, setupScriptPath, startupScriptPath, chromebotScript)
+func InternalWinSwarmingBot(num int, pw, setupScriptPath, startupScriptPath, chromebotScript string) *gce.Instance {
+	vm := Swarming20170615(fmt.Sprintf("skia-i-gce-%03d", num), gce.SERVICE_ACCOUNT_CHROME_SWARMING)
+	return AddWinConfigs(vm, pw, setupScriptPath, startupScriptPath, chromebotScript)
 }
 
 // GCE instances with GPUs.
@@ -261,20 +290,19 @@
 	group := util.NewNamedErrGroup()
 	for _, num := range instanceNums {
 		var vm *gce.Instance
-		ipAddr := fmt.Sprintf(IP_ADDRESS_TMPL, num)
 		if *ct {
-			vm = SkiaCTBot(num, ipAddr)
+			vm = SkiaCTBot(num)
 		} else if *windows {
 			if *internal {
-				vm = InternalWinSwarmingBot(num, ipAddr, pw, setupScript, startupScript, chromebotScript)
+				vm = InternalWinSwarmingBot(num, pw, setupScript, startupScript, chromebotScript)
 			} else {
-				vm = WinSwarmingBot(num, ipAddr, pw, setupScript, startupScript, chromebotScript)
+				vm = WinSwarmingBot(num, pw, setupScript, startupScript, chromebotScript)
 			}
 		} else {
 			if *internal {
-				vm = InternalLinuxSwarmingBot(num, ipAddr)
+				vm = InternalLinuxSwarmingBot(num)
 			} else {
-				vm = LinuxSwarmingBot(num, ipAddr)
+				vm = LinuxSwarmingBot(num)
 			}
 		}
 		if *gpu {
diff --git a/scripts/chromebot-schtask.ps1 b/scripts/chromebot-schtask.ps1
index d5e9e79..837e507 100644
--- a/scripts/chromebot-schtask.ps1
+++ b/scripts/chromebot-schtask.ps1
@@ -120,12 +120,15 @@
 banner "Start Swarming."
 $swarm_slave_dir = "c:\b\s"
 if (!(Test-Path ($swarm_slave_dir))) {
+  new-item $swarm_slave_dir -itemtype directory
   $swarming = "https://chromium-swarm.appspot.com"
   $hostname =(cmd /c "hostname") | Out-String
   if ($hostname.StartsWith("skia-i-")) {
     $swarming = "https://chrome-swarming.appspot.com"
   }
-  cmd /c "python -c `"import urllib; exec urllib.urlopen('$swarming/bootstrap').read()`""
+  $metadataJson = Invoke-WebRequest -Uri http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token -Headers @{"Metadata-Flavor"="Google"} | ConvertFrom-Json
+  curl $swarming/bot_code?bot_id=$hostname -Headers @{"Authorization"="Bearer " + $metadataJson.access_token} -OutFile $swarm_slave_dir/swarming_bot.zip
 }
+cmd /c "python $swarm_slave_dir/swarming_bot.zip start_bot"
 
 banner "The Task ended"