| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  | # |source| this file | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Utilities for working with Azure instances | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Default zone | 
					
						
							|  |  |  | cloud_DefaultZone() { | 
					
						
							|  |  |  |   echo "westus" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-14 23:11:29 -07:00
										 |  |  | cloud_RestartPreemptedInstances() { | 
					
						
							|  |  |  |   : # Not implemented | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  | # | 
					
						
							|  |  |  | # __cloud_GetConfigValueFromInstanceName | 
					
						
							|  |  |  | # Return a piece of configuration information about an instance | 
					
						
							|  |  |  | # Provide the exact name of an instance and the configuration key, and the corresponding value will be returned | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # example: | 
					
						
							|  |  |  | #   This will return the name of the resource group of the instance named | 
					
						
							|  |  |  | #   __cloud_GetConfigValueFromInstanceName some-instance-name resourceGroup | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cloud_GetConfigValueFromInstanceName() { | 
					
						
							|  |  |  |   query="[?name=='$1']" | 
					
						
							|  |  |  |   key="[$2]" | 
					
						
							|  |  |  |   config_value=$(az vm list -d -o tsv --query "$query.$key") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | cloud_GetResourceGroupFromInstanceName() { | 
					
						
							|  |  |  |   resourceGroup=$(az vm list -o tsv --query "[?name=='$1'].[resourceGroup]") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | cloud_GetIdFromInstanceName() { | 
					
						
							|  |  |  |   id=$(az vm list -o tsv --query "[?name=='$1'].[id]") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # __cloud_FindInstances | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Find instances matching the specified pattern. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # For each matching instance, an entry in the `instances` array will be added with the | 
					
						
							|  |  |  | # following information about the instance: | 
					
						
							|  |  |  | #   "name:public IP:private IP:location" | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # filter   - The instances to filter on | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # examples: | 
					
						
							|  |  |  | #   $ __cloud_FindInstances prefix some-machine-prefix | 
					
						
							|  |  |  | #   $ __cloud_FindInstances name exact-machine-name | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  Examples of plain-text filter command | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This will return an exact match for a machine named pgnode | 
					
						
							|  |  |  | #  az vm list -d --query "[?name=='pgnode'].[name,publicIps,privateIps,location]" | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  This will return a match for any machine with prefix pgnode, ex: pgnode and pgnode2 | 
					
						
							|  |  |  | #  az vm list -d --query "[?starts_with(name,'pgnode')].[name,publicIps,privateIps,location]" | 
					
						
							|  |  |  | __cloud_FindInstances() { | 
					
						
							|  |  |  |   case $1 in | 
					
						
							|  |  |  |     prefix) | 
					
						
							|  |  |  |       query="[?starts_with(name,'$2')]" | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |     name) | 
					
						
							|  |  |  |       query="[?name=='$2']" | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |     *) | 
					
						
							|  |  |  |       echo "Unknown filter command: $1" | 
					
						
							|  |  |  |       ;; | 
					
						
							|  |  |  |   esac | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   keys="[name,publicIps,privateIps,location]" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   instances=() | 
					
						
							|  |  |  |   while read -r name publicIp privateIp location; do | 
					
						
							|  |  |  |     instances+=("$name:$publicIp:$privateIp:$location") | 
					
						
							|  |  |  |   done < <(az vm list -d -o tsv --query "$query.$keys") | 
					
						
							|  |  |  |   echo "${instances[*]}" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_FindInstances [namePrefix] | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Find instances with names matching the specified prefix | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # For each matching instance, an entry in the `instances` array will be added with the | 
					
						
							|  |  |  | # following information about the instance: | 
					
						
							|  |  |  | #   "name:public IP:private IP:location" | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # namePrefix - The instance name prefix to look for | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # examples: | 
					
						
							|  |  |  | #   $ cloud_FindInstances all-machines-with-a-common-machine-prefix | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | cloud_FindInstances() { | 
					
						
							|  |  |  |   __cloud_FindInstances prefix "$1" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_FindInstance [name] | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Find an instance with a name matching the exact pattern. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # For each matching instance, an entry in the `instances` array will be added with the | 
					
						
							|  |  |  | # following information about the instance: | 
					
						
							|  |  |  | #   "name:public IP:private IP:location" | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # name - The instance name to look for | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # examples: | 
					
						
							|  |  |  | #   $ cloud_FindInstance exact-machine-name | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | cloud_FindInstance() { | 
					
						
							|  |  |  |   __cloud_FindInstances name "$1" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_Initialize [networkName] | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Perform one-time initialization that may be required for the given testnet. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # networkName   - unique name of this testnet | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # This function will be called before |cloud_CreateInstances| | 
					
						
							|  |  |  | cloud_Initialize() { | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |   declare resourceGroup="$1" | 
					
						
							|  |  |  |   declare location="$2" | 
					
						
							|  |  |  |   declare nsgName=${resourceGroup}-nsg | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Check if resource group exists.  If not, create it. | 
					
						
							|  |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							|  |  |  |     numGroup=$(az group list --query "length([?name=='$resourceGroup'])") | 
					
						
							|  |  |  |     if [[ $numGroup -eq 0 ]]; then | 
					
						
							|  |  |  |       echo Resource Group "$resourceGroup" does not exist.  Creating it now. | 
					
						
							|  |  |  |       az group create --name "$resourceGroup" --location "$location" | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       echo Resource group "$resourceGroup" already exists. | 
					
						
							|  |  |  |       az group show --name "$resourceGroup" | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     az network nsg create --name "$nsgName" --resource-group "$resourceGroup" | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   create_nsg_rule() { | 
					
						
							|  |  |  |     ruleName="$1" | 
					
						
							|  |  |  |     ports="$2" | 
					
						
							|  |  |  |     access="$3" | 
					
						
							|  |  |  |     protocol="$4" | 
					
						
							|  |  |  |     priority="$5" | 
					
						
							|  |  |  |     ( | 
					
						
							|  |  |  |       set -x | 
					
						
							|  |  |  |       az network nsg rule create -g "${resourceGroup}" --nsg-name "${nsgName}" -n "${ruleName}" \
 | 
					
						
							|  |  |  |                                  --priority "${priority}" --source-address-prefixes "*" --source-port-ranges "*" \
 | 
					
						
							|  |  |  |                                  --destination-address-prefixes "*" --destination-port-ranges "${ports}" --access "${access}" \
 | 
					
						
							|  |  |  |                                  --protocol "${protocol}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   create_nsg_rule "InboundTCP" "8000-10000" "Allow" "Tcp" 1000 | 
					
						
							|  |  |  |   create_nsg_rule "InboundUDP" "8000-10000" "Allow" "Udp" 1001 | 
					
						
							|  |  |  |   create_nsg_rule "InboundHTTP" "80" "Allow" "Tcp" 1002 | 
					
						
							|  |  |  |   create_nsg_rule "InboundNetworkExplorerAPI" "3001" "Allow" "Tcp" 1003 | 
					
						
							|  |  |  |   create_nsg_rule "InboundDrone" "9900" "Allow" "Tcp" 1004 | 
					
						
							|  |  |  |   create_nsg_rule "InboundJsonRpc" "8899-8900" "Allow" "Tcp" 1005 | 
					
						
							|  |  |  |   create_nsg_rule "InboundRsync" "873" "Allow" "Tcp" 1006 | 
					
						
							|  |  |  |   create_nsg_rule "InboundStun" "3478" "Allow" "Udp" 1007 | 
					
						
							|  |  |  |   create_nsg_rule "InboundSSH" "22" "Allow" "Tcp" 1008 | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_CreateInstances [networkName] [namePrefix] [numNodes] [imageName] | 
					
						
							|  |  |  | #                       [machineType] [bootDiskSize] [enableGpu] | 
					
						
							|  |  |  | #                       [startupScript] [address] | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Creates one more identical instances. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # networkName   - unique name of this testnet | 
					
						
							|  |  |  | # namePrefix    - unique string to prefix all the instance names with | 
					
						
							|  |  |  | # numNodes      - number of instances to create | 
					
						
							|  |  |  | # imageName     - Disk image for the instances | 
					
						
							|  |  |  | # machineType   - GCE machine type.  Note that this may also include an | 
					
						
							|  |  |  | #                 `--accelerator=` or other |gcloud compute instances create| | 
					
						
							|  |  |  | #                 options | 
					
						
							|  |  |  | # bootDiskSize  - Optional size of the boot disk in GB | 
					
						
							|  |  |  | # enableGpu     - Optionally enable GPU, use the value "true" to enable | 
					
						
							|  |  |  | #                 eg, request 4 K80 GPUs with "count=4,type=nvidia-tesla-k80" | 
					
						
							|  |  |  | # startupScript - Optional startup script to execute when the instance boots | 
					
						
							|  |  |  | # address       - Optional name of the GCE static IP address to attach to the | 
					
						
							|  |  |  | #                 instance.  Requires that |numNodes| = 1 and that addressName | 
					
						
							|  |  |  | #                 has been provisioned in the GCE region that is hosting `$zone` | 
					
						
							| 
									
										
										
										
											2019-09-19 14:28:25 -06:00
										 |  |  | # bootDiskType  - Optional specify SSD or HDD boot disk | 
					
						
							|  |  |  | # additionalDiskSize - Optional specify size of additional storage volume | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  | # | 
					
						
							|  |  |  | # Tip: use cloud_FindInstances to locate the instances once this function | 
					
						
							|  |  |  | #      returns | 
					
						
							|  |  |  | cloud_CreateInstances() { | 
					
						
							|  |  |  |   declare networkName="$1" | 
					
						
							|  |  |  |   declare namePrefix="$2" | 
					
						
							|  |  |  |   declare numNodes="$3" | 
					
						
							|  |  |  |   declare enableGpu="$4" | 
					
						
							|  |  |  |   declare machineType="$5" | 
					
						
							|  |  |  |   declare zone="$6" | 
					
						
							|  |  |  |   declare optionalBootDiskSize="$7" | 
					
						
							|  |  |  |   declare optionalStartupScript="$8" | 
					
						
							|  |  |  |   declare optionalAddress="$9" | 
					
						
							|  |  |  |   declare optionalBootDiskType="${10}" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   declare -a nodes | 
					
						
							|  |  |  |   if [[ $numNodes = 1 ]]; then | 
					
						
							|  |  |  |     nodes=("$namePrefix") | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     for node in $(seq -f "${namePrefix}%0${#numNodes}g" 1 "$numNodes"); do | 
					
						
							|  |  |  |       nodes+=("$node") | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  |   fi | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |   nsgName=${networkName}-nsg | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   declare -a args | 
					
						
							|  |  |  |   args=( | 
					
						
							|  |  |  |     --resource-group "$networkName" | 
					
						
							|  |  |  |     --tags testnet | 
					
						
							|  |  |  |     --image UbuntuLTS | 
					
						
							|  |  |  |     --size "$machineType" | 
					
						
							| 
									
										
										
										
											2019-11-14 09:14:53 -05:00
										 |  |  |     --ssh-key-values "$(cat "${sshPrivateKey}".pub)" | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |     --location "$zone" | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |     --nsg "$nsgName" | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if [[ -n $optionalBootDiskSize ]]; then | 
					
						
							|  |  |  |     args+=( | 
					
						
							|  |  |  |       --os-disk-size-gb "$optionalBootDiskSize" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  |   if [[ -n $optionalStartupScript ]]; then | 
					
						
							|  |  |  |     args+=( | 
					
						
							|  |  |  |       --custom-data "$optionalStartupScript" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if [[ -n $optionalBootDiskType ]]; then | 
					
						
							| 
									
										
										
										
											2019-04-25 13:43:42 -06:00
										 |  |  |     args+=( | 
					
						
							|  |  |  |       --storage-sku "$optionalBootDiskType" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     args+=( | 
					
						
							|  |  |  |       --storage-sku StandardSSD_LRS | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |   fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if [[ -n $optionalAddress ]]; then | 
					
						
							|  |  |  |     [[ $numNodes = 1 ]] || { | 
					
						
							|  |  |  |       echo "Error: address may not be supplied when provisioning multiple nodes: $optionalAddress" | 
					
						
							|  |  |  |       exit 1 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     args+=( | 
					
						
							|  |  |  |       --public-ip-address "$optionalAddress" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |     # For node in numNodes, create VM and put the creation process in the background with --no-wait | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |     for nodeName in "${nodes[@]}"; do | 
					
						
							|  |  |  |       az vm create --name "$nodeName" "${args[@]}" --no-wait | 
					
						
							|  |  |  |     done | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |     for nodeName in "${nodes[@]}"; do | 
					
						
							|  |  |  |       az vm wait --created --name "$nodeName" --resource-group "$networkName" --verbose --timeout 600 | 
					
						
							|  |  |  |     done | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |     # If GPU is to be enabled, install the appropriate extension | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |     if $enableGpu; then | 
					
						
							|  |  |  |       for nodeName in "${nodes[@]}"; do | 
					
						
							|  |  |  |         az vm extension set \
 | 
					
						
							|  |  |  |         --resource-group "$networkName" \
 | 
					
						
							|  |  |  |         --vm-name "$nodeName" \
 | 
					
						
							|  |  |  |         --name NvidiaGpuDriverLinux \
 | 
					
						
							|  |  |  |         --publisher Microsoft.HpcCompute \
 | 
					
						
							|  |  |  |         --version 1.2 \
 | 
					
						
							|  |  |  |         --no-wait | 
					
						
							|  |  |  |       done | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-01 14:43:31 -06:00
										 |  |  |       # Wait until all nodes have GPU extension installed | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |       for nodeName in "${nodes[@]}"; do | 
					
						
							| 
									
										
										
										
											2019-04-25 13:43:42 -06:00
										 |  |  |         az vm wait --updated --name "$nodeName" --resource-group "$networkName" --verbose --timeout 600 | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |       done | 
					
						
							|  |  |  |     fi | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_DeleteInstances | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Deletes all the instances listed in the `instances` array | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | cloud_DeleteInstances() { | 
					
						
							|  |  |  |   if [[ ${#instances[0]} -eq 0 ]]; then | 
					
						
							|  |  |  |     echo No instances to delete | 
					
						
							|  |  |  |     return | 
					
						
							|  |  |  |   fi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   declare names=("${instances[@]/:*/}") | 
					
						
							|  |  |  |   ( | 
					
						
							|  |  |  |     set -x | 
					
						
							|  |  |  |     id_list=() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Build a space delimited list of all resource IDs to delete | 
					
						
							|  |  |  |     for instance in "${names[@]}"; do | 
					
						
							|  |  |  |       cloud_GetIdFromInstanceName "$instance" | 
					
						
							|  |  |  |       id_list+=("$id") | 
					
						
							|  |  |  |     done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete all instances in the id_list and return once they are all deleted | 
					
						
							| 
									
										
										
										
											2019-04-25 13:43:42 -06:00
										 |  |  |     az vm delete --ids "${id_list[@]}" --yes --verbose --no-wait | 
					
						
							| 
									
										
										
										
											2019-04-23 16:41:45 -06:00
										 |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_WaitForInstanceReady [instanceName] [instanceIp] [instanceZone] [timeout] | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Return once the newly created VM instance is responding.  This function is cloud-provider specific. | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | cloud_WaitForInstanceReady() { | 
					
						
							|  |  |  |   declare instanceName="$1" | 
					
						
							|  |  |  | #  declare instanceIp="$2"  # unused | 
					
						
							|  |  |  | #  declare instanceZone="$3"  # unused | 
					
						
							|  |  |  |   declare timeout="$4" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cloud_GetResourceGroupFromInstanceName "$instanceName" | 
					
						
							|  |  |  |   az vm wait -g "$resourceGroup" -n "$instanceName" --created  --interval 10 --timeout "$timeout" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_FetchFile [instanceName] [publicIp] [remoteFile] [localFile] | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Fetch a file from the given instance.  This function uses a cloud-specific | 
					
						
							|  |  |  | # mechanism to fetch the file | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | cloud_FetchFile() { | 
					
						
							|  |  |  |   declare instanceName="$1" | 
					
						
							|  |  |  |   declare publicIp="$2" | 
					
						
							|  |  |  |   declare remoteFile="$3" | 
					
						
							|  |  |  |   declare localFile="$4" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cloud_GetConfigValueFromInstanceName "$instanceName" osProfile.adminUsername | 
					
						
							|  |  |  |   scp "${config_value}@${publicIp}:${remoteFile}" "$localFile" | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-07-11 16:23:32 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_CreateAndAttachPersistentDisk | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Not yet implemented for this cloud provider | 
					
						
							|  |  |  | cloud_CreateAndAttachPersistentDisk() { | 
					
						
							|  |  |  |   echo "ERROR: cloud_CreateAndAttachPersistentDisk is not yet implemented for azure" | 
					
						
							|  |  |  |   exit 1 | 
					
						
							| 
									
										
										
										
											2019-09-19 15:08:23 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # cloud_StatusAll | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Not yet implemented for this cloud provider | 
					
						
							|  |  |  | cloud_StatusAll() { | 
					
						
							|  |  |  |   echo "ERROR: cloud_StatusAll is not yet implemented for azure" | 
					
						
							|  |  |  | } |