From c60b702e016b845ab77564a9e40b3a6b64e17188 Mon Sep 17 00:00:00 2001 From: Steven Fairchild Date: Wed, 10 Apr 2024 11:24:40 -0400 Subject: [PATCH] Update RP and Gateway vmss OS image to cbl-mariner-2-gen2-fips. Restructure VMSS bootstrap bash scripts for increased reliability, and easier debugging Move all shared code into a commonly shared file to be sourced by all bootstrapping scripts. This allows for code reuse, minimal duplication. Fix mdm mdsd certificate download script Increase rpm retry time to 30 minutes total, every 30 seconds. Install Azure Security Monitor via VMSS Extension Remove RHUI and Microsoft repo configuration, add Mariner Extended repo config Remove lvm disk resize Mariner does not use lvm, the disk is automatically grown to the full size specified. Firewalld configuration has been removed, as Mariner does not have the requirements to support the nftables backend. Firewall rules will be configured at the vnet level in Azure. Remove semanage Mariner Linux does not have selinux configured. Add changes to remove CHECKACCESS Merged in PR https://github.com/Azure/ARO-RP/pull/3643 Remove gateway log rotation config Log rotation for the podman level driver log was not the correct approach. The podman log driver is now journald, so all logs will be shipped to journald rather than a ctr.log file. During mdm and mdsd setup, I've added wait steps for the download scripts to complete getting certificates. Without this, the download scripts run in a subshell and fixing up the certificates fails. Add firewalld configuration, required for podman networking Add podman aro network creation to isolate RP containers from possible interaction on the default podman network. --- pkg/deploy/assets/env-development.json | 2 +- pkg/deploy/assets/gateway-production.json | 15 +- pkg/deploy/assets/rp-production.json | 15 +- pkg/deploy/generator/resources_dev.go | 6 +- pkg/deploy/generator/resources_gateway.go | 31 +- pkg/deploy/generator/resources_rp.go | 32 +- pkg/deploy/generator/scripts.go | 12 + pkg/deploy/generator/scripts/devProxyVMSS.sh | 1 + pkg/deploy/generator/scripts/gatewayVMSS.sh | 621 ++++----------- pkg/deploy/generator/scripts/rpVMSS.sh | 745 ++++-------------- pkg/deploy/generator/scripts/util-common.sh | 132 ++++ pkg/deploy/generator/scripts/util-packages.sh | 125 +++ pkg/deploy/generator/scripts/util-services.sh | 673 ++++++++++++++++ pkg/deploy/generator/scripts/util-system.sh | 300 +++++++ pkg/deploy/generator/scripts/util.sh | 33 + 15 files changed, 1657 insertions(+), 1086 deletions(-) create mode 100644 pkg/deploy/generator/scripts/util-common.sh create mode 100644 pkg/deploy/generator/scripts/util-packages.sh create mode 100644 pkg/deploy/generator/scripts/util-services.sh create mode 100644 pkg/deploy/generator/scripts/util-system.sh create mode 100644 pkg/deploy/generator/scripts/util.sh diff --git a/pkg/deploy/assets/env-development.json b/pkg/deploy/assets/env-development.json index ef9a60f496e..49f3529ad50 100644 --- a/pkg/deploy/assets/env-development.json +++ b/pkg/deploy/assets/env-development.json @@ -367,7 +367,7 @@ "autoUpgradeMinorVersion": true, "settings": {}, "protectedSettings": { - "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'PROXYIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('proxyImage')),''')\n','PROXYIMAGEAUTH=$(base64 -d \u003c\u003c\u003c''',base64(parameters('proxyImageAuth')),''')\n','PROXYCERT=''',parameters('proxyCert'),'''\n','PROXYCLIENTCERT=''',parameters('proxyClientCert'),'''\n','PROXYKEY=''',parameters('proxyKey'),'''\n','\n',base64ToString('I0FkZGluZyByZXRyeSBsb2dpYyB0byB5dW0gY29tbWFuZHMgaW4gb3JkZXIgdG8gYXZvaWQgc3RhbGxpbmcgb3V0IG9uIHJlc291cmNlIGxvY2tzCmVjaG8gImluc3RhbGxpbmcgbW9ieS1lbmdpbmUgKGRvY2tlcikiCmZvciBhdHRlbXB0IGluIHsxLi42MH07IGRvCgl0ZG5mIGluc3RhbGwgLXkgbW9ieS1lbmdpbmUgbW9ieS1jbGkgJiYgYnJlYWsKCWlmIFtbICR7YXR0ZW1wdH0gLWx0IDYwIF1dOyB0aGVuIHNsZWVwIDMwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKc3lzdGVtY3RsIGVuYWJsZSBkb2NrZXIKc3lzdGVtY3RsIHN0YXJ0IGRvY2tlcgoKbWtkaXIgL3Jvb3QvLmRvY2tlcgpjYXQgPi9yb290Ly5kb2NrZXIvY29uZmlnLmpzb24gPDxFT0YKewoJImF1dGhzIjogewoJCSIke1BST1hZSU1BR0UlJS8qfSI6IHsKCQkJImF1dGgiOiAiJFBST1hZSU1BR0VBVVRIIgoJCX0KCX0KfQpFT0YKCmRvY2tlciBwdWxsICIkUFJPWFlJTUFHRSIKCm1rZGlyIC9ldGMvcHJveHkKYmFzZTY0IC1kIDw8PCIkUFJPWFlDRVJUIiA+L2V0Yy9wcm94eS9wcm94eS5jcnQKYmFzZTY0IC1kIDw8PCIkUFJPWFlLRVkiID4vZXRjL3Byb3h5L3Byb3h5LmtleQpiYXNlNjQgLWQgPDw8IiRQUk9YWUNMSUVOVENFUlQiID4vZXRjL3Byb3h5L3Byb3h5LWNsaWVudC5jcnQKY2hvd24gLVIgMTAwMDoxMDAwIC9ldGMvcHJveHkKY2htb2QgMDYwMCAvZXRjL3Byb3h5L3Byb3h5LmtleQoKY2F0ID4vZXRjL3N5c2NvbmZpZy9wcm94eSA8PEVPRgpQUk9YWV9JTUFHRT0nJFBST1hZSU1BR0UnCkVPRgoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL3Byb3h5LnNlcnZpY2UgPDwnRU9GJwpbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9wcm94eQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL2RvY2tlciBybSAtZiAlbgpFeGVjU3RhcnQ9L3Vzci9iaW4vZG9ja2VyIHJ1biAtLXJtIC0tbmFtZSAlbiAtcCA0NDM6ODQ0MyAtdiAvZXRjL3Byb3h5Oi9zZWNyZXRzICRQUk9YWV9JTUFHRQpFeGVjU3RvcD0vdXNyL2Jpbi9kb2NrZXIgc3RvcCAlbgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCnN5c3RlbWN0bCBlbmFibGUgcHJveHkuc2VydmljZQoKY2F0ID4vZXRjL2Nyb24ud2Vla2x5L3B1bGwtaW1hZ2UgPDwnRU9GJwojIS9iaW4vYmFzaAoKZG9ja2VyIHB1bGwgJFBST1hZSU1BR0UKc3lzdGVtY3RsIHJlc3RhcnQgcHJveHkuc2VydmljZQpFT0YKY2htb2QgK3ggL2V0Yy9jcm9uLndlZWtseS9wdWxsLWltYWdlCgpjYXQgPi9ldGMvY3Jvbi53ZWVrbHkveXVtdXBkYXRlIDw8J0VPRicKIyEvYmluL2Jhc2gKCnl1bSB1cGRhdGUgLXkKRU9GCmNobW9kICt4IC9ldGMvY3Jvbi53ZWVrbHkveXVtdXBkYXRlCgpjYXQgPi9ldGMvY3Jvbi5kYWlseS9yZXN0YXJ0LXByb3h5IDw8J0VPRicKIyEvYmluL2Jhc2gKCnN5c3RlbWN0bCByZXN0YXJ0IHByb3h5LnNlcnZpY2UKRU9GCmNobW9kICt4IC9ldGMvY3Jvbi5kYWlseS9yZXN0YXJ0LXByb3h5CgooCglzbGVlcCAzMAoJcmVib290CikgJgo=')))]" + "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'PROXYIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('proxyImage')),''')\n','PROXYIMAGEAUTH=$(base64 -d \u003c\u003c\u003c''',base64(parameters('proxyImageAuth')),''')\n','PROXYCERT=''',parameters('proxyCert'),'''\n','PROXYCLIENTCERT=''',parameters('proxyClientCert'),'''\n','PROXYKEY=''',parameters('proxyKey'),'''\n','\n',base64ToString('IyEvYmluL2Jhc2gKI0FkZGluZyByZXRyeSBsb2dpYyB0byB5dW0gY29tbWFuZHMgaW4gb3JkZXIgdG8gYXZvaWQgc3RhbGxpbmcgb3V0IG9uIHJlc291cmNlIGxvY2tzCmVjaG8gImluc3RhbGxpbmcgbW9ieS1lbmdpbmUgKGRvY2tlcikiCmZvciBhdHRlbXB0IGluIHsxLi42MH07IGRvCgl0ZG5mIGluc3RhbGwgLXkgbW9ieS1lbmdpbmUgbW9ieS1jbGkgJiYgYnJlYWsKCWlmIFtbICR7YXR0ZW1wdH0gLWx0IDYwIF1dOyB0aGVuIHNsZWVwIDMwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKc3lzdGVtY3RsIGVuYWJsZSBkb2NrZXIKc3lzdGVtY3RsIHN0YXJ0IGRvY2tlcgoKbWtkaXIgL3Jvb3QvLmRvY2tlcgpjYXQgPi9yb290Ly5kb2NrZXIvY29uZmlnLmpzb24gPDxFT0YKewoJImF1dGhzIjogewoJCSIke1BST1hZSU1BR0UlJS8qfSI6IHsKCQkJImF1dGgiOiAiJFBST1hZSU1BR0VBVVRIIgoJCX0KCX0KfQpFT0YKCmRvY2tlciBwdWxsICIkUFJPWFlJTUFHRSIKCm1rZGlyIC9ldGMvcHJveHkKYmFzZTY0IC1kIDw8PCIkUFJPWFlDRVJUIiA+L2V0Yy9wcm94eS9wcm94eS5jcnQKYmFzZTY0IC1kIDw8PCIkUFJPWFlLRVkiID4vZXRjL3Byb3h5L3Byb3h5LmtleQpiYXNlNjQgLWQgPDw8IiRQUk9YWUNMSUVOVENFUlQiID4vZXRjL3Byb3h5L3Byb3h5LWNsaWVudC5jcnQKY2hvd24gLVIgMTAwMDoxMDAwIC9ldGMvcHJveHkKY2htb2QgMDYwMCAvZXRjL3Byb3h5L3Byb3h5LmtleQoKY2F0ID4vZXRjL3N5c2NvbmZpZy9wcm94eSA8PEVPRgpQUk9YWV9JTUFHRT0nJFBST1hZSU1BR0UnCkVPRgoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL3Byb3h5LnNlcnZpY2UgPDwnRU9GJwpbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9wcm94eQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL2RvY2tlciBybSAtZiAlbgpFeGVjU3RhcnQ9L3Vzci9iaW4vZG9ja2VyIHJ1biAtLXJtIC0tbmFtZSAlbiAtcCA0NDM6ODQ0MyAtdiAvZXRjL3Byb3h5Oi9zZWNyZXRzICRQUk9YWV9JTUFHRQpFeGVjU3RvcD0vdXNyL2Jpbi9kb2NrZXIgc3RvcCAlbgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCnN5c3RlbWN0bCBlbmFibGUgcHJveHkuc2VydmljZQoKY2F0ID4vZXRjL2Nyb24ud2Vla2x5L3B1bGwtaW1hZ2UgPDwnRU9GJwojIS9iaW4vYmFzaAoKZG9ja2VyIHB1bGwgJFBST1hZSU1BR0UKc3lzdGVtY3RsIHJlc3RhcnQgcHJveHkuc2VydmljZQpFT0YKY2htb2QgK3ggL2V0Yy9jcm9uLndlZWtseS9wdWxsLWltYWdlCgpjYXQgPi9ldGMvY3Jvbi53ZWVrbHkveXVtdXBkYXRlIDw8J0VPRicKIyEvYmluL2Jhc2gKCnl1bSB1cGRhdGUgLXkKRU9GCmNobW9kICt4IC9ldGMvY3Jvbi53ZWVrbHkveXVtdXBkYXRlCgpjYXQgPi9ldGMvY3Jvbi5kYWlseS9yZXN0YXJ0LXByb3h5IDw8J0VPRicKIyEvYmluL2Jhc2gKCnN5c3RlbWN0bCByZXN0YXJ0IHByb3h5LnNlcnZpY2UKRU9GCmNobW9kICt4IC9ldGMvY3Jvbi5kYWlseS9yZXN0YXJ0LXByb3h5CgooCglzbGVlcCAzMAoJcmVib290CikgJgo=')))]" }, "provisionAfterExtensions": [ "Microsoft.Azure.Monitor.AzureMonitorLinuxAgent", diff --git a/pkg/deploy/assets/gateway-production.json b/pkg/deploy/assets/gateway-production.json index 0c4690775c4..7d28407a363 100644 --- a/pkg/deploy/assets/gateway-production.json +++ b/pkg/deploy/assets/gateway-production.json @@ -290,7 +290,20 @@ "autoUpgradeMinorVersion": true, "settings": {}, "protectedSettings": { - "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','GATEWAYMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayMdsdConfigVersion')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayFeatures')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKCmVjaG8gInNldHRpbmcgc3NoIHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIgojIFdlIG5lZWQgdG8gbWFudWFsbHkgc2V0IFBhc3N3b3JkQXV0aGVudGljYXRpb24gdG8gdHJ1ZSBpbiBvcmRlciBmb3IgdGhlIFZNU1MgQWNjZXNzIEpJVCB0byB3b3JrCnNlZCAtaSAncy9QYXNzd29yZEF1dGhlbnRpY2F0aW9uIG5vL1Bhc3N3b3JkQXV0aGVudGljYXRpb24geWVzL2cnIC9ldGMvc3NoL3NzaGRfY29uZmlnCnN5c3RlbWN0bCByZWxvYWQgc3NoZC5zZXJ2aWNlCgojQWRkaW5nIHJldHJ5IGxvZ2ljIHRvIHl1bSBjb21tYW5kcyBpbiBvcmRlciB0byBhdm9pZCBzdGFsbGluZyBvdXQgb24gcmVzb3VyY2UgbG9ja3MKZWNobyAicnVubmluZyBSSFVJIGZpeCIKZm9yIGF0dGVtcHQgaW4gezEuLjYwfTsgZG8KICB5dW0gdXBkYXRlIC15IC0tZGlzYWJsZXJlcG89JyonIC0tZW5hYmxlcmVwbz0ncmh1aS1taWNyb3NvZnQtYXp1cmUqJyAmJiBicmVhawogIGlmIFtbICR7YXR0ZW1wdH0gLWx0IDYwIF1dOyB0aGVuIHNsZWVwIDMwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKZWNobyAicnVubmluZyB5dW0gdXBkYXRlIgpmb3IgYXR0ZW1wdCBpbiB7MS4uNjB9OyBkbwogIHl1bSAteSAteCBXQUxpbnV4QWdlbnQgLXggV0FMaW51eEFnZW50LXVkZXYgdXBkYXRlIC0tYWxsb3dlcmFzaW5nICYmIGJyZWFrCiAgaWYgW1sgJHthdHRlbXB0fSAtbHQgNjAgXV07IHRoZW4gc2xlZXAgMzA7IGVsc2UgZXhpdCAxOyBmaQpkb25lCgplY2hvICJleHRlbmRpbmcgcGFydGl0aW9uIHRhYmxlIgojIExpbnV4IGJsb2NrIGRldmljZXMgYXJlIGluY29uc2lzdGVudGx5IG5hbWVkCiMgaXQncyBkaWZmaWN1bHQgdG8gdGllIHRoZSBsdm0gcHYgdG8gdGhlIHBoeXNpY2FsIGRpc2sgdXNpbmcgL2Rldi9kaXNrIGZpbGVzLCB3aGljaCBpcyB3aHkgbHZzIGlzIHVzZWQgaGVyZQpwaHlzaWNhbF9kaXNrPSIkKGx2cyAtbyBkZXZpY2VzIC1hIHwgaGVhZCAtbjIgfCB0YWlsIC1uMSB8IGN1dCAtZCAnICcgLWYgMyB8IGN1dCAtZCBcKCAtZiAxIHwgdHIgLWQgJ1s6ZGlnaXQ6XScpIgpncm93cGFydCAiJHBoeXNpY2FsX2Rpc2siIDIKCmVjaG8gImV4dGVuZGluZyBmaWxlc3lzdGVtcyIKbHZleHRlbmQgLWwgKzIwJUZSRUUgL2Rldi9yb290dmcvcm9vdGx2Cnhmc19ncm93ZnMgLwoKbHZleHRlbmQgLWwgKzEwMCVGUkVFIC9kZXYvcm9vdHZnL3Zhcmx2Cnhmc19ncm93ZnMgL3ZhcgoKcnBtIC0taW1wb3J0IGh0dHBzOi8vZGwuZmVkb3JhcHJvamVjdC5vcmcvcHViL2VwZWwvUlBNLUdQRy1LRVktRVBFTC04CnJwbSAtLWltcG9ydCBodHRwczovL3BhY2thZ2VzLm1pY3Jvc29mdC5jb20va2V5cy9taWNyb3NvZnQuYXNjCgpmb3IgYXR0ZW1wdCBpbiB7MS4uNjB9OyBkbwogIHl1bSAteSBpbnN0YWxsIGh0dHBzOi8vZGwuZmVkb3JhcHJvamVjdC5vcmcvcHViL2VwZWwvZXBlbC1yZWxlYXNlLWxhdGVzdC04Lm5vYXJjaC5ycG0gJiYgYnJlYWsKICBpZiBbWyAke2F0dGVtcHR9IC1sdCA2MCBdXTsgdGhlbiBzbGVlcCAzMDsgZWxzZSBleGl0IDE7IGZpCmRvbmUKCmVjaG8gImNvbmZpZ3VyaW5nIGxvZ3JvdGF0ZSIKCiMgZ2F0ZXdheV9sb2dkaXIgaXMgYSByZWFkb25seSB2YXJpYWJsZSB0aGF0IHNwZWNpZmllcyB0aGUgaG9zdCBwYXRoIG1vdW50IHBvaW50IGZvciB0aGUgZ2F0ZXdheSBjb250YWluZXIgbG9nIGZpbGUKIyBmb3IgdGhlIHB1cnBvc2Ugb2Ygcm90YXRpbmcgdGhlIGdhdGV3YXkgbG9ncwpkZWNsYXJlIC1yIGdhdGV3YXlfbG9nZGlyPScvdmFyL2xvZy9hcm8tZ2F0ZXdheScKCmNhdCA+L2V0Yy9sb2dyb3RhdGUuY29uZiA8PEVPRgojIHNlZSAibWFuIGxvZ3JvdGF0ZSIgZm9yIGRldGFpbHMKIyByb3RhdGUgbG9nIGZpbGVzIHdlZWtseQp3ZWVrbHkKCiMga2VlcCAyIHdlZWtzIHdvcnRoIG9mIGJhY2tsb2dzCnJvdGF0ZSAyCgojIGNyZWF0ZSBuZXcgKGVtcHR5KSBsb2cgZmlsZXMgYWZ0ZXIgcm90YXRpbmcgb2xkIG9uZXMKY3JlYXRlCgojIHVzZSBkYXRlIGFzIGEgc3VmZml4IG9mIHRoZSByb3RhdGVkIGZpbGUKZGF0ZWV4dAoKIyB1bmNvbW1lbnQgdGhpcyBpZiB5b3Ugd2FudCB5b3VyIGxvZyBmaWxlcyBjb21wcmVzc2VkCmNvbXByZXNzCgojIFJQTSBwYWNrYWdlcyBkcm9wIGxvZyByb3RhdGlvbiBpbmZvcm1hdGlvbiBpbnRvIHRoaXMgZGlyZWN0b3J5CmluY2x1ZGUgL2V0Yy9sb2dyb3RhdGUuZAoKIyBubyBwYWNrYWdlcyBvd24gd3RtcCBhbmQgYnRtcCAtLSB3ZSdsbCByb3RhdGUgdGhlbSBoZXJlCi92YXIvbG9nL3d0bXAgewogICAgbW9udGhseQogICAgY3JlYXRlIDA2NjQgcm9vdCB1dG1wCiAgICAgICAgbWluc2l6ZSAxTQogICAgcm90YXRlIDEKfQoKL3Zhci9sb2cvYnRtcCB7CiAgICBtaXNzaW5nb2sKICAgIG1vbnRobHkKICAgIGNyZWF0ZSAwNjAwIHJvb3QgdXRtcAogICAgcm90YXRlIDEKfQoKIyBNYXhpbXVtIGxvZyBkaXJlY3Rvcnkgc2l6ZSBpcyAxMDBHIHdpdGggdGhpcyBjb25maWd1cmF0aW9uCiMgU2V0dGluZyBsaW1pdCB0byAxMDBHIHRvIGFsbG93IHNwYWNlIGZvciBvdGhlciBsb2dnaW5nIHNlcnZpY2VzCiMgY29weXRydW5jYXRlIGlzIGEgY3JpdGljYWwgb3B0aW9uIHVzZWQgdG8gcHJldmVudCBsb2dzIGZyb20gYmVpbmcgc2hpcHBlZCB0d2ljZQoke2dhdGV3YXlfbG9nZGlyfSB7CiAgICBzaXplIDIwRwogICAgcm90YXRlIDUKICAgIGNyZWF0ZSAwNjAwIHJvb3Qgcm9vdAogICAgY29weXRydW5jYXRlCiAgICBub29sZGRpcgogICAgY29tcHJlc3MKfQpFT0YKCmVjaG8gImNvbmZpZ3VyaW5nIHl1bSByZXBvc2l0b3J5IGFuZCBydW5uaW5nIHl1bSB1cGRhdGUiCmNhdCA+L2V0Yy95dW0ucmVwb3MuZC9henVyZS5yZXBvIDw8J0VPRicKW2F6dXJlLWNsaV0KbmFtZT1henVyZS1jbGkKYmFzZXVybD1odHRwczovL3BhY2thZ2VzLm1pY3Jvc29mdC5jb20veXVtcmVwb3MvYXp1cmUtY2xpCmVuYWJsZWQ9eWVzCmdwZ2NoZWNrPXllcwoKW2F6dXJlY29yZV0KbmFtZT1henVyZWNvcmUKYmFzZXVybD1odHRwczovL3BhY2thZ2VzLm1pY3Jvc29mdC5jb20veXVtcmVwb3MvYXp1cmVjb3JlCmVuYWJsZWQ9eWVzCmdwZ2NoZWNrPW5vCkVPRgoKc2VtYW5hZ2UgZmNvbnRleHQgLWEgLXQgdmFyX2xvZ190ICIvdmFyL2xvZy9qb3VybmFsKC8uKik/Igpta2RpciAtcCAvdmFyL2xvZy9qb3VybmFsCgpmb3IgYXR0ZW1wdCBpbiB7MS4uNjB9OyBkbwogIHl1bSAteSBpbnN0YWxsIGNsYW1hdiBhenNlYy1jbGFtYXYgYXpzZWMtbW9uaXRvciBhenVyZS1jbGkgYXp1cmUtbWRzZCBhenVyZS1zZWN1cml0eSBwb2RtYW4tZG9ja2VyIG9wZW5zc2wtcGVybCBweXRob24zICYmIGJyZWFrCiAgIyBoYWNrIC0gd2UgYXJlIGluc3RhbGxpbmcgcHl0aG9uMyBvbiBob3N0cyBkdWUgdG8gYW4gaXNzdWUgd2l0aCBBenVyZSBMaW51eCBFeHRlbnNpb25zIGh0dHBzOi8vZ2l0aHViLmNvbS9BenVyZS9henVyZS1saW51eC1leHRlbnNpb25zL3B1bGwvMTUwNQogIGlmIFtbICR7YXR0ZW1wdH0gLWx0IDYwIF1dOyB0aGVuIHNsZWVwIDMwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKZWNobyAiYXBwbHlpbmcgZmlyZXdhbGwgcnVsZXMiCiMgaHR0cHM6Ly9hY2Nlc3MucmVkaGF0LmNvbS9zZWN1cml0eS9jdmUvY3ZlLTIwMjAtMTM0MDEKY2F0ID4vZXRjL3N5c2N0bC5kLzAyLWRpc2FibGUtYWNjZXB0LXJhLmNvbmYgPDwnRU9GJwpuZXQuaXB2Ni5jb25mLmFsbC5hY2NlcHRfcmE9MApFT0YKCmNhdCA+L2V0Yy9zeXNjdGwuZC8wMS1kaXNhYmxlLWNvcmUuY29uZiA8PCdFT0YnCmtlcm5lbC5jb3JlX3BhdHRlcm4gPSB8L2Jpbi90cnVlCkVPRgpzeXNjdGwgLS1zeXN0ZW0KCmZpcmV3YWxsLWNtZCAtLWFkZC1wb3J0PTgwL3RjcCAtLXBlcm1hbmVudApmaXJld2FsbC1jbWQgLS1hZGQtcG9ydD04MDgxL3RjcCAtLXBlcm1hbmVudApmaXJld2FsbC1jbWQgLS1hZGQtcG9ydD00NDMvdGNwIC0tcGVybWFuZW50CgplY2hvICJsb2dnaW5nIGludG8gcHJvZCBhY3IiCmV4cG9ydCBBWlVSRV9DTE9VRF9OQU1FPSRBWlVSRUNMT1VETkFNRQpheiBsb2dpbiAtaSAtLWFsbG93LW5vLXN1YnNjcmlwdGlvbnMKCiMgVGhlIG1hbmFnZWQgaWRlbnRpdHkgdGhhdCB0aGUgVk0gcnVucyBhcyBvbmx5IGhhcyBhIHNpbmdsZSByb2xlYXNzaWdubWVudC4KIyBUaGlzIHJvbGUgYXNzaWdubWVudCBpcyBBQ1JQdWxsIHdoaWNoIGlzIG5vdCBuZWNlc3NhcmlseSBwcmVzZW50IGluIHRoZQojIHN1YnNjcmlwdGlvbiB3ZSdyZSBkZXBsb3lpbmcgaW50by4gIElmIHRoZSBpZGVudGl0eSBkb2VzIG5vdCBoYXZlIGFueQojIHJvbGUgYXNzaWdubWVudHMgc2NvcGVkIG9uIHRoZSBzdWJzY3JpcHRpb24gd2UncmUgZGVwbG95aW5nIGludG8sIGl0IHdpbGwKIyBub3Qgc2hvdyBvbiBheiBsb2dpbiAtaSwgd2hpY2ggaXMgd2h5IHRoZSBiZWxvdyBsaW5lIGlzIGNvbW1lbnRlZC4KIyBheiBhY2NvdW50IHNldCAtcyAiJFNVQlNDUklQVElPTklEIgoKIyBTdXBwcmVzcyBlbXVsYXRpb24gb3V0cHV0IGZvciBwb2RtYW4gaW5zdGVhZCBvZiBkb2NrZXIgZm9yIGF6IGFjciBjb21wYXRhYmlsaXR5Cm1rZGlyIC1wIC9ldGMvY29udGFpbmVycy8KdG91Y2ggL2V0Yy9jb250YWluZXJzL25vZG9ja2VyCgpta2RpciAtcCAvcm9vdC8uZG9ja2VyClJFR0lTVFJZX0FVVEhfRklMRT0vcm9vdC8uZG9ja2VyL2NvbmZpZy5qc29uIGF6IGFjciBsb2dpbiAtLW5hbWUgIiQoc2VkIC1lICdzfC4qL3x8JyA8PDwiJEFDUlJFU09VUkNFSUQiKSIKCk1ETUlNQUdFPSIke1JQSU1BR0UlJS8qfS8ke01ETUlNQUdFIyovfSIKZG9ja2VyIHB1bGwgIiRNRE1JTUFHRSIKZG9ja2VyIHB1bGwgIiRSUElNQUdFIgpkb2NrZXIgcHVsbCAiJEZMVUVOVEJJVElNQUdFIgoKYXogbG9nb3V0CgplY2hvICJjb25maWd1cmluZyBmbHVlbnRiaXQgc2VydmljZSIKbWtkaXIgLXAgL2V0Yy9mbHVlbnRiaXQvCm1rZGlyIC1wIC92YXIvbGliL2ZsdWVudAoKY2F0ID4vZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZiA8PCdFT0YnCltJTlBVVF0KCU5hbWUgc3lzdGVtZAoJVGFnIGpvdXJuYWxkCglTeXN0ZW1kX0ZpbHRlciBfQ09NTT1hcm8KCURCIC92YXIvbGliL2ZsdWVudC9qb3VybmFsZGIKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggam91cm5hbGQKCVJlbW92ZV93aWxkY2FyZCBfCglSZW1vdmUgVElNRVNUQU1QCgpbT1VUUFVUXQoJTmFtZSBmb3J3YXJkCglNYXRjaCAqCglQb3J0IDI5MjMwCkVPRgoKZWNobyAiRkxVRU5UQklUSU1BR0U9JEZMVUVOVEJJVElNQUdFIiA+L2V0Yy9zeXNjb25maWcvZmx1ZW50Yml0CgpjYXQgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vZmx1ZW50Yml0LnNlcnZpY2UgPDwnRU9GJwpbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApTdGFydExpbWl0SW50ZXJ2YWxTZWM9MAoKW1NlcnZpY2VdClJlc3RhcnRTZWM9MXMKRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdApFeGVjU3RhcnRQcmU9LS91c3IvYmluL2RvY2tlciBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vZG9ja2VyIHJ1biBcCiAgLS1zZWN1cml0eS1vcHQgbGFiZWw9ZGlzYWJsZSBcCiAgLS1lbnRyeXBvaW50IC9vcHQvdGQtYWdlbnQtYml0L2Jpbi90ZC1hZ2VudC1iaXQgXAogIC0tbmV0PWhvc3QgXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtdiAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZjovZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZiBcCiAgLXYgL3Zhci9saWIvZmx1ZW50Oi92YXIvbGliL2ZsdWVudDp6IFwKICAtdiAvdmFyL2xvZy9qb3VybmFsOi92YXIvbG9nL2pvdXJuYWw6cm8gXAogIC12IC9ldGMvbWFjaGluZS1pZDovZXRjL21hY2hpbmUtaWQ6cm8gXAogICRGTFVFTlRCSVRJTUFHRSBcCiAgLWMgL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYKCkV4ZWNTdG9wPS91c3IvYmluL2RvY2tlciBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9NQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CkVPRgoKZWNobyAiY29uZmlndXJpbmcgbWRtIHNlcnZpY2UiCmNhdCA+L2V0Yy9zeXNjb25maWcvbWRtIDw8RU9GCk1ETUZST05URU5EVVJMPSckTURNRlJPTlRFTkRVUkwnCk1ETUlNQUdFPSckTURNSU1BR0UnCk1ETVNPVVJDRUVOVklST05NRU5UPSckTE9DQVRJT04nCk1ETVNPVVJDRVJPTEU9Z2F0ZXdheQpNRE1TT1VSQ0VST0xFSU5TVEFOQ0U9JyQoaG9zdG5hbWUpJwpFT0YKCm1rZGlyIC92YXIvZXR3CmNhdCA+L2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZG0uc2VydmljZSA8PCdFT0YnCltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL21kbQpFeGVjU3RhcnRQcmU9LS91c3IvYmluL2RvY2tlciBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vZG9ja2VyIHJ1biBcCiAgLS1lbnRyeXBvaW50IC91c3Ivc2Jpbi9NZXRyaWNzRXh0ZW5zaW9uIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLW0gMmcgXAogIC12IC9ldGMvbWRtLnBlbTovZXRjL21kbS5wZW0gXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRNRE1JTUFHRSBcCiAgLUNlcnRGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLUZyb250RW5kVXJsICRNRE1GUk9OVEVORFVSTCBcCiAgLUxvZ2dlciBDb25zb2xlIFwKICAtTG9nTGV2ZWwgV2FybmluZyBcCiAgLVByaXZhdGVLZXlGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLVNvdXJjZUVudmlyb25tZW50ICRNRE1TT1VSQ0VFTlZJUk9OTUVOVCBcCiAgLVNvdXJjZVJvbGUgJE1ETVNPVVJDRVJPTEUgXAogIC1Tb3VyY2VSb2xlSW5zdGFuY2UgJE1ETVNPVVJDRVJPTEVJTlNUQU5DRQpFeGVjU3RvcD0vdXNyL2Jpbi9kb2NrZXIgc3RvcCAlTgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCmVjaG8gImNvbmZpZ3VyaW5nIGFyby1nYXRld2F5IHNlcnZpY2UiCmNhdCA+L2V0Yy9zeXNjb25maWcvYXJvLWdhdGV3YXkgPDxFT0YKQUNSX1JFU09VUkNFX0lEPSckQUNSUkVTT1VSQ0VJRCcKREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKTURNX0FDQ09VTlQ9IiRSUE1ETUFDQ09VTlQiCk1ETV9OQU1FU1BBQ0U9R2F0ZXdheQpHQVRFV0FZX0RPTUFJTlM9JyRHQVRFV0FZRE9NQUlOUycKR0FURVdBWV9GRUFUVVJFUz0nJEdBVEVXQVlGRUFUVVJFUycKUlBJTUFHRT0nJFJQSU1BR0UnCkVPRgoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1nYXRld2F5LnNlcnZpY2UgPDxFT0YKW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLWdhdGV3YXkKRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9kb2NrZXIgcm0gLWYgJU4KRXhlY1N0YXJ0UHJlPS91c3IvYmluL21rZGlyIC1wICR7Z2F0ZXdheV9sb2dkaXJ9CkV4ZWNTdGFydD0vdXNyL2Jpbi9kb2NrZXIgcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLWUgQUNSX1JFU09VUkNFX0lEIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9GRUFUVVJFUyBcCiAgLWUgTURNX0FDQ09VTlQgXAogIC1lIE1ETV9OQU1FU1BBQ0UgXAogIC1tIDJnIFwKICAtcCA4MDo4MDgwIFwKICAtcCA4MDgxOjgwODEgXAogIC1wIDQ0Mzo4NDQzIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgLXYgJHtnYXRld2F5X2xvZ2Rpcn06L2N0ci5sb2c6eiBcCiAgXCRSUElNQUdFIFwKICBnYXRld2F5CkV4ZWNTdG9wPS91c3IvYmluL2RvY2tlciBzdG9wIC10IDM2MDAgJU4KVGltZW91dFN0b3BTZWM9MzYwMApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCmNoY29uIC1SIHN5c3RlbV91Om9iamVjdF9yOnZhcl9sb2dfdDpzMCAvdmFyL29wdC9taWNyb3NvZnQvbGludXhtb25hZ2VudAoKbWtkaXIgLXAgL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUKCmVjaG8gImNvbmZpZ3VyaW5nIG1kc2QgYW5kIG1kbSBzZXJ2aWNlcyIKZm9yIHZhciBpbiAibWRzZCIgIm1kbSI7IGRvCmNhdCA+L2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnNlcnZpY2UgPDxFT0YKW1VuaXRdCkRlc2NyaXB0aW9uPVBlcmlvZGljICR2YXIgY3JlZGVudGlhbHMgcmVmcmVzaAoKW1NlcnZpY2VdClR5cGU9b25lc2hvdApFeGVjU3RhcnQ9L3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2ggJHZhcgpFT0YKCmNhdCA+L2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnRpbWVyIDw8RU9GCltVbml0XQpEZXNjcmlwdGlvbj1QZXJpb2RpYyAkdmFyIGNyZWRlbnRpYWxzIHJlZnJlc2gKQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1RpbWVyXQpPbkJvb3RTZWM9MG1pbgpPbkNhbGVuZGFyPTAvMTI6MDA6MDAKQWNjdXJhY3lTZWM9NXMKCltJbnN0YWxsXQpXYW50ZWRCeT10aW1lcnMudGFyZ2V0CkVPRgpkb25lCgpjYXQgPi91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIDw8RU9GCiMhL2Jpbi9iYXNoCnNldCAtZXUKCkNPTVBPTkVOVD0iXCQxIgplY2hvICJEb3dubG9hZCBcJENPTVBPTkVOVCBjcmVkZW50aWFscyIKClRFTVBfRElSPVwkKG1rdGVtcCAtZCkKZXhwb3J0IEFaVVJFX0NPTkZJR19ESVI9XCQobWt0ZW1wIC1kKQoKZWNobyAiTG9nZ2luZyBpbnRvIEF6dXJlLi4uIgpSRVRSSUVTPTMKd2hpbGUgWyAiXCRSRVRSSUVTIiAtZ3QgMCBdOyBkbwogICAgaWYgYXogbG9naW4gLWkgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCiAgICB0aGVuCiAgICAgICAgZWNobyAiYXogbG9naW4gc3VjY2Vzc2Z1bCIKICAgICAgICBicmVhawogICAgZWxzZQogICAgICAgIGVjaG8gImF6IGxvZ2luIGZhaWxlZC4gUmV0cnlpbmcuLi4iCiAgICAgICAgbGV0IFJFVFJJRVMtPTEKICAgICAgICBzbGVlcCA1CiAgICBmaQpkb25lCgp0cmFwICJjbGVhbnVwIiBFWElUCgpjbGVhbnVwKCkgewogIGF6IGxvZ291dAogIFtbICJcJFRFTVBfRElSIiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJFRFTVBfRElSCiAgW1sgIlwkQVpVUkVfQ09ORklHX0RJUiIgPX4gL3RtcC8uKyBdXSAmJiBybSAtcmYgXCRBWlVSRV9DT05GSUdfRElSCn0KCmlmIFsgIlwkQ09NUE9ORU5UIiA9ICJtZG0iIF07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT0iL2V0Yy9tZG0ucGVtIgplbGlmIFsgIlwkQ09NUE9ORU5UIiA9ICJtZHNkIiBdOyB0aGVuCiAgQ1VSUkVOVF9DRVJUX0ZJTEU9Ii92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtIgplbHNlCiAgZWNobyBJbnZhbGlkIHVzYWdlICYmIGV4aXQgMQpmaQoKU0VDUkVUX05BTUU9Imd3eS1cJHtDT01QT05FTlR9IgpORVdfQ0VSVF9GSUxFPSJcJFRFTVBfRElSL1wkQ09NUE9ORU5ULnBlbSIKZm9yIGF0dGVtcHQgaW4gezEuLjV9OyBkbwogIGF6IGtleXZhdWx0IHNlY3JldCBkb3dubG9hZCAtLWZpbGUgXCRORVdfQ0VSVF9GSUxFIC0taWQgImh0dHBzOi8vJEtFWVZBVUxUUFJFRklYLWd3eS4kS0VZVkFVTFRETlNTVUZGSVgvc2VjcmV0cy9cJFNFQ1JFVF9OQU1FIiAmJiBicmVhawogIGlmIFtbIFwkYXR0ZW1wdCAtbHQgNSBdXTsgdGhlbiBzbGVlcCAxMDsgZWxzZSBleGl0IDE7IGZpCmRvbmUKCmlmIFsgLWYgXCRORVdfQ0VSVF9GSUxFIF07IHRoZW4KICBpZiBbICJcJENPTVBPTkVOVCIgPSAibWRzZCIgXTsgdGhlbgogICAgY2hvd24gc3lzbG9nOnN5c2xvZyBcJE5FV19DRVJUX0ZJTEUKICBlbHNlCiAgICBzZWQgLWkgLW5lICcxLC9FTkQgQ0VSVElGSUNBVEUvIHAnIFwkTkVXX0NFUlRfRklMRQogIGZpCgogIG5ld19jZXJ0X3NuPSJcJChvcGVuc3NsIHg1MDkgLWluICJcJE5FV19DRVJUX0ZJTEUiIC1ub291dCAtc2VyaWFsIHwgYXdrIC1GPSAne3ByaW50IFwkMn0nKSIKICBjdXJyZW50X2NlcnRfc249IlwkKG9wZW5zc2wgeDUwOSAtaW4gIlwkQ1VSUkVOVF9DRVJUX0ZJTEUiIC1ub291dCAtc2VyaWFsIHwgYXdrIC1GPSAne3ByaW50IFwkMn0nKSIKICBpZiBbWyAhIC16IFwkbmV3X2NlcnRfc24gXV0gJiYgW1sgXCRuZXdfY2VydF9zbiAhPSAiXCRjdXJyZW50X2NlcnRfc24iIF1dOyB0aGVuCiAgICBlY2hvIHVwZGF0aW5nIGNlcnRpZmljYXRlIGZvciBcJENPTVBPTkVOVAogICAgY2htb2QgMDYwMCBcJE5FV19DRVJUX0ZJTEUKICAgIG12IFwkTkVXX0NFUlRfRklMRSBcJENVUlJFTlRfQ0VSVF9GSUxFCiAgZmkKZWxzZQogIGVjaG8gRmFpbGVkIHRvIHJlZnJlc2ggY2VydGlmaWNhdGUgZm9yIFwkQ09NUE9ORU5UICYmIGV4aXQgMQpmaQpFT0YKCmNobW9kIHUreCAvdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaAoKc3lzdGVtY3RsIGVuYWJsZSBkb3dubG9hZC1tZHNkLWNyZWRlbnRpYWxzLnRpbWVyCnN5c3RlbWN0bCBlbmFibGUgZG93bmxvYWQtbWRtLWNyZWRlbnRpYWxzLnRpbWVyCgovdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCBtZHNkCi91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIG1kbQpNRFNEQ0VSVElGSUNBVEVTQU49JChvcGVuc3NsIHg1MDkgLWluIC92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtIC1ub291dCAtc3ViamVjdCB8IHNlZCAtZSAncy8uKkNOID0gLy8nKQoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL3dhdGNoLW1kbS1jcmVkZW50aWFscy5zZXJ2aWNlIDw8RU9GCltVbml0XQpEZXNjcmlwdGlvbj1XYXRjaCBmb3IgY2hhbmdlcyBpbiBtZG0ucGVtIGFuZCByZXN0YXJ0cyB0aGUgbWRtIHNlcnZpY2UKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvYmluL3N5c3RlbWN0bCByZXN0YXJ0IG1kbS5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKRU9GCgpjYXQgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGggPDxFT0YKW1BhdGhdClBhdGhNb2RpZmllZD0vZXRjL21kbS5wZW0KCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCnN5c3RlbWN0bCBlbmFibGUgd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGgKc3lzdGVtY3RsIHN0YXJ0IHdhdGNoLW1kbS1jcmVkZW50aWFscy5wYXRoCgpta2RpciAvZXRjL3N5c3RlbWQvc3lzdGVtL21kc2Quc2VydmljZS5kCmNhdCA+L2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZHNkLnNlcnZpY2UuZC9vdmVycmlkZS5jb25mIDw8J0VPRicKW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApFT0YKCmNhdCA+L2V0Yy9kZWZhdWx0L21kc2QgPDxFT0YKTURTRF9ST0xFX1BSRUZJWD0vdmFyL3J1bi9tZHNkL2RlZmF1bHQKTURTRF9PUFRJT05TPSItQSAtZCAtciBcJE1EU0RfUk9MRV9QUkVGSVgiCgpleHBvcnQgTU9OSVRPUklOR19HQ1NfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnCmV4cG9ydCBNT05JVE9SSU5HX0dDU19BQ0NPVU5UPSckUlBNRFNEQUNDT1VOVCcKZXhwb3J0IE1PTklUT1JJTkdfR0NTX1JFR0lPTj0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdApleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRD0nJE1EU0RDRVJUSUZJQ0FURVNBTicKZXhwb3J0IE1PTklUT1JJTkdfR0NTX05BTUVTUEFDRT0nJFJQTURTRE5BTUVTUEFDRScKZXhwb3J0IE1PTklUT1JJTkdfQ09ORklHX1ZFUlNJT049JyRHQVRFV0FZTURTRENPTkZJR1ZFUlNJT04nCmV4cG9ydCBNT05JVE9SSU5HX1VTRV9HRU5FVkFfQ09ORklHX1NFUlZJQ0U9dHJ1ZQoKZXhwb3J0IE1PTklUT1JJTkdfVEVOQU5UPSckTE9DQVRJT04nCmV4cG9ydCBNT05JVE9SSU5HX1JPTEU9Z2F0ZXdheQpleHBvcnQgTU9OSVRPUklOR19ST0xFX0lOU1RBTkNFPSckKGhvc3RuYW1lKScKCmV4cG9ydCBNRFNEX01TR1BBQ0tfU09SVF9DT0xVTU5TPTEKRU9GCgojIHNldHRpbmcgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdCBzZWVtcyB0byBoYXZlIGNhdXNlZCBtZHNkIG5vdAojIHRvIGhvbm91ciBTU0xfQ0VSVF9GSUxFIGFueSBtb3JlLCBoZWF2ZW4gb25seSBrbm93cyB3aHkuCm1rZGlyIC1wIC91c3IvbGliL3NzbC9jZXJ0cwpjc3BsaXQgLWYgL3Vzci9saWIvc3NsL2NlcnRzL2NlcnQtIC1iICUwM2QucGVtIC9ldGMvcGtpL3Rscy9jZXJ0cy9jYS1idW5kbGUuY3J0IC9eJC8xIHsqfSA+L2Rldi9udWxsCmNfcmVoYXNoIC91c3IvbGliL3NzbC9jZXJ0cwoKIyB3ZSBsZWF2ZSBjbGllbnRJZCBibGFuayBhcyBsb25nIGFzIG9ubHkgMSBtYW5hZ2VkIGlkZW50aXR5IGFzc2lnbmVkIHRvIHZtc3MKIyBpZiB3ZSBoYXZlIG1vcmUgdGhhbiAxLCB3ZSB3aWxsIG5lZWQgdG8gcG9wdWxhdGUgd2l0aCBjbGllbnRJZCB1c2VkIGZvciBvZmYtbm9kZSBzY2FubmluZwpjYXQgPi9ldGMvZGVmYXVsdC92c2Etbm9kZXNjYW4tYWdlbnQuY29uZmlnIDw8RU9GCnsKICAgICJOaWNlIjogMTksCiAgICAiVGltZW91dCI6IDEwODAwLAogICAgIkNsaWVudElkIjogIiIsCiAgICAiVGVuYW50SWQiOiAiJEFaVVJFU0VDUEFDS1ZTQVRFTkFOVElEIiwKICAgICJRdWFseXNTdG9yZUJhc2VVcmwiOiAiJEFaVVJFU0VDUEFDS1FVQUxZU1VSTCIsCiAgICAiUHJvY2Vzc1RpbWVvdXQiOiAzMDAsCiAgICAiQ29tbWFuZERlbGF5IjogMAogIH0KRU9GCgplY2hvICJlbmFibGluZyBhcm8gc2VydmljZXMiCmZvciBzZXJ2aWNlIGluIGFyby1nYXRld2F5IGF1b21zIGF6c2VjZCBhenNlY21vbmQgbWRzZCBtZG0gY2hyb255ZCBmbHVlbnRiaXQ7IGRvCiAgc3lzdGVtY3RsIGVuYWJsZSAkc2VydmljZS5zZXJ2aWNlCmRvbmUKCmZvciBzY2FuIGluIGJhc2VsaW5lIGNsYW1hdiBzb2Z0d2FyZTsgZG8KICAvdXNyL2xvY2FsL2Jpbi9henNlY2QgY29uZmlnIC1zICRzY2FuIC1kIFAxRApkb25lCgplY2hvICJyZWJvb3RpbmciCnJlc3RvcmVjb24gLVJGIC92YXIvbG9nLyoKKHNsZWVwIDMwOyByZWJvb3QpICYK')))]" + "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','GATEWAYMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayMdsdConfigVersion')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayFeatures')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKIyBJbnRlcm5hbCBGdW5jdGlvbnMgYW5kIENvbnN0YW50cwoKIyBlbXB0eV9zdHIgLSBjb25zdGFudDsgdXNlZCBieSBmdW5jdGlvbnMgZm9yIG9wdGlvbmFsIG5hbWVyZWYgc3RyaW5nIGFyZ3VlbWVudHMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CmRlY2xhcmUgLXIgZW1wdHlfc3RyPSIiCgojIHJvbGVfZ2F0ZXdheSBpcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKZGVjbGFyZSAtciByb2xlX2dhdGV3YXk9ImdhdGV3YXkiCiMgcm9sZV9ycCBpcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKZGVjbGFyZSAtciByb2xlX3JwPSJycCIKCiMgbG9nIGlzIGEgd3JhcHBlciBmb3IgZWNobyB0aGF0IGluY2x1ZGVzIHRoZSBmdW5jdGlvbiBuYW1lCiMgQXJncwojIDEpIG1zZyAtIHN0cmluZwojIDIpIHN0YWNrX2xldmVsIC0gaW50OyBvcHRpb25hbCwgZGVmYXVsdHMgdG8gY2FsbGluZyBmdW5jdGlvbgpsb2coKSB7CiAgICBsb2NhbCAtciBtc2c9IiR7MTotImxvZyBtZXNzYWdlIGlzIGVtcHR5In0iCiAgICBsb2NhbCAtciBzdGFja19sZXZlbD0iJHsyOi0xfSIKICAgIGVjaG8gIiR7RlVOQ05BTUVbJHtzdGFja19sZXZlbH1dfTogJHttc2d9Igp9CgojIGFib3J0IGlzIGEgd3JhcHBlciBmb3IgbG9nIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlCmFib3J0KCkgewogICAgbG9jYWwgLXJpIG9yaWdpbl9zdGFja2xldmVsPTIKICAgIGxvZyAiJHsxfSIgIiRvcmlnaW5fc3RhY2tsZXZlbCIKICAgIGxvZyAiRXhpdGluZyIKICAgIGV4aXQgMQp9CgojIHdyaXRlX2ZpbGUKIyBBcmdzCiMgMSkgZmlsZW5hbWUgLSBzdHJpbmcKIyAyKSBmaWxlX2NvbnRlbnRzIC0gc3RyaW5nCiMgMykgY2xvYmJlciAtIGJvb2xlYW47IG9wdGlvbmFsIC0gZGVmYXVsdHMgdG8gZmFsc2UKd3JpdGVfZmlsZSgpIHsKICAgIGxvY2FsIC1uIGZpbGVuYW1lPSIkMSIKICAgIGxvY2FsIC1uIGZpbGVfY29udGVudHM9IiQyIgogICAgbG9jYWwgLXIgY2xvYmJlcj0iJHszOi1mYWxzZX0iCgogICAgaWYgJGNsb2JiZXI7IHRoZW4KICAgICAgICBsb2cgIk92ZXJ3cml0aW5nIGZpbGUgJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+ICIkZmlsZW5hbWUiCiAgICBlbHNlCiAgICAgICAgbG9nICJBcHBlbmRpbmcgdG8gJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+PiAiJGZpbGVuYW1lIgogICAgZmkKfQoKIyByZXRyeSBBZGRpbmcgcmV0cnkgbG9naWMgdG8geXVtIGNvbW1hbmRzIGluIG9yZGVyIHRvIGF2b2lkIHN0YWxsaW5nIG91dCBvbiByZXNvdXJjZSBsb2NrcwojIGFyZ3M6CiMgMSkgY21kX3JldHJ5IC0gbmFtZXJlZiwgYXJyYXk7IENvbW1hbmQgYW5kIGFyZ3VlbWVudChzKSB0byByZXRyeQojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CnJldHJ5KCkgewogICAgbG9jYWwgLW4gY21kX3JldHJ5PSIkMSIKICAgIGxvY2FsIC1uIHdhaXRfdGltZT0iJDIiCiAgICBsb2NhbCAtcmkgcmV0cmllcz0iJHszOi01fSIKCiAgICBmb3IgYXR0ZW1wdCBpbiB7MS4uNX07IGRvCiAgICAgICAgbG9nICJhdHRlbXB0ICMke2F0dGVtcHR9IC0gJHtGVU5DTkFNRVsyXX0iCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICAgICAgJHtjbWRfcmV0cnlbQF19ICYKCiAgICAgICAgd2FpdCAkISAmJiBicmVhawogICAgICAgIGlmIFsgIiR7YXR0ZW1wdH0iIC1sZSAiJHJldHJpZXMiIF07IHRoZW4KICAgICAgICAgICAgc2xlZXAgIiR3YWl0X3RpbWUiCiAgICAgICAgZWxzZQogICAgICAgICAgICBhYm9ydCAiYXR0ZW1wdCAjJHthdHRlbXB0fSAtIEZhaWxlZCB0byB1cGRhdGUgcGFja2FnZXMiCiAgICAgICAgZmkKICAgIGRvbmUKfQoKIyB2ZXJpZnlfcm9sZQojIGFyZ3M6CiMgMSkgdGVzdF9yb2xlIC0gbmFtZXJlZjsgcm9sZSBiZWluZyB2ZXJpZmllZAojIDIpIGNlcnRzIC0gYm9vbGVhbiwgb3B0aW9uYWw7IGRlZmF1bHRzIHRvIGZhbHNlLiBTZXQgdG8gdHJ1ZSB0byBhZGQgZGV2cHJveHkgdG8gYWxsb3dlZCByb2xlcwp2ZXJpZnlfcm9sZSgpIHsKICAgIGxvY2FsIC1uIHRlc3Rfcm9sZT0iJDEiCiAgICBsb2NhbCAtciBjZXJ0cz0iJHsyOi1mYWxzZX0iCgogICAgYWxsb3dlZF9yb2xlc19nbG9iPSIoJHJvbGVfcnB8JHJvbGVfZ2F0ZXdheSkiCiAgICBpZiAkY2VydHM7IHRoZW4KICAgICAgICAjIHJlbW92ZSB0cmFpbGluZyAiKSIgYW5kIGFwcGVuZCBhZGRpdGlvbmFsIHJvbGUKICAgICAgICBhbGxvd2VkX3JvbGVzX2dsb2I9IiR7YWxsb3dlZF9yb2xlc19nbG9iJVwpKn18ZGV2cHJveHkpIgogICAgZmkKCiAgICBpZiBbWyAiJHRlc3Rfcm9sZSIgPX4gJGFsbG93ZWRfcm9sZXNfZ2xvYiBdXTsgdGhlbgogICAgICAgIGxvZyAiVmVyaWZpZWQgcm9sZSBcIiR0ZXN0X3JvbGVcIiIKICAgIGVsc2UKICAgICAgICBhYm9ydCAiZmFpbGVkIHRvIHZlcmlmeSByb2xlLCByb2xlIFwiJHt0ZXN0X3JvbGV9XCIgbm90IGluIFwiJHthbGxvd2VkX3JvbGVzX2dsb2J9XCIiCiAgICBmaQp9CgojIGdldF9rZXl2YXVsdF9zdWZmaXgKIyBhcmdzOgojIDEpIHJsIC0gbmFtZXJlZiwgc3RyaW5nOyByb2xlIHRvIGdldCBzaG9ydCByb2xlIGZvcgojIDIpIGt2X3N1ZmZpeCAtIG5hbWVyZWYsIHN0cmluZzsgc2hvcnQgcm9sZSB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoaXMgbmFtZXJlZgojIDMpIHNlY19wcmVmaXggLSBuYW1lcmVmLCBzdHJpbmc7IGtleXZhdWx0IGNlcnRpZmljYXRlIHByZWZpeCB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoaXMgbmFtZXJlZgpnZXRfa2V5dmF1bHRfc3VmZml4KCkgewogICAgbG9jYWwgLW4gcmw9IiQxIgogICAgbG9jYWwgLW4ga3Zfc3VmZml4PSIkMiIKICAgIGxvY2FsIC1uIHNlY19wcmVmaXg9IiQzIgoKICAgIGxvY2FsIC1yIGtleXZhdWx0X3N1ZmZpeF9ycD0ic3ZjIgogICAgbG9jYWwgLXIga2V5dmF1bHRfcHJlZml4X2dhdGV3YXk9Imd3eSIKCiAgICBjYXNlICIkcmwiIGluCiAgICAgICAgIiRyb2xlX2dhdGV3YXkiKQogICAgICAgICAgICBrdl9zdWZmaXg9IiRrZXl2YXVsdF9wcmVmaXhfZ2F0ZXdheSIKICAgICAgICAgICAgc2VjX3ByZWZpeD0iJGtleXZhdWx0X3ByZWZpeF9nYXRld2F5IgogICAgICAgICAgICA7OwogICAgICAgICIkcm9sZV9ycCIpCiAgICAgICAgICAgIGt2X3N1ZmZpeD0iJGtleXZhdWx0X3N1ZmZpeF9ycCIKICAgICAgICAgICAgc2VjX3ByZWZpeD0iJHJvbGVfcnAiCiAgICAgICAgICAgIDs7CiAgICAgICAgKikKICAgICAgICAgICAgYWJvcnQgInVua293biByb2xlICRybCIKICAgICAgICAgICAgOzsKICAgIGVzYWMKfQoKIyByZWJvb3Rfdm0gcmVzdG9yZXMgYWxsIHNlbGludXggZmlsZSBjb250ZXh0cywgdGhlbiBzY2hlZHVsZXMgYSByZWJvb3QgZm9yIG9uZSBob3VyIGxhdGVyCiMgUmVib290cyBzaG91bGQgc2NoZWR1bGVkIGFmdGVyIGFsbCBWTSBleHRlbnNpb25zIGhhdmUgaGFkIHRpbWUgdG8gY29tcGxldGUKIyBSZWZlcmVuY2U6IGh0dHBzOi8vbGVhcm4ubWljcm9zb2Z0LmNvbS9lbi11cy9henVyZS92aXJ0dWFsLW1hY2hpbmVzL2V4dGVuc2lvbnMvY3VzdG9tLXNjcmlwdC1saW51eCN0aXBzCnJlYm9vdF92bSgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgKHNodXRkb3duIC1yIG5vdyAmKQp9CiMhL2Jpbi9iYXNoCiMgUmVwb3NpdG9yeSBhbmQgcGFja2FnZSBtYW5hZ2VtZW50IHJlbGF0ZWQgZnVuY3Rpb25zCgpjb25maWd1cmVfcmVwb19tYXJpbmVyX2V4dGVuZGVkKCkgewogICAgbG9jYWwgLXIgZXh0ZW5kZWRfcmVwb19jb25maWc9Imh0dHBzOi8vcGFja2FnZXMubWljcm9zb2Z0LmNvbS9jYmwtbWFyaW5lci8yLjAvcHJvZC9leHRlbmRlZC94ODZfNjQvY29uZmlnLnJlcG8iCiAgICBjdXJsIC1zU0wgIiRleHRlbmRlZF9yZXBvX2NvbmZpZyIgLW8gL2V0Yy95dW0ucmVwb3MuZC9tYXJpbmVyLWV4dGVuZGVkLnJlcG8KCiAgICBsb2NhbCAtciByZXBvX25hbWU9ImNibC1tYXJpbmVyMi4wcHJvZGV4dGVuZGVkeDg2XzY0IgoKICAgIGxvY2FsIC1yYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIHVwZGF0ZQogICAgICAgIC15CiAgICAgICAgLS1lbmFibGVyZXBvPSIkcmVwb19uYW1lIgogICAgKQoKICAgIGxvZyAiRW5hYmxpbmcgcmVwbyAkcmVwb19uYW1lIgogICAgcmV0cnkgY21kICIkMSIgIiR7MjotfSIKfQoKIyBjb25maWd1cmVfcnBtX3JlcG9zCiMgTmV3IHJlcG9zaXRvcmllcyBzaG91bGQgYmUgYWRkZWQgaW4gdGhlaXIgb3duIGZ1bmN0aW9ucywgYW5kIGNhbGxlZCBoZXJlCiMgYXJnczoKIyAxKSB3YWl0X3RpbWUgLSBuYW1lcmVmLCBpbnRlZ2VyOyBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJ5aW5nIGNvbW1hbmQKIyAyKSByZXRyaWVzIC0gaW50ZWdlciwgb3B0aW9uYWw7IEFtb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmNvbmZpZ3VyZV9ycG1fcmVwb3MoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGNvbmZpZ3VyZV9yZXBvX21hcmluZXJfZXh0ZW5kZWQgIiQxIiAiJHsyOi0xfSIKfQoKIyBkbmZfaW5zdGFsbF9wa2dzCiMgYXJnczoKIyAxKSBwa2dzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5OyBQYWNrYWdlcyB0byBiZSBpbnN0YWxsZWQKIyAyKSB3YWl0X3RpbWUgLSBuYW1lcmVmLCBpbnRlZ2VyOyBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJ5aW5nIGNvbW1hbmQKIyAzKSByZXRyaWVzIC0gaW50ZWdlciwgb3B0aW9uYWw7IEFtb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmRuZl9pbnN0YWxsX3BrZ3MoKSB7CiAgICBsb2NhbCAtbiBwa2dzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgbG9jYWwgLWEgY21kPSgKICAgICAgICBkbmYKICAgICAgICAteQogICAgICAgIGluc3RhbGwKICAgICkKICAgIAogICAgIyBSZWZlcmVuY2U6IGh0dHBzOi8vd3d3LnNoZWxsY2hlY2submV0L3dpa2kvU0MyMjA2CiAgICAjIGFwcGVuZCBwa2dzIGFycmF5IHRvIGNtZAogICAgbWFwZmlsZSAtTyAkKCggJHsjY21kW0BdfSArIDEgKSkgLWQgJyAnIGNtZCA8PDwgIiR7cGtnc1tAXX0iCiAgICBsb2NhbCAtciBjbWQKCiAgICBsb2cgIkF0dGVtcHRpbmcgdG8gaW5zdGFsbCBwYWNrYWdlczogJHtwa2dzWypdfSIKICAgIHJldHJ5IGNtZCAiJDIiICIkezM6LX0iCn0KCgojIGRuZl91cGRhdGVfcGtncwojIGFyZ3M6CiMgMSkgZXhjbHVkZXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXksIG9wdGlvbmFsOyBQYWNrYWdlcyB0byBleGNsdWRlIGZyb20gdXBkYXRpbmcKIyAgICAgICBFYWNoIGluZGV4IG11c3QgYmUgcHJlZml4ZWQgd2l0aCAteCAKIyAyKSB3YWl0X3RpbWUgLSBuYW1lcmVmLCBpbnRlZ2VyOyBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJ5aW5nIGNvbW1hbmQKIyAzKSByZXRyaWVzIC0gaW50ZWdlciwgb3B0aW9uYWw7IEFtbW91bnQgb2YgdGltZXMgdG8gcmV0cnkgY29tbWFuZCwgZGVmYXVsdHMgdG8gNQpkbmZfdXBkYXRlX3BrZ3MoKSB7CiAgICBsb2NhbCAtbiBleGNsdWRlcz0iJHsxOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIC15CiAgICAgICAgIyBSZXBsYWNlZCB3aXRoIGV4Y2x1ZGVzCiAgICAgICAgIiIKICAgICAgICB1cGRhdGUKICAgICAgICAtLWFsbG93ZXJhc2luZwogICAgKQoKICAgIGlmIFsgLW4gIiR7ZXhjbHVkZXN9IiBdOyB0aGVuCiAgICAgICAgIyBSZWZlcmVuY2UgaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIyMDYKICAgICAgICBtYXBmaWxlIC1PIDIgY21kIDw8PCAiJHtleGNsdWRlc1tAXX0iCiAgICBlbHNlCiAgICAgICAgIyBSZW1vdmUgZW1wdHkgc3RyaW5nIGlmIHdlIGFyZW4ndCByZXBsYWNpbmcgdGhlbSwgcHJvYmFibHkgZG9lc24ndCBtYXR0ZXIsIGJ1dCB3aHkgbm90IGJlIHNhZmUKICAgICAgICB1bnNldCAiY21kWzJdIgogICAgZmkKICAgIGxvY2FsIC1yIGNtZAoKICAgIGxvZyAiVXBkYXRpbmcgYWxsIHBhY2thZ2VzIGV4Y2x1ZGluZyBcIiR7ZXhjbHVkZXNbKl06LX1cIiIKICAgIHJldHJ5IGNtZCAiJDIiICIkezM6LX0iCn0KCiMgY29uZmlndXJlX2RuZl9jcm9uX2pvYgojIGNyZWF0ZSBjcm9uIGpvYiB0byBhdXRvIHVwZGF0ZSBycG0gcGFja2FnZXMKY29uZmlndXJlX2RuZl9jcm9uX2pvYigpIHsKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2NhbCAtciBjcm9uX3dlZWtseV9kbmZfdXBkYXRlX2ZpbGVuYW1lPScvZXRjL2Nyb24ud2Vla2x5L2RuZnVwZGF0ZScKICAgIGxvY2FsIC1yIGNyb25fd2Vla2x5X2RuZl91cGRhdGVfZmlsZT0iIyEvYmluL2Jhc2gKZG5mIHVwZGF0ZSAteSIKCiAgICB3cml0ZV9maWxlIGNyb25fd2Vla2x5X2RuZl91cGRhdGVfZmlsZW5hbWUgY3Jvbl93ZWVrbHlfZG5mX3VwZGF0ZV9maWxlIHRydWUKICAgIGNobW9kIHUreCAiJGNyb25fd2Vla2x5X2RuZl91cGRhdGVfZmlsZW5hbWUiCn0KCiMgcnBtX2ltcG9ydF9rZXlzCiMgYXJnczoKIyAxKSBrZXlzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5OyBycG0ga2V5cyB0byBiZSBpbXBvcnRlZAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZApycG1faW1wb3J0X2tleXMoKSB7CiAgICBsb2NhbCAtbiBrZXlzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Iga2V5IGluICR7a2V5c1tAXX07IGRvCiAgICAgICAgaWYgWyAkeyNrZXlzW0BdfSAtZXEgMCBdOyB0aGVuCiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgZmkKICAgICAgICAgICAgbG9jYWwgLWEgY21kPSgKICAgICAgICAgICAgICAgIHJwbQogICAgICAgICAgICAgICAgLS1pbXBvcnQKICAgICAgICAgICAgICAgIC12CiAgICAgICAgICAgICAgICAiJGtleSIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgbG9nICJJbXBvcnRpbmcgcnBtIHJlcG9zaXRvcnkga2V5ICRrZXkiCiAgICAgICAgICAgIHJldHJ5IGNtZCAiJDIiICIkezM6LX0iICYmIHVuc2V0IGtleQogICAgZG9uZQp9CiMhL2Jpbi9iYXNoCiMgQVJPIHNlcnZpY2Ugc2V0dXAgZnVuY3Rpb25zCgojIGVuYWJsZV9zZXJ2aWNlcyBlbmFibGVzIHRoZSBzeXN0ZW1kIHNlcnZpY2VzIHRoYXQgYXJlIHBhc3NlZCBpbgojIGFyZ3M6CiMgMSkgc2VydmljZXMgLSBhcnJheTsgc2VydmljZXMgdG8gYmUgZW5hYmxlZAplbmFibGVfc2VydmljZXMoKSB7CiAgICBsb2NhbCAtbiBzdmNzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKCiAgICBsb2cgImVuYWJsaW5nIHNlcnZpY2VzICR7c3Zjc1sqXX0iCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBzdmMgaW4gJHtzdmNzW0BdfTsgZG8KICAgICAgICBsb2cgIkVuYWJsaW5nIGFuZCBzdGFydGluZyAkc3ZjIG5vdyIKICAgICAgICBzeXN0ZW1jdGwgZW5hYmxlIFwKICAgICAgICAgICAgICAgICAgLS1ub3cgXAogICAgICAgICAgICAgICAgICAiJHN2YyIKICAgIGRvbmUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fZ2F0ZXdheQojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IGNvbnRhaW5lciBpbWFnZQojIDIpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IFZNU1Mgcm9sZQojIDMpIGNvbmZfZmlsZSAtIG5hbWVyZWYsIHN0cmluZzsgYXJvIGdhdGV3YXkgZW52aXJvbm1lbnQgZmlsZQojIDQpIG5ldHdvcmsgLSBuYW1lcmVmLCBzdHJpbmc7IHBvZG1hbiBuZXR3b3JrIG5hbWUgdG8gYmUgYXR0YWNoZWQKY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiByb2xlPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZfZmlsZT0iJDMiCiAgICBsb2NhbCAtbiBuZXR3b3JrPSIkNCIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIGFyby1nYXRld2F5IHNlcnZpY2UiCgogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLWdhdGV3YXknCgogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9jb25mX2ZpbGVuYW1lIGNvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1nYXRld2F5LnNlcnZpY2UnCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGU9IltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPSR7YXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZX0KRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtZSBBQ1JfUkVTT1VSQ0VfSUQgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX0ZFQVRVUkVTIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMmcgXAogIC0tbmV0d29yaz0kbmV0d29yayBcCiAgLXAgODA6ODA4MCBcCiAgLXAgODA4MTo4MDgxIFwKICAtcCA0NDM6ODQ0MyBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgJHtyb2xlLCx9CkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wIC10IDM2MDAgJU4KVGltZW91dFN0b3BTZWM9MzYwMApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldAogICAgIgoKICAgIHdyaXRlX2ZpbGUgYXJvX2dhdGV3YXlfc2VydmljZV9maWxlbmFtZSBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycAojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IFJQIGNvbnRhaW5lciBpbWFnZQojIDIpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IFZNU1Mgcm9sZQojIDMpIGNvbmZfZmlsZSAtIG5hbWVyZWYsIHN0cmluZzsgYXJvIHJwIGVudmlyb25tZW50IGZpbGUKIyA0KSBuZXR3b3JrIC0gbmFtZXJlZiwgc3RyaW5nOyBwb2RtYW4gbmV0d29yayBuYW1lIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycCgpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIHJvbGU9IiQyIgogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMyIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQ0IgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvLXJwIHNlcnZpY2UiCgogICAgbG9jYWwgLXIgYXJvX3JwX2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1ycCcKCiAgICB3cml0ZV9maWxlIGFyb19ycF9jb25mX2ZpbGVuYW1lIGNvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcnBfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tcnAuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3JwX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9JHthcm9fcnBfY29uZl9maWxlbmFtZX0KRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtZSBBQ1JfUkVTT1VSQ0VfSUQgXAogIC1lIEFETUlOX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRSBcCiAgLWUgQVJNX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRSBcCiAgLWUgQVpVUkVfQVJNX0NMSUVOVF9JRCBcCiAgLWUgQVpVUkVfRlBfQ0xJRU5UX0lEIFwKICAtZSBDTFVTVEVSX01ETV9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01ETV9OQU1FU1BBQ0UgXAogIC1lIENMVVNURVJfTURTRF9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04gXAogIC1lIENMVVNURVJfTURTRF9OQU1FU1BBQ0UgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgRE9NQUlOX05BTUUgXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9SRVNPVVJDRUdST1VQIFwKICAtZSBLRVlWQVVMVF9QUkVGSVggXAogIC1lIE1ETV9BQ0NPVU5UIFwKICAtZSBNRE1fTkFNRVNQQUNFIFwKICAtZSBNRFNEX0VOVklST05NRU5UIFwKICAtZSBSUF9GRUFUVVJFUyBcCiAgLWUgQVJPX0lOU1RBTExfVklBX0hJVkUgXAogIC1lIEFST19ISVZFX0RFRkFVTFRfSU5TVEFMTEVSX1BVTExTUEVDIFwKICAtZSBBUk9fQURPUFRfQllfSElWRSBcCiAgLWUgT0lEQ19BRkRfRU5EUE9JTlQgXAogIC1lIE9JRENfU1RPUkFHRV9BQ0NPVU5UX05BTUUgXAogIC1tIDJnIFwKICAtLW5ldHdvcms9JG5ldHdvcmsgXAogIC1wIDQ0Mzo4NDQzIFwKICAtdiAvZXRjL2Fyby1ycDovZXRjL2Fyby1ycCBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgJHtyb2xlLCx9CkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wIC10IDM2MDAgJU4KVGltZW91dFN0b3BTZWM9MzYwMApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19ycF9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19ycF9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19tb25pdG9yCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgbmV0d29yayAtIG5hbWVyZWYsIHN0cmluZzsgcG9kbWFuIG5ldHdvcmsgbmFtZSB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvcigpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvLW1vbml0b3Igc2VydmljZSIKCiAgICAjIERPTUFJTl9OQU1FLCBDTFVTVEVSX01EU0RfQUNDT1VOVCwgQ0xVU1RFUl9NRFNEX0NPTkZJR19WRVJTSU9OLCBHQVRFV0FZX0RPTUFJTlMsIEdBVEVXQVlfUkVTT1VSQ0VHUk9VUCwgTURTRF9FTlZJUk9OTUVOVCBDTFVTVEVSX01EU0RfTkFNRVNQQUNFCiAgICAjIGFyZSBub3QgdXNlZCwgYnV0IGNhbid0IGVhc2lseSBiZSByZWZhY3RvcmVkIG91dC4gU2hvdWxkIGJlIHJldmlzaXRlZCBpbiB0aGUgZnV0dXJlLgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1tb25pdG9yJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZT0iQVpVUkVfRlBfQ0xJRU5UX0lEPSckRlBDTElFTlRJRCcKRE9NQUlOX05BTUU9JyRMT0NBVElPTi4kQ0xVU1RFUlBBUkVOVERPTUFJTk5BTUUnCkNMVVNURVJfTURTRF9BQ0NPVU5UPSckQ0xVU1RFUk1EU0RBQ0NPVU5UJwpDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT049JyRDTFVTVEVSTURTRENPTkZJR1ZFUlNJT04nCkdBVEVXQVlfRE9NQUlOUz0nJEdBVEVXQVlET01BSU5TJwpHQVRFV0FZX1JFU09VUkNFR1JPVVA9JyRHQVRFV0FZUkVTT1VSQ0VHUk9VUE5BTUUnCk1EU0RfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnCkNMVVNURVJfTURTRF9OQU1FU1BBQ0U9JyRDTFVTVEVSTURTRE5BTUVTUEFDRScKQ0xVU1RFUl9NRE1fQUNDT1VOVD0nJENMVVNURVJNRE1BQ0NPVU5UJwpDTFVTVEVSX01ETV9OQU1FU1BBQ0U9QkJNCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCktFWVZBVUxUX1BSRUZJWD0nJEtFWVZBVUxUUFJFRklYJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT1CQk0KUlBJTUFHRT0nJGltYWdlJyIKCiAgICB3cml0ZV9maWxlIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZSBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1tb25pdG9yLnNlcnZpY2UnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLW1vbml0b3IKRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtLW5ldHdvcms9JG5ldHdvcmsgXAogIC1lIEFaVVJFX0ZQX0NMSUVOVF9JRCBcCiAgLWUgRE9NQUlOX05BTUUgXAogIC1lIENMVVNURVJfTURTRF9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04gXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9SRVNPVVJDRUdST1VQIFwKICAtZSBNRFNEX0VOVklST05NRU5UIFwKICAtZSBDTFVTVEVSX01EU0RfTkFNRVNQQUNFIFwKICAtZSBDTFVTVEVSX01ETV9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01ETV9OQU1FU1BBQ0UgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMi41ZyBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgbW9uaXRvcgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZW5hbWUgYXJvX21vbml0b3Jfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fcG9ydGFsCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgbmV0d29yayAtIG5hbWVyZWYsIHN0cmluZzsgcG9kbWFuIG5ldHdvcmsgbmFtZSB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fcG9ydGFsKCkgewogICAgbG9jYWwgLW4gaW1hZ2U9IiQxIgogICAgbG9jYWwgLW4gbmV0d29yaz0iJDIiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8gcG9ydGFsIHNlcnZpY2UiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZT0iQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFM9JyRQT1JUQUxBQ0NFU1NHUk9VUElEUycKQVpVUkVfUE9SVEFMX0NMSUVOVF9JRD0nJFBPUlRBTENMSUVOVElEJwpBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTPSckUE9SVEFMRUxFVkFURURHUk9VUElEUycKREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPVBvcnRhbApQT1JUQUxfSE9TVE5BTUU9JyRMT0NBVElPTi5hZG1pbi4kUlBQQVJFTlRET01BSU5OQU1FJwpSUElNQUdFPSckaW1hZ2UnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXBvcnRhbC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsPTAKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC0tbmV0d29yaz0kbmV0d29yayBcCiAgLWUgQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFMgXAogIC1lIEFaVVJFX1BPUlRBTF9DTElFTlRfSUQgXAogIC1lIEFaVVJFX1BPUlRBTF9FTEVWQVRFRF9HUk9VUF9JRFMgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLWUgUE9SVEFMX0hPU1ROQU1FIFwKICAtbSAyZyBcCiAgLXAgNDQ0Ojg0NDQgXAogIC1wIDIyMjI6MjIyMiBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgcG9ydGFsClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19wb3J0YWxfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9tZHNkCiMgYXJnczoKIyAxKSBtb25pdG9yaW5nX3JvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgojIDIpIG1vbml0b3JfY29uZmlnX3ZlcnNpb24gLSBuYW1lcmVmLCBzdHJpbmc7IG1kc2QgY29uZmlnIHZlcnNpb24KY29uZmlndXJlX3NlcnZpY2VfbWRzZCgpIHsKICAgIGxvY2FsIC1uIHJvbGU9IiQxIgogICAgbG9jYWwgLW4gbW9uaXRvcl9jb25maWdfdmVyc2lvbj0iJDIiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJjb25maWd1cmluZyBtZHNkIHNlcnZpY2UiCgogICAgdmVyaWZ5X3JvbGUgcm9sZQoKICAgIGxvY2FsIC1yIG1kc2Rfc2VydmljZV9kaXI9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vbWRzZC5zZXJ2aWNlLmQiCiAgICBta2RpciAtcCAiJG1kc2Rfc2VydmljZV9kaXIiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZW5hbWU9IiRtZHNkX3NlcnZpY2VfZGlyL292ZXJyaWRlLmNvbmYiCiAgICBsb2NhbCAtciBtZHNkX2NlcnRpZmljYXRlX3Nhbj0iJChvcGVuc3NsIHg1MDkgLWluIC92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtIC1ub291dCAtc3ViamVjdCB8IHNlZCAtZSAncy8uKkNOID0gLy8nKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGU9IltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQiCgogICAgd3JpdGVfZmlsZSBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZW5hbWUgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZGVmYXVsdF9tZHNkX2ZpbGVuYW1lPSIvZXRjL2RlZmF1bHQvbWRzZCIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZGVmYXVsdF9tZHNkX2ZpbGU9Ik1EU0RfUk9MRV9QUkVGSVg9L3Zhci9ydW4vbWRzZC9kZWZhdWx0Ck1EU0RfT1BUSU9OUz1cIi1BIC1kIC1yIFwkTURTRF9ST0xFX1BSRUZJWFwiCgpleHBvcnQgTU9OSVRPUklOR19HQ1NfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnCmV4cG9ydCBNT05JVE9SSU5HX0dDU19BQ0NPVU5UPSckUlBNRFNEQUNDT1VOVCcKZXhwb3J0IE1PTklUT1JJTkdfR0NTX1JFR0lPTj0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdApleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRD0nJG1kc2RfY2VydGlmaWNhdGVfc2FuJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfTkFNRVNQQUNFPSckUlBNRFNETkFNRVNQQUNFJwpleHBvcnQgTU9OSVRPUklOR19DT05GSUdfVkVSU0lPTj0nJG1vbml0b3JfY29uZmlnX3ZlcnNpb24nCmV4cG9ydCBNT05JVE9SSU5HX1VTRV9HRU5FVkFfQ09ORklHX1NFUlZJQ0U9dHJ1ZQoKZXhwb3J0IE1PTklUT1JJTkdfVEVOQU5UPSckTE9DQVRJT04nCmV4cG9ydCBNT05JVE9SSU5HX1JPTEU9JyRyb2xlJwpleHBvcnQgTU9OSVRPUklOR19ST0xFX0lOU1RBTkNFPVwiJChob3N0bmFtZSlcIgoKZXhwb3J0IE1EU0RfTVNHUEFDS19TT1JUX0NPTFVNTlM9XCIxXCIiCgogICAgd3JpdGVfZmlsZSBkZWZhdWx0X21kc2RfZmlsZW5hbWUgZGVmYXVsdF9tZHNkX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdAojIGFyZ3M6CiMgMSkgY29uZl9maWxlIC0gc3RyaW5nOyBmbHVlbmJpdCBjb25maWd1cmF0aW9uIGZpbGUKIyAyKSBpbWFnZSAtIHN0cmluZzsgZmx1ZW50Yml0IGNvbnRhaW5lciBpbWFnZSB0byBydW4KIyAzKSBuZXR3b3JrIC0gbmFtZXJlZiwgc3RyaW5nOyBwb2RtYW4gbmV0d29yayBuYW1lIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQzIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgZmx1ZW50Yml0IHNlcnZpY2UiCgogICAgbWtkaXIgLXAgL2V0Yy9mbHVlbnRiaXQvCiAgICBta2RpciAtcCAvdmFyL2xpYi9mbHVlbnQKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGNvbmZfZmlsZW5hbWU9Jy9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mJwogICAgd3JpdGVfZmlsZSBjb25mX2ZpbGVuYW1lIGNvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzeXNjb25maWdfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX2ZpbGU9IkZMVUVOVEJJVElNQUdFPSRpbWFnZSIKCiAgICB3cml0ZV9maWxlIHN5c2NvbmZpZ19maWxlbmFtZSBzeXNjb25maWdfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2ZsdWVudGJpdC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzZXJ2aWNlX2ZpbGU9IltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0ClN0YXJ0TGltaXRJbnRlcnZhbFNlYz0wCgpbU2VydmljZV0KUmVzdGFydFNlYz0xcwpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvZmx1ZW50Yml0CkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLXNlY3VyaXR5LW9wdCBsYWJlbD1kaXNhYmxlIFwKICAtLWVudHJ5cG9pbnQgL29wdC90ZC1hZ2VudC1iaXQvYmluL3RkLWFnZW50LWJpdCBcCiAgLS1uZXQ9aG9zdCBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC12IC9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mOi9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mIFwKICAtdiAvdmFyL2xpYi9mbHVlbnQ6L3Zhci9saWIvZmx1ZW50OnogXAogIC12IC92YXIvbG9nL2pvdXJuYWw6L3Zhci9sb2cvam91cm5hbDpybyBcCiAgLXYgL2V0Yy9tYWNoaW5lLWlkOi9ldGMvbWFjaGluZS1pZDpybyBcCiAgJGltYWdlIFwKICAtYyAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZgoKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgJU4KUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz01ClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSBzZXJ2aWNlX2ZpbGVuYW1lIHNlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3RpbWVyc19tZG1fbWRzZAojIGFyZ3M6CiMgMSkgcm9sZSAtIHN0cmluZzsgY2FuIGJlICJnYXRld2F5IiBvciAicnAiCmNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QoKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgdmVyaWZ5X3JvbGUgcm9sZQoKICAgIGxvY2FsIGtleXZhdWx0X3N1ZmZpeCBzZWNyZXRfcHJlZml4CiAgICBnZXRfa2V5dmF1bHRfc3VmZml4IHJvbGUga2V5dmF1bHRfc3VmZml4IHNlY3JldF9wcmVmaXgKCiAgICBmb3IgdmFyIGluICJtZHNkIiAibWRtIjsgZG8KICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc19zZXJ2aWNlX2ZpbGVuYW1lPSIvZXRjL3N5c3RlbWQvc3lzdGVtL2Rvd25sb2FkLSR2YXItY3JlZGVudGlhbHMuc2VydmljZSIKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc19zZXJ2aWNlX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1QZXJpb2RpYyAkdmFyIGNyZWRlbnRpYWxzIHJlZnJlc2gKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoICR2YXIiCgogICAgICAgIHdyaXRlX2ZpbGUgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlbmFtZSBkb3dubG9hZF9jcmVkc19zZXJ2aWNlX2ZpbGUgdHJ1ZQoKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgICAgIGxvY2FsIGRvd25sb2FkX2NyZWRzX3RpbWVyX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1QZXJpb2RpYyAkdmFyIGNyZWRlbnRpYWxzIHJlZnJlc2gKQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1RpbWVyXQpPbkJvb3RTZWM9MG1pbgpPbkNhbGVuZGFyPTAvMTI6MDA6MDAKQWNjdXJhY3lTZWM9NXMKCltJbnN0YWxsXQpXYW50ZWRCeT10aW1lcnMudGFyZ2V0IgoKICAgICAgICB3cml0ZV9maWxlIGRvd25sb2FkX2NyZWRzX3RpbWVyX2ZpbGVuYW1lIGRvd25sb2FkX2NyZWRzX3RpbWVyX2ZpbGUgdHJ1ZQogICAgZG9uZQoKICAgIGxvY2FsIC1yIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlbmFtZT0iL3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2giCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlPSIjIS9iaW4vYmFzaApzZXQgLWV1CgpDT01QT05FTlQ9XCQxCmVjaG8gXCJEb3dubG9hZCBcJENPTVBPTkVOVCBjcmVkZW50aWFsc1wiCgpURU1QX0RJUj1cIlwkKG1rdGVtcCAtZClcIgpleHBvcnQgQVpVUkVfQ09ORklHX0RJUj1cIlwkKG1rdGVtcCAtZClcIgoKZWNobyBcIkxvZ2dpbmcgaW50byBBenVyZS4uLlwiClJFVFJJRVM9Mwp3aGlsZSBbWyBcJFJFVFJJRVMgLWd0IDAgXV07IGRvCiAgICBpZiBheiBsb2dpbiAtaSAtLWFsbG93LW5vLXN1YnNjcmlwdGlvbnMKICAgIHRoZW4KICAgICAgICBlY2hvIFwiYXogbG9naW4gc3VjY2Vzc2Z1bFwiCiAgICAgICAgYnJlYWsKICAgIGVsc2UKICAgICAgICBlY2hvIFwiYXogbG9naW4gZmFpbGVkLiBSZXRyeWluZy4uLlwiCiAgICAgICAgbGV0IFJFVFJJRVMtPTEKICAgICAgICBzbGVlcCA1CiAgICBmaQpkb25lCgp0cmFwIFwiY2xlYW51cFwiIEVYSVQKCmNsZWFudXAoKSB7CiAgYXogbG9nb3V0CiAgW1sgXCRURU1QX0RJUiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJFRFTVBfRElSCiAgW1sgXCRBWlVSRV9DT05GSUdfRElSID1+IC90bXAvLisgXV0gJiYgcm0gLXJmIFwkQVpVUkVfQ09ORklHX0RJUgp9CgppZiBbWyBcJENPTVBPTkVOVCA9IFwibWRtXCIgXV07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT1cIi9ldGMvbWRtLnBlbVwiCmVsaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kc2RcIiBdXTsgdGhlbgogIENVUlJFTlRfQ0VSVF9GSUxFPVwiL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUvbWRzZC5wZW1cIgplbHNlCiAgZWNobyBJbnZhbGlkIHVzYWdlICYmIGV4aXQgMQpmaQoKU0VDUkVUX05BTUU9XCIkc2VjcmV0X3ByZWZpeC1cJHtDT01QT05FTlR9XCIKTkVXX0NFUlRfRklMRT1cIlwkVEVNUF9ESVIvXCRDT01QT05FTlQucGVtXCIKZm9yIGF0dGVtcHQgaW4gezEuLjV9OyBkbwogIGF6IGtleXZhdWx0IFwKICAgIHNlY3JldCBcCiAgICBkb3dubG9hZCBcCiAgICAtLWZpbGUgXCJcJE5FV19DRVJUX0ZJTEVcIiBcCiAgICAtLWlkIFwiaHR0cHM6Ly8kS0VZVkFVTFRQUkVGSVgtJGtleXZhdWx0X3N1ZmZpeC4kS0VZVkFVTFRETlNTVUZGSVgvc2VjcmV0cy9cJFNFQ1JFVF9OQU1FXCIgXAogICAgJiYgYnJlYWsKICBpZiBbWyBcJGF0dGVtcHQgLWx0IDUgXV07IHRoZW4gc2xlZXAgMTA7IGVsc2UgZXhpdCAxOyBmaQpkb25lCgppZiBbIC1mIFwkTkVXX0NFUlRfRklMRSBdOyB0aGVuCiAgaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kc2RcIiBdXTsgdGhlbgogICAgY2hvd24gc3lzbG9nOnN5c2xvZyBcJE5FV19DRVJUX0ZJTEUKICBlbHNlCiAgICBzZWQgLWkgLW5lICcxLC9FTkQgQ0VSVElGSUNBVEUvIHAnIFwkTkVXX0NFUlRfRklMRQogIGZpCgogIG5ld19jZXJ0X3NuPVwiXCQob3BlbnNzbCB4NTA5IC1pbiBcIlwkTkVXX0NFUlRfRklMRVwiIC1ub291dCAtc2VyaWFsIHwgYXdrIC1GPSAne3ByaW50IFwkMn0nKVwiCiAgY3VycmVudF9jZXJ0X3NuPVwiXCQob3BlbnNzbCB4NTA5IC1pbiBcIlwkQ1VSUkVOVF9DRVJUX0ZJTEVcIiAtbm9vdXQgLXNlcmlhbCB8IGF3ayAtRj0gJ3twcmludCBcJDJ9JylcIgogIGlmIFtbICEgLXogXCRuZXdfY2VydF9zbiBdXSAmJiBbWyBcJG5ld19jZXJ0X3NuICE9IFwiXCRjdXJyZW50X2NlcnRfc25cIiBdXTsgdGhlbgogICAgZWNobyB1cGRhdGluZyBjZXJ0aWZpY2F0ZSBmb3IgXCRDT01QT05FTlQKICAgIGNobW9kIDA2MDAgXCRORVdfQ0VSVF9GSUxFCiAgICBtdiBcJE5FV19DRVJUX0ZJTEUgXCRDVVJSRU5UX0NFUlRfRklMRQogIGZpCmVsc2UKICBlY2hvIEZhaWxlZCB0byByZWZyZXNoIGNlcnRpZmljYXRlIGZvciBcJENPTVBPTkVOVCAmJiBleGl0IDEKZmkiCgogICAgd3JpdGVfZmlsZSBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGUgdHJ1ZQoKICAgIGNobW9kIHUreCAvdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaAoKICAgICRkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgbWRzZCAmCiAgICB3YWl0ICIkISIKCgogICAgJGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlbmFtZSBtZG0gJgogICAgd2FpdCAiJCEiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS93YXRjaC1tZG0tY3JlZGVudGlhbHMuc2VydmljZSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkRlc2NyaXB0aW9uPVdhdGNoIGZvciBjaGFuZ2VzIGluIG1kbS5wZW0gYW5kIHJlc3RhcnRzIHRoZSBtZG0gc2VydmljZQoKW1NlcnZpY2VdClR5cGU9b25lc2hvdApFeGVjU3RhcnQ9L3Vzci9iaW4vc3lzdGVtY3RsIHJlc3RhcnQgbWRtLnNlcnZpY2UKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGVuYW1lIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZW5hbWU9Jy91c3IvbGliL3N5c3RlbWQvc3lzdGVtL3dhdGNoLW1kbS1jcmVkZW50aWFscy5wYXRoJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciB3YXRjaF9tZG1fY3JlZHNfcGF0aF9maWxlPSdbUGF0aF0KUGF0aE1vZGlmaWVkPS9ldGMvbWRtLnBlbQoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZW5hbWUgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZSB0cnVlCgogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzPSd3YXRjaC1tZG0tY3JlZGVudGlhbHMucGF0aCcKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgIiR3YXRjaF9tZG1fY3JlZHMiIHx8IGFib3J0ICJmYWlsZWQgdG8gZW5hYmxlIGFuZCBzdGFydCAkd2F0Y2hfbWRtX2NyZWRzIgp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX21kbQojIGFyZ3M6CiMgMSkgcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgY2FuIGJlICJnYXRld2F5IiBvciAicnAiCiMgMikgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IG1kbSBjb250YWluZXIgaW1hZ2UgdG8gcnVuCiMgMykgbmV0d29yayAtIG5hbWVyZWYsIHN0cmluZzsgcG9kbWFuIG5ldHdvcmsgbmFtZSB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9tZG0oKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQzIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgbWRtIHNlcnZpY2UiCgogICAgdmVyaWZ5X3JvbGUgcm9sZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX21kbV9maWxlbmFtZT0iL2V0Yy9zeXNjb25maWcvbWRtIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzeXNjb25maWdfbWRtX2ZpbGU9Ik1ETUZST05URU5EVVJMPSckTURNRlJPTlRFTkRVUkwnCk1ETUlNQUdFPSckaW1hZ2UnCk1ETVNPVVJDRUVOVklST05NRU5UPSckTE9DQVRJT04nCk1ETVNPVVJDRVJPTEU9JyRyb2xlJwpNRE1TT1VSQ0VST0xFSU5TVEFOQ0U9XCIkKGhvc3RuYW1lKVwiIgoKICAgIHdyaXRlX2ZpbGUgc3lzY29uZmlnX21kbV9maWxlbmFtZSBzeXNjb25maWdfbWRtX2ZpbGUgdHJ1ZQoKICAgIG1rZGlyIC1wIC92YXIvZXR3CiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kbV9zZXJ2aWNlX2ZpbGVuYW1lPSIvZXRjL3N5c3RlbWQvc3lzdGVtL21kbS5zZXJ2aWNlIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1fc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9tZG0KRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0tZW50cnlwb2ludCAvdXNyL3NiaW4vTWV0cmljc0V4dGVuc2lvbiBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC0tbmV0d29yaz0kbmV0d29yayBcCiAgLW0gMmcgXAogIC12IC9ldGMvbWRtLnBlbTovZXRjL21kbS5wZW0gXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgLUNlcnRGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLUZyb250RW5kVXJsICRNRE1GUk9OVEVORFVSTCBcCiAgLUxvZ2dlciBDb25zb2xlIFwKICAtTG9nTGV2ZWwgV2FybmluZyBcCiAgLVByaXZhdGVLZXlGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLVNvdXJjZUVudmlyb25tZW50ICRMT0NBVElPTiBcCiAgLVNvdXJjZVJvbGUgJHJvbGUgXAogIC1Tb3VyY2VSb2xlSW5zdGFuY2UgJEhPU1ROQU1FCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgbWRtX3NlcnZpY2VfZmlsZW5hbWUgbWRtX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3Ztc3NfYXJvX3NlcnZpY2UKIyBhcmdzOgojIDEpIHIgLSBuYW1lcmVmLCBzdHJpbmc7IHJvbGUgb2YgVk1TUwojIDIpIGltYWdlcyAtIG5hbWVyZWYsIGFzc29jaWF0aXZlIGFycmF5OyBBUk8gY29udGFpbmVyIGltYWdlcwojIDMpIGNvbmZpZ3MgLSBuYW1lcmVmLCBhc3NvY2lhdGl2ZSBhcnJheTsgY29uZmlndXJhdGlvbiBmaWxlcyBhbmQgdmVyc2lvbnMuIFRoZSB2YWx1ZXMgc2hvdWxkIGJlIGEgcmVmZXJlbmNlIHRvIHZhcmlhYmxlcywgbm90IGRlcmVmZXJlbmNlZC4KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgaXMgYmVjYXVzZSB0aGUgdmFsdWUgaXMgdXNlZCB3aGVuIGNyZWF0aW5nIG5hbWVyZWYgdmFyaWFibGVzIGJ5IGhlbHBlciBmdW5jdGlvbnMuCmNvbmZpZ3VyZV92bXNzX2Fyb19zZXJ2aWNlcygpIHsKICAgIGxvY2FsIC1uIHI9IiQxIgogICAgbG9jYWwgLW4gaW1hZ2VzPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZpZ3M9IiQzIgogICAgbG9nICJzdGFydGluZyIKICAgIHZlcmlmeV9yb2xlICIkMSIKCiAgICBpZiBbICIkciIgPT0gIiRyb2xlX2dhdGV3YXkiIF07IHRoZW4KICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fZ2F0ZXdheSAiJHtpbWFnZXNbInJwIl19IiAiJDEiICIke2NvbmZpZ3NbImdhdGV3YXlfY29uZmlnIl19IiAiJHtjb25maWdzWyJuZXR3b3JrIl19IgogICAgZWxpZiBbICIkciIgPT0gIiRyb2xlX3JwIiBdOyB0aGVuCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwICIke2ltYWdlc1sicnAiXX0iICIkMSIgIiR7Y29uZmlnc1sicnBfY29uZmlnIl19IiAiJHtjb25maWdzWyJuZXR3b3JrIl19IgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19tb25pdG9yICIke2ltYWdlc1sicnAiXX0iICIke2NvbmZpZ3NbIm5ldHdvcmsiXX0iCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX3BvcnRhbCAiJHtpbWFnZXNbInJwIl19IiAiJHtjb25maWdzWyJuZXR3b3JrIl19IgogICAgZmkKCiAgICBjb25maWd1cmVfc2VydmljZV9mbHVlbnRiaXQgIiR7Y29uZmlnc1siZmx1ZW50Yml0Il19IiAiJHtpbWFnZXNbImZsdWVudGJpdCJdfSIgIiR7Y29uZmlnc1sibmV0d29yayJdfSIKICAgIGNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QgIiQxIgogICAgY29uZmlndXJlX3NlcnZpY2VfbWRtICIkMSIgIiR7aW1hZ2VzWyJtZG0iXX0iICIke2NvbmZpZ3NbIm5ldHdvcmsiXX0iCiAgICBjb25maWd1cmVfc2VydmljZV9tZHNkICIkMSIgIiR7Y29uZmlnc1sibWRzZCJdfSIKICAgIHJ1bl9henNlY2RfY29uZmlnX3NjYW4KfQoKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAojIFRoaXMgZmlsZSBpcyBpbnRlbmRlZCB0byBiZSBzb3VyY2VkIGJ5IGJvb3RzdHJhcHBpbmcgc2NyaXB0cyBmb3IgY29tbW9ubHkgdXNlZCBmdW5jdGlvbnMKCiMgY29uZmlndXJlX3NzaGQKIyBXZSBuZWVkIHRvIGNvbmZpZ3VyZSBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHRvIHllcyBpbiBvcmRlciBmb3IgdGhlIFZNU1MgQWNjZXNzIEpJVCB0byB3b3JrCmNvbmZpZ3VyZV9zc2hkKCkgewogICAgbG9nICJzdGFydGluZyIKICAgIGxvY2FsIC1yIHNzaGRfY29uZmlnPSIvZXRjL3NzaC9zc2hkX2NvbmZpZyIKCiAgICBsb2cgIkVkaXRpbmcgJHNzaGRfY29uZmlnIHRvIGFsbG93IHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIgogICAgc2VkIC1pICdzL1Bhc3N3b3JkQXV0aGVudGljYXRpb24gbm8vUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvZycgIiRzc2hkX2NvbmZpZyIKCiAgICBzeXN0ZW1jdGwgcmVsb2FkIHNzaGQuc2VydmljZSB8fCBhYm9ydCAic3NoZCBmYWlsZWQgdG8gcmVsb2FkIgp9CgojIGNvbmZpZ3VyZV9sb2dyb3RhdGUgY2xvYmJlcnMgL2V0Yy9sb2dyb3RhdGUuY29uZgojIGFyZ3M6CiMgMSkgZHJvcGluX2ZpbGVzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXksIG9wdGlvbmFsOyBsb2dyb3RhdGUgZmlsZXMgdG8gd3JpdGUgdG8gL2V0Yy9sb2dyb3RhdGUuZAojICAgICAgIEtleSBuYW1lIGRpY3RhdGVzIGZpbGVuYW1lcyB3cml0dGVuIHRvIC9ldGMvbG9ncm90YXRlLmQuCiMgRXhhbXBsZTogCiMgICBLZXkgZGljdGF0ZXMgdGhlIGZpbGVuYW1lIHdyaXR0ZW4gaW4gL2V0Yy9sb2dyb3RhdGUuZAojICAgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAojICAgbG9jYWwgLXJBIGxvZ3JvdGF0ZV9kcm9waW5zPSgKIyAgICAgIFsiZ2F0ZXdheSJdPSIkZ2F0ZXdheV9sb2dfZmlsZSIKIyAgICkKY29uZmlndXJlX2xvZ3JvdGF0ZSgpIHsKICAgIGxvY2FsIC1uIGRyb3Bpbl9maWxlcz0iJHsxOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGxvZ3JvdGF0ZV9jb25mX2ZpbGVuYW1lPScvZXRjL2xvZ3JvdGF0ZS5jb25mJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBsb2dyb3RhdGVfY29uZl9maWxlPScjIHNlZSAibWFuIGxvZ3JvdGF0ZSIgZm9yIGRldGFpbHMKIyByb3RhdGUgbG9nIGZpbGVzIHdlZWtseQp3ZWVrbHkKCiMga2VlcCAyIHdlZWtzIHdvcnRoIG9mIGJhY2tsb2dzCnJvdGF0ZSAyCgojIGNyZWF0ZSBuZXcgKGVtcHR5KSBsb2cgZmlsZXMgYWZ0ZXIgcm90YXRpbmcgb2xkIG9uZXMKY3JlYXRlCgojIHVzZSBkYXRlIGFzIGEgc3VmZml4IG9mIHRoZSByb3RhdGVkIGZpbGUKZGF0ZWV4dAoKIyB1bmNvbW1lbnQgdGhpcyBpZiB5b3Ugd2FudCB5b3VyIGxvZyBmaWxlcyBjb21wcmVzc2VkCmNvbXByZXNzCgojIFJQTSBwYWNrYWdlcyBkcm9wIGxvZyByb3RhdGlvbiBpbmZvcm1hdGlvbiBpbnRvIHRoaXMgZGlyZWN0b3J5CmluY2x1ZGUgL2V0Yy9sb2dyb3RhdGUuZAoKIyBubyBwYWNrYWdlcyBvd24gd3RtcCBhbmQgYnRtcCAtLSB3ZSB3aWxsIHJvdGF0ZSB0aGVtIGhlcmUKL3Zhci9sb2cvd3RtcCB7CiAgICBtb250aGx5CiAgICBjcmVhdGUgMDY2NCByb290IHV0bXAKICAgICAgICBtaW5zaXplIDFNCiAgICByb3RhdGUgMQp9CgovdmFyL2xvZy9idG1wIHsKICAgIG1pc3NpbmdvawogICAgbW9udGhseQogICAgY3JlYXRlIDA2MDAgcm9vdCB1dG1wCiAgICByb3RhdGUgMQp9JwoKICAgIHdyaXRlX2ZpbGUgbG9ncm90YXRlX2NvbmZfZmlsZW5hbWUgbG9ncm90YXRlX2NvbmZfZmlsZSB0cnVlCgogICAgaWYgWyAtbiAiJHtkcm9waW5fZmlsZXNbKl19IiBdOyB0aGVuCiAgICAgICAgbG9jYWwgLXIgbG9ncm90YXRlX2Q9Ii9ldGMvbG9ncm90YXRlLmQiCiAgICAgICAgbG9nICJXcml0aW5nIGxvZ3JvdGF0ZSBmaWxlcyB0byAkbG9ncm90YXRlX2QiCiAgICAgICAgZm9yIGRyb3Bpbl9uYW1lIGluICIkeyFkcm9waW5fZmlsZXNbQF19IjsgZG8KICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlbmFtZT0iJGxvZ3JvdGF0ZV9kLyRkcm9waW5fbmFtZSIKICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlPSIke2Ryb3Bpbl9maWxlc1siJGRyb3Bpbl9uYW1lIl19IgogICAgICAgICAgICB3cml0ZV9maWxlIGRyb3Bpbl9maWxlbmFtZSBkcm9waW5fZmlsZSB0cnVlCiAgICAgICAgZG9uZQogICAgZmkKfQoKIyBwdWxsX2NvbnRhaW5lcl9pbWFnZXMKIyBhcmdzOgojIDEpIHB1bGxfaW1hZ2VzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5CiMgMikgcmVnaXN0cnlfY29uZiAtIG5hbWVyZWYsIHN0cmluZywgb3B0aW9uYWw7IHBhdGggdG8gZG9ja2VyL3BvZG1hbiBjb25maWd1cmF0aW9uIGZpbGUKcHVsbF9jb250YWluZXJfaW1hZ2VzKCkgewogICAgbG9jYWwgLW4gcHVsbF9pbWFnZXM9IiQxIgogICAgbG9jYWwgLW4gcmVnaXN0cnlfY29uZj0iJHsyOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yaSByZXRyeV90aW1lPTMwCiAgICAjIFRoZSBtYW5hZ2VkIGlkZW50aXR5IHRoYXQgdGhlIFZNIHJ1bnMgYXMgb25seSBoYXMgYSBzaW5nbGUgcm9sZWFzc2lnbm1lbnQuCiAgICAjIFRoaXMgcm9sZSBhc3NpZ25tZW50IGlzIEFDUlB1bGwgd2hpY2ggaXMgbm90IG5lY2Vzc2FyaWx5IHByZXNlbnQgaW4gdGhlCiAgICAjIHN1YnNjcmlwdGlvbiB3ZSdyZSBkZXBsb3lpbmcgaW50by4gIElmIHRoZSBpZGVudGl0eSBkb2VzIG5vdCBoYXZlIGFueQogICAgIyByb2xlIGFzc2lnbm1lbnRzIHNjb3BlZCBvbiB0aGUgc3Vic2NyaXB0aW9uIHdlJ3JlIGRlcGxveWluZyBpbnRvLCBpdCB3aWxsCiAgICAjIG5vdCBzaG93IG9uIGF6IGxvZ2luIC1pLCB3aGljaCBpcyB3aHkgdGhlIGJlbG93IGxpbmUgaXMgY29tbWVudGVkLgogICAgIyBheiBhY2NvdW50IHNldCAtcyAiJFNVQlNDUklQVElPTklEIgogICAgY21kPSgKICAgICAgICBhegogICAgICAgIGxvZ2luCiAgICAgICAgLWkKICAgICAgICAtLWFsbG93LW5vLXN1YnNjcmlwdGlvbnMKICAgICkKCiAgICBsb2cgIlJ1bm5pbmcgYXogbG9naW4gd2l0aCByZXRyaWVzIgogICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKCiAgICAjIFN1cHByZXNzIGVtdWxhdGlvbiBvdXRwdXQgZm9yIHBvZG1hbiBpbnN0ZWFkIG9mIGRvY2tlciBmb3IgYXogYWNyIGNvbXBhdGFiaWxpdHkKICAgIG1rZGlyIC1wIC9ldGMvY29udGFpbmVycy8KICAgIG1rZGlyIC1wIC9yb290Ly5kb2NrZXIKICAgIHRvdWNoIC9ldGMvY29udGFpbmVycy9ub2RvY2tlcgoKICAgICMgVGhpcyBuYW1lIGlzIHVzZWQgaW4gdGhlIGNhc2UgdGhhdCBheiBhY3IgbG9naW4gc2VhcmNoZXMgZm9yIHRoaXMgaW4gaXQncyBlbnZpcm9ubWVudAogICAgZXhwb3J0IFJFR0lTVFJZX0FVVEhfRklMRT0iL3Jvb3QvLmRvY2tlci9jb25maWcuanNvbiIKICAgIAogICAgaWYgWyAtbiAiJHtyZWdpc3RyeV9jb25mfSIgXTsgdGhlbgogICAgICAgIHdyaXRlX2ZpbGUgUkVHSVNUUllfQVVUSF9GSUxFIHJlZ2lzdHJ5X2NvbmYgdHJ1ZQogICAgZmkKCiAgICBsb2cgImxvZ2dpbmcgaW50byBwcm9kIGFjciIKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBhY3IKICAgICAgICBsb2dpbgogICAgICAgIC0tbmFtZQogICAgICAgICMgVE9ETyByZXBsYWNlIHRoaXMgd2l0aCB2YXJpYWJsZSBleHBhbnNpb24KICAgICAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIwMDEKICAgICAgICAiJChzZWQgLWUgJ3N8LiovfHwnIDw8PCIkQUNSUkVTT1VSQ0VJRCIpIgogICAgKQoKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgaSBpbiAke3B1bGxfaW1hZ2VzW0BdfTsgZG8KICAgICAgICBsb2NhbCAtbiBpbWFnZT0iJGkiCiAgICAgICAgY21kPSgKICAgICAgICAgICAgcG9kbWFuCiAgICAgICAgICAgIHB1bGwKICAgICAgICAgICAgIiRpbWFnZSIKICAgICAgICApCgogICAgICAgIGxvZyAiUHVsbGluZyBpbWFnZSAkaW1hZ2Ugd2l0aCByZXRyaWVzIG5vdyIKICAgICAgICByZXRyeSBjbWQgcmV0cnlfdGltZQogICAgZG9uZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgY21kPSgKICAgICAgICBhegogICAgICAgIGxvZ291dAogICAgKQoKICAgIGxvZyAiUnVubmluZyBheiBsb2dvdXQgd2l0aCByZXRyaWVzIgogICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKfQoKIyBjb25maWd1cmVfY2VydHMKIyBhcmdzOgojIDEpIHJvbGUgLSBzdHJpbmc7IGNhbiBiZSAiZGV2cHJveHkiIG9yICJycCIKY29uZmlndXJlX2NlcnRzKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBjZXJ0aWZpY2F0ZXMgZm9yICRyb2xlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUgdHJ1ZQoKICAgIGlmIFsgIiRyb2xlIiA9PSAiZGV2cHJveHkiIF07IHRoZW4KICAgICAgICBsb2NhbCAtciBwcm94eV9jZXJ0c19iYXNlZGlyPSIvZXRjL3Byb3h5IgogICAgICAgIG1rZGlyIC1wICIkcHJveHlfY2VydHNfYmFzZWRpciIKICAgICAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUNFUlQiID4gIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmNydCIKICAgICAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUtFWSIgPiAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHkua2V5IgogICAgICAgIGJhc2U2NCAtZCA8PDwiJFBST1hZQ0xJRU5UQ0VSVCIgPiAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHktY2xpZW50LmNydCIKICAgICAgICBjaG93biAtUiAxMDAwOjEwMDAgL2V0Yy9wcm94eQogICAgICAgIGNobW9kIDA2MDAgIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmtleSIKICAgICAgICByZXR1cm4gMAogICAgZmkKCiAgICBpZiBbICIkcm9sZSIgPT0gInJwIiBdOyB0aGVuCiAgICAgICAgbG9jYWwgLXIgcnBfY2VydHNfYmFzZWRpcj0iL2V0Yy9hcm8tcnAiCiAgICAgICAgbWtkaXIgLXAgIiRycF9jZXJ0c19iYXNlZGlyIgogICAgICAgIGJhc2U2NCAtZCA8PDwiJEFETUlOQVBJQ0FCVU5ETEUiID4gIiRycF9jZXJ0c19iYXNlZGlyL2FkbWluLWNhLWJ1bmRsZS5wZW0iCiAgICAgICAgaWYgW1sgLW4gIiRBUk1BUElDQUJVTkRMRSIgXV07IHRoZW4KICAgICAgICBiYXNlNjQgLWQgPDw8IiRBUk1BUElDQUJVTkRMRSIgPiAiJHJwX2NlcnRzX2Jhc2VkaXIvYXJtLWNhLWJ1bmRsZS5wZW0iCiAgICAgICAgZmkKICAgICAgICBjaG93biAtUiAxMDAwOjEwMDAgIiRycF9jZXJ0c19iYXNlZGlyIgogICAgZmkKCiAgICAjIHNldHRpbmcgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdCBzZWVtcyB0byBoYXZlIGNhdXNlZCBtZHNkIG5vdAogICAgIyB0byBob25vdXIgU1NMX0NFUlRfRklMRSBhbnkgbW9yZSwgaGVhdmVuIG9ubHkga25vd3Mgd2h5LgogICAgbG9jYWwgLXIgc3NsX2NlcnRzX2Jhc2VkaXI9Ii91c3IvbGliL3NzbC9jZXJ0cyIKICAgIG1rZGlyIC1wICIkc3NsX2NlcnRzX2Jhc2VkaXIiCiAgICBjc3BsaXQgLWYgIiRzc2xfY2VydHNfYmFzZWRpci9jZXJ0LSIgLWIgJTAzZC5wZW0gL2V0Yy9wa2kvdGxzL2NlcnRzL2NhLWJ1bmRsZS5jcnQgL14kLzEgInsqfSIgMT4vZGV2L251bGwKICAgIGNfcmVoYXNoICIkc3NsX2NlcnRzX2Jhc2VkaXIiCgogICAgIyB3ZSBsZWF2ZSBjbGllbnRJZCBibGFuayBhcyBsb25nIGFzIG9ubHkgMSBtYW5hZ2VkIGlkZW50aXR5IGFzc2lnbmVkIHRvIHZtc3MKICAgICMgaWYgd2UgaGF2ZSBtb3JlIHRoYW4gMSwgd2Ugd2lsbCBuZWVkIHRvIHBvcHVsYXRlIHdpdGggY2xpZW50SWQgdXNlZCBmb3Igb2ZmLW5vZGUgc2Nhbm5pbmcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbm9kZXNjYW5fYWdlbnRfZmlsZW5hbWU9Ii9ldGMvZGVmYXVsdC92c2Etbm9kZXNjYW4tYWdlbnQuY29uZmlnIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBub2Rlc2Nhbl9hZ2VudF9maWxlPSJ7CiAgICBcIk5pY2VcIjogMTksCiAgICBcIlRpbWVvdXRcIjogMTA4MDAsCiAgICBcIkNsaWVudElkXCI6IFwiXCIsCiAgICBcIlRlbmFudElkXCI6ICRBWlVSRVNFQ1BBQ0tWU0FURU5BTlRJRCwKICAgIFwiUXVhbHlzU3RvcmVCYXNlVXJsXCI6ICRBWlVSRVNFQ1BBQ0tRVUFMWVNVUkwsCiAgICBcIlByb2Nlc3NUaW1lb3V0XCI6IDMwMCwKICAgIFwiQ29tbWFuZERlbGF5XCI6IDAKICB9IgoKICAgIHdyaXRlX2ZpbGUgbm9kZXNjYW5fYWdlbnRfZmlsZW5hbWUgbm9kZXNjYW5fYWdlbnRfZmlsZSB0cnVlCn0KCiMgcnVuX2F6c2VjZF9jb25maWdfc2NhbgpydW5fYXpzZWNkX2NvbmZpZ19zY2FuKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYXIgY29uZmlncz0oCiAgICAgICAgImJhc2VsaW5lIgogICAgICAgICJjbGFtYXYiCiAgICAgICAgInNvZnR3YXJlIgogICAgKQoKICAgIGxvZyAiU2Nhbm5pbmcgY29uZmlndXJhdGlvbiBmaWxlcyB3aXRoIGF6c2VjZCAke2NvbmZpZ3NbKl19IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Igc2NhbiBpbiAke2NvbmZpZ3NbQF19OyBkbwogICAgICAgIGxvZyAiU2Nhbm5pbmcgY29uZmlnIGZpbGUgJHNjYW4gbm93IgogICAgICAgIC91c3IvbG9jYWwvYmluL2F6c2VjZCBjb25maWcgLXMgIiRzY2FuIiAtZCBQMUQKICAgIGRvbmUKfQoKIyBjcmVhdGVfcmVxdWlyZWRfZGlycwpjcmVhdGVfcmVxdWlyZWRfZGlycygpIHsKICAgIGNyZWF0ZV9kaXJzPSgKICAgICAgICAvdmFyL2xvZy9qb3VybmFsCiAgICAgICAgL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUKICAgICAgICAjIERvZXMgbm90IGV4aXN0IG9uIGRldlByb3h5Vk1TUwogICAgICAgIC92YXIvb3B0L21pY3Jvc29mdC9saW51eG1vbmFnZW50CiAgICApCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgZCBpbiAke2NyZWF0ZV9kaXJzW0BdfTsgZG8KICAgICAgICBsb2cgIkNyZWF0aW5nIGRpcmVjdG9yeSAkZCIKICAgICAgICBta2RpciAtcCAiJGQiIHx8IGFib3J0ICJmYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAkZCIKICAgIGRvbmUKfQoKIyBjcmVhdGVfcG9kbWFuX25ldHdvcmtzKCkKIyBhcmdzOgojIDEpIG5ldHMgLSBuYW1lcmVmLCBhc3NvY2lhdGl2ZSBhcnJheTsgTmV0d29ya3MgdG8gYmUgY3JlYXRlZAojICAgICAgIEtleSBpcyB0aGUgbmV0d29yayBuYW1lLCB2YWx1ZSBpcyB0aGUgc3VibmV0IHdpdGggY2lkciBub3RhdGlvbgpjcmVhdGVfcG9kbWFuX25ldHdvcmtzKCkgewogICAgbG9jYWwgLW4gbmV0cz0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIG4gaW4gJHshbmV0c1tAXX07IGRvCiAgICAgICAgbG9nICJDcmVhdGluZyBwb2RtYW4gbmV0d29yayBcIiRuXCIgd2l0aCBzdWJuZXQgXCIke25ldHNbJG5dfVwiIgogICAgICAgIHBvZG1hbiBuZXR3b3JrIFwKICAgICAgICAgICAgY3JlYXRlIFwKICAgICAgICAgICAgLS1zdWJuZXQgIiR7bmV0c1siJG4iXX0iIFwKICAgICAgICAgICAgIiRuIgogICAgZG9uZQp9CgojIGZpcmV3YWxsZF9jb25maWd1cmVfYmFja2VuZApmaXJld2FsbGRfY29uZmlndXJlX2JhY2tlbmQoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvZyAiQ2hhbmdpbmcgZmlyZXdhbGxkIGJhY2tlbmQgdG8gaXB0YWJsZXMiCiAgICBjb25mX2ZpbGU9Ii9ldGMvZmlyZXdhbGxkL2ZpcmV3YWxsZC5jb25mIgogICAgc2VkIC1pICdzL0ZpcmV3YWxsQmFja2VuZD1uZnRhYmxlcy9GaXJld2FsbEJhY2tlbmQ9aXB0YWJsZXMvZycgIiRjb25mX2ZpbGUiCn0KCiMgZmlyZXdhbGxkX2NvbmZpZ3VyZQojIGFyZ3M6CiMgMSkgcG9ydHMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHBvcnRzIHRvIGJlIGVuYWJsZWQuCiMgICAgICAgUG9ydHMgbXVzdCBiZSBwb3N0Zml4ZWQgd2l0aCAvdGNwIG9yIC91ZHAKZmlyZXdhbGxkX2NvbmZpZ3VyZSgpIHsKICAgIGxvY2FsIC1uIHBvcnRzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgZmlyZXdhbGxkX2NvbmZpZ3VyZV9iYWNrZW5kCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgc2VydmljZT0oCiAgICAgICAgImZpcmV3YWxsZCIKICAgICkKICAgIGVuYWJsZV9zZXJ2aWNlcyBzZXJ2aWNlCgogICAgbG9nICJFbmFibGluZyBwb3J0cyAke3BvcnRzWypdfSBvbiBkZWZhdWx0IGZpcmV3YWxsZCB6b25lIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgcG9ydCBpbiAke3BvcnRzW0BdfTsgZG8KICAgICAgICBsb2cgIkVuYWJsaW5nIHBvcnQgJHBvcnQgbm93IgogICAgICAgIGZpcmV3YWxsLWNtZCAiLS1hZGQtcG9ydD0kcG9ydCIgXAogICAgICAgICAgICAgICAgICAgICAtLXBlcm1hbmVudAogICAgZG9uZQoKICAgIGxvZyAiV3JpdGluZyBydW50aW1lIGNvbmZpZyB0byBwZXJtYW5lbnQgY29uZmlnIgogICAgZmlyZXdhbGwtY21kIC0tcnVudGltZS10by1wZXJtYW5lbnQKfQoKI1N0YXJ0IG9mIGdhdGV3YXlWTVNTLnNoCiMhL2Jpbi9iYXNoCgpzZXQgLW8gZXJyZXhpdCBcCiAgICAtbyBwaXBlZmFpbCBcCiAgICAtbyBub3Vuc2V0CgptYWluKCkgewogICAgIyB0cmFuc2FjdGlvbiBhdHRlbXB0IHJldHJ5IHRpbWUgaW4gc2Vjb25kcwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmkgcmV0cnlfd2FpdF90aW1lPTMwCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGxvY2FsIC1yaSBwa2dfcmV0cnlfY291bnQ9NjAKCiAgICBjcmVhdGVfcmVxdWlyZWRfZGlycwogICAgY29uZmlndXJlX3NzaGQKICAgIGNvbmZpZ3VyZV9ycG1fcmVwb3MgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAiJHBrZ19yZXRyeV9jb3VudCIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1hciBleGNsdWRlX3BrZ3M9KAogICAgICAgICIteCBXQUxpbnV4QWdlbnQiCiAgICAgICAgIi14IFdBTGludXhBZ2VudC11ZGV2IgogICAgKQoKICAgIGRuZl91cGRhdGVfcGtncyBleGNsdWRlX3BrZ3MgXAogICAgICAgICAgICAgICAgICAgIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgaW5zdGFsbF9wa2dzPSgKICAgICAgICBhenVyZS1jbGkKICAgICAgICBjbGFtYXYKICAgICAgICBhenNlYy1jbGFtYXYKICAgICAgICBhenVyZS1jbGkKICAgICAgICBhenVyZS1tZHNkCiAgICAgICAgYXp1cmUtc2VjdXJpdHkKICAgICAgICBwb2RtYW4KICAgICAgICBwb2RtYW4tZG9ja2VyCiAgICAgICAgb3BlbnNzbC1wZXJsCiAgICAgICAgIyBoYWNrIC0gd2UgYXJlIGluc3RhbGxpbmcgcHl0aG9uMyBvbiBob3N0cyBkdWUgdG8gYW4gaXNzdWUgd2l0aCBBenVyZSBMaW51eCBFeHRlbnNpb25zIGh0dHBzOi8vZ2l0aHViLmNvbS9BenVyZS9henVyZS1saW51eC1leHRlbnNpb25zL3B1bGwvMTUwNQogICAgICAgIHB5dGhvbjMKICAgICAgICAjIHJlcXVpcmVkIGZvciBwb2RtYW4gbmV0d29ya2luZwogICAgICAgIGZpcmV3YWxsZAogICAgKQoKICAgIGRuZl9pbnN0YWxsX3BrZ3MgaW5zdGFsbF9wa2dzIFwKICAgICAgICAgICAgICAgICAgICAgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBUT0RPIHJlbW92ZSB0aGlzIG9uY2UgTWljcm9zb2Z0Q0JMTWFyaW5lcjpjYmwtbWFyaW5lcjpjYmwtbWFyaW5lci0yLWdlbjItZmlwcyBzdXBwb3J0cyBhdXRvbWF0aWMgdXBkYXRlcwogICAgIyBSZWZlcmVuY2U6IGh0dHBzOi8vbGVhcm4ubWljcm9zb2Z0LmNvbS9lbi11cy9henVyZS92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy1hdXRvbWF0aWMtdXBncmFkZSNzdXBwb3J0ZWQtb3MtaW1hZ2VzCiAgICBjb25maWd1cmVfZG5mX2Nyb25fam9iCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTE5CiAgICBjb25maWd1cmVfbG9ncm90YXRlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0IGRpc2FibGU9U0MyMTUzCiAgICBsb2NhbCAtciBtZG1pbWFnZT0iJHtSUElNQUdFJSUvKn0vJHtNRE1JTUFHRSMqL30iCiAgICBsb2NhbCAtciBycGltYWdlPSIkUlBJTUFHRSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZmx1ZW50Yml0X2ltYWdlPSIkRkxVRU5UQklUSU1BR0UiCiAgICAjIHZhbHVlcyBhcmUgcmVmZXJlbmNlcyB0byB2YXJpYWJsZXMsIHRoZXkgc2hvdWxkIG5vdCBiZSBkZXJlZmVyZW5jZWQgaGVyZQogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtckEgYXJvX2ltYWdlcz0oCiAgICAgICAgWyJtZG0iXT0ibWRtaW1hZ2UiCiAgICAgICAgWyJycCJdPSJycGltYWdlIgogICAgICAgIFsiZmx1ZW50Yml0Il09ImZsdWVudGJpdF9pbWFnZSIKICAgICkKCiAgICBwdWxsX2NvbnRhaW5lcl9pbWFnZXMgYXJvX2ltYWdlcwoKICAgIGxvY2FsIC1yIGFyb19uZXR3b3JrPSJhcm8iCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yQSBuZXR3b3Jrcz0oCiAgICAgICAgWyIkYXJvX25ldHdvcmsiXT0iMTkyLjE2OC4yNTQuMC8yNCIKICAgICkKICAgIGNyZWF0ZV9wb2RtYW5fbmV0d29ya3MgbmV0d29ya3MKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yYSBlbmFibGVfcG9ydHM9KAogICAgICAgICMgUlAgZ2F0ZXdheQogICAgICAgICI4MC90Y3AiCiAgICAgICAgIjgwODEvdGNwIgogICAgICAgICI0NDMvdGNwIgogICAgICAgICMgSklUIHNzaAogICAgICAgICIyMi90Y3AiCiAgICApCgogICAgZmlyZXdhbGxkX2NvbmZpZ3VyZSBlbmFibGVfcG9ydHMKCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBmbHVlbnRiaXRfY29uZl9maWxlPSJbSU5QVVRdCk5hbWUgc3lzdGVtZApUYWcgam91cm5hbGQKU3lzdGVtZF9GaWx0ZXIgX0NPTU09YXJvCkRCIC92YXIvbGliL2ZsdWVudC9qb3VybmFsZGIKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggam91cm5hbGQKCVJlbW92ZV93aWxkY2FyZCBfCglSZW1vdmUgVElNRVNUQU1QCgpbT1VUUFVUXQoJTmFtZSBmb3J3YXJkCglNYXRjaCAqCglQb3J0IDI5MjMwIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfY29uZl9maWxlPSJBQ1JfUkVTT1VSQ0VfSUQ9JyRBQ1JSRVNPVVJDRUlEJwpEQVRBQkFTRV9BQ0NPVU5UX05BTUU9JyREQVRBQkFTRUFDQ09VTlROQU1FJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT0nJHtyb2xlX2dhdGV3YXlefScKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfRkVBVFVSRVM9JyRHQVRFV0FZRkVBVFVSRVMnClJQSU1BR0U9JyRycGltYWdlJyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2RfY29uZmlnX3ZlcnNpb249IiRHQVRFV0FZTURTRENPTkZJR1ZFUlNJT04iCgogICAgIyB2YWx1ZXMgYXJlIHJlZmVyZW5jZXMgdG8gdmFyaWFibGVzLCB0aGV5IHNob3VsZCBub3QgYmUgZGVyZWZlcmVuY2VkIGhlcmUKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJBIGFyb19jb25maWdzPSgKICAgICAgICBbImdhdGV3YXlfY29uZmlnIl09ImFyb19nYXRld2F5X2NvbmZfZmlsZSIKICAgICAgICBbImZsdWVudGJpdCJdPSJmbHVlbnRiaXRfY29uZl9maWxlIgogICAgICAgIFsibWRzZCJdPSJtZHNkX2NvbmZpZ192ZXJzaW9uIgogICAgICAgIFsibmV0d29yayJdPSJhcm9fbmV0d29yayIKICAgICkKCiAgICBjb25maWd1cmVfdm1zc19hcm9fc2VydmljZXMgcm9sZV9nYXRld2F5IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm9faW1hZ2VzIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm9fY29uZmlncwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJhIGdhdGV3YXlfc2VydmljZXM9KAogICAgICAgICJhcm8tZ2F0ZXdheSIKICAgICAgICAiYXpzZWNkIgogICAgICAgICJtZHNkIgogICAgICAgICJtZG0iCiAgICAgICAgImNocm9ueWQiCiAgICAgICAgImZsdWVudGJpdCIKICAgICAgICAiZG93bmxvYWQtbWRzZC1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAiZG93bmxvYWQtbWRtLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICJmaXJld2FsbGQiCiAgICApCgogICAgZW5hYmxlX3NlcnZpY2VzIGdhdGV3YXlfc2VydmljZXMKCiAgICByZWJvb3Rfdm0KfQoKZXhwb3J0IEFaVVJFX0NMT1VEX05BTUU9IiR7QVpVUkVDTE9VRE5BTUU6PyJGYWlsZWQgdG8gY2Fycnkgb3ZlciB2YXJpYWJsZXMifSIKCiMgdXRpbC5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFRoaXMgaXMgYmVjYXVzZSBjb21tb25WTVNTLnNoIGlzIGNvbmNhdGVuYXRlZCB3aXRoIHRoaXMgc2NyaXB0CnV0aWw9InV0aWwuc2giCmlmIFsgLWYgIiR1dGlsIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwuc2gKICAgIHNvdXJjZSAiJHV0aWwiCmZpCgptYWluICIkQCIK')))]" + } + } + }, + { + "name": "AzureMonitorLinuxAgent", + "properties": { + "publisher": "Microsoft.Azure.Monitor", + "type": "AzureMonitorLinuxAgent", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "GCS_AUTO_CONFIG": true } } } diff --git a/pkg/deploy/assets/rp-production.json b/pkg/deploy/assets/rp-production.json index c073531b2bd..952d638d946 100644 --- a/pkg/deploy/assets/rp-production.json +++ b/pkg/deploy/assets/rp-production.json @@ -439,7 +439,20 @@ "autoUpgradeMinorVersion": true, "settings": {}, "protectedSettings": { - "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','ADMINAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('adminApiClientCertCommonName')),''')\n','ARMAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armApiClientCertCommonName')),''')\n','ARMCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armClientId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','CLUSTERMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdmAccount')),''')\n','CLUSTERMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdAccount')),''')\n','CLUSTERMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdConfigVersion')),''')\n','CLUSTERMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdNamespace')),''')\n','CLUSTERPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterParentDomainName')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','FPCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpClientId')),''')\n','FPSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpServicePrincipalId')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYRESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayResourceGroupName')),''')\n','GATEWAYSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayServicePrincipalId')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','PORTALACCESSGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalAccessGroupIds')),''')\n','PORTALCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalClientId')),''')\n','PORTALELEVATEDGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalElevatedGroupIds')),''')\n','RPFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpFeatures')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdConfigVersion')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','RPPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpParentDomainName')),''')\n','OIDCSTORAGEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('oidcStorageAccountName')),''')\n','CLUSTERSINSTALLVIAHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersInstallViaHive')),''')\n','CLUSTERSADOPTBYHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersAdoptByHive')),''')\n','CLUSTERDEFAULTINSTALLERPULLSPEC=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterDefaultInstallerPullspec')),''')\n','ADMINAPICABUNDLE=''',parameters('adminApiCaBundle'),'''\n','ARMAPICABUNDLE=''',parameters('armApiCaBundle'),'''\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKCmVjaG8gInNldHRpbmcgc3NoIHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIgojIFdlIG5lZWQgdG8gbWFudWFsbHkgc2V0IFBhc3N3b3JkQXV0aGVudGljYXRpb24gdG8gdHJ1ZSBpbiBvcmRlciBmb3IgdGhlIFZNU1MgQWNjZXNzIEpJVCB0byB3b3JrCnNlZCAtaSAncy9QYXNzd29yZEF1dGhlbnRpY2F0aW9uIG5vL1Bhc3N3b3JkQXV0aGVudGljYXRpb24geWVzL2cnIC9ldGMvc3NoL3NzaGRfY29uZmlnCnN5c3RlbWN0bCByZWxvYWQgc3NoZC5zZXJ2aWNlCgojQWRkaW5nIHJldHJ5IGxvZ2ljIHRvIHl1bSBjb21tYW5kcyBpbiBvcmRlciB0byBhdm9pZCBzdGFsbGluZyBvdXQgb24gcmVzb3VyY2UgbG9ja3MKZWNobyAicnVubmluZyBSSFVJIGZpeCIKZm9yIGF0dGVtcHQgaW4gezEuLjYwfTsgZG8KICB5dW0gdXBkYXRlIC15IC0tZGlzYWJsZXJlcG89JyonIC0tZW5hYmxlcmVwbz0ncmh1aS1taWNyb3NvZnQtYXp1cmUqJyAmJiBicmVhawogIGlmIFtbICR7YXR0ZW1wdH0gLWx0IDYwIF1dOyB0aGVuIHNsZWVwIDMwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKZWNobyAicnVubmluZyB5dW0gdXBkYXRlIgpmb3IgYXR0ZW1wdCBpbiB7MS4uNjB9OyBkbwogIHl1bSAteSAteCBXQUxpbnV4QWdlbnQgLXggV0FMaW51eEFnZW50LXVkZXYgdXBkYXRlIC0tYWxsb3dlcmFzaW5nICYmIGJyZWFrCiAgaWYgW1sgJHthdHRlbXB0fSAtbHQgNjAgXV07IHRoZW4gc2xlZXAgMzA7IGVsc2UgZXhpdCAxOyBmaQpkb25lCgplY2hvICJleHRlbmRpbmcgcGFydGl0aW9uIHRhYmxlIgojIExpbnV4IGJsb2NrIGRldmljZXMgYXJlIGluY29uc2lzdGVudGx5IG5hbWVkCiMgaXQncyBkaWZmaWN1bHQgdG8gdGllIHRoZSBsdm0gcHYgdG8gdGhlIHBoeXNpY2FsIGRpc2sgdXNpbmcgL2Rldi9kaXNrIGZpbGVzLCB3aGljaCBpcyB3aHkgbHZzIGlzIHVzZWQgaGVyZQpwaHlzaWNhbERpc2s9IiQobHZzIC1vIGRldmljZXMgLWEgfCBoZWFkIC1uMiB8IHRhaWwgLW4xIHwgY3V0IC1kICcgJyAtZiAzIHwgY3V0IC1kIFwoIC1mIDEgfCB0ciAtZCAnWzpkaWdpdDpdJykiCmdyb3dwYXJ0ICIkcGh5c2ljYWxEaXNrIiAyCgplY2hvICJleHRlbmRpbmcgZmlsZXN5c3RlbXMiCmx2ZXh0ZW5kIC1sICsyMCVGUkVFIC9kZXYvcm9vdHZnL3Jvb3Rsdgp4ZnNfZ3Jvd2ZzIC8KCmx2ZXh0ZW5kIC1sICsxMDAlRlJFRSAvZGV2L3Jvb3R2Zy92YXJsdgp4ZnNfZ3Jvd2ZzIC92YXIKCmVjaG8gImltcG9ydGluZyBycG0gcmVwb3NpdG9yaWVzIgpycG0gLS1pbXBvcnQgaHR0cHM6Ly9kbC5mZWRvcmFwcm9qZWN0Lm9yZy9wdWIvZXBlbC9SUE0tR1BHLUtFWS1FUEVMLTgKcnBtIC0taW1wb3J0IGh0dHBzOi8vcGFja2FnZXMubWljcm9zb2Z0LmNvbS9rZXlzL21pY3Jvc29mdC5hc2MKCmZvciBhdHRlbXB0IGluIHsxLi42MH07IGRvCiAgeXVtIC15IGluc3RhbGwgaHR0cHM6Ly9kbC5mZWRvcmFwcm9qZWN0Lm9yZy9wdWIvZXBlbC9lcGVsLXJlbGVhc2UtbGF0ZXN0LTgubm9hcmNoLnJwbSAmJiBicmVhawogIGlmIFtbICR7YXR0ZW1wdH0gLWx0IDYwIF1dOyB0aGVuIHNsZWVwIDMwOyBlbHNlIGV4aXQgMTsgZmkKZG9uZQoKZWNobyAiY29uZmlndXJpbmcgbG9ncm90YXRlIgpjYXQgPi9ldGMvbG9ncm90YXRlLmNvbmYgPDwnRU9GJwojIHNlZSAibWFuIGxvZ3JvdGF0ZSIgZm9yIGRldGFpbHMKIyByb3RhdGUgbG9nIGZpbGVzIHdlZWtseQp3ZWVrbHkKCiMga2VlcCAyIHdlZWtzIHdvcnRoIG9mIGJhY2tsb2dzCnJvdGF0ZSAyCgojIGNyZWF0ZSBuZXcgKGVtcHR5KSBsb2cgZmlsZXMgYWZ0ZXIgcm90YXRpbmcgb2xkIG9uZXMKY3JlYXRlCgojIHVzZSBkYXRlIGFzIGEgc3VmZml4IG9mIHRoZSByb3RhdGVkIGZpbGUKZGF0ZWV4dAoKIyB1bmNvbW1lbnQgdGhpcyBpZiB5b3Ugd2FudCB5b3VyIGxvZyBmaWxlcyBjb21wcmVzc2VkCmNvbXByZXNzCgojIFJQTSBwYWNrYWdlcyBkcm9wIGxvZyByb3RhdGlvbiBpbmZvcm1hdGlvbiBpbnRvIHRoaXMgZGlyZWN0b3J5CmluY2x1ZGUgL2V0Yy9sb2dyb3RhdGUuZAoKIyBubyBwYWNrYWdlcyBvd24gd3RtcCBhbmQgYnRtcCAtLSB3ZSdsbCByb3RhdGUgdGhlbSBoZXJlCi92YXIvbG9nL3d0bXAgewogICAgbW9udGhseQogICAgY3JlYXRlIDA2NjQgcm9vdCB1dG1wCiAgICAgICAgbWluc2l6ZSAxTQogICAgcm90YXRlIDEKfQoKL3Zhci9sb2cvYnRtcCB7CiAgICBtaXNzaW5nb2sKICAgIG1vbnRobHkKICAgIGNyZWF0ZSAwNjAwIHJvb3QgdXRtcAogICAgcm90YXRlIDEKfQpFT0YKCmVjaG8gImNvbmZpZ3VyaW5nIHl1bSByZXBvc2l0b3J5IGFuZCBydW5uaW5nIHl1bSB1cGRhdGUiCmNhdCA+L2V0Yy95dW0ucmVwb3MuZC9henVyZS5yZXBvIDw8J0VPRicKW2F6dXJlLWNsaV0KbmFtZT1henVyZS1jbGkKYmFzZXVybD1odHRwczovL3BhY2thZ2VzLm1pY3Jvc29mdC5jb20veXVtcmVwb3MvYXp1cmUtY2xpCmVuYWJsZWQ9eWVzCmdwZ2NoZWNrPXllcwoKW2F6dXJlY29yZV0KbmFtZT1henVyZWNvcmUKYmFzZXVybD1odHRwczovL3BhY2thZ2VzLm1pY3Jvc29mdC5jb20veXVtcmVwb3MvYXp1cmVjb3JlCmVuYWJsZWQ9eWVzCmdwZ2NoZWNrPW5vCkVPRgoKc2VtYW5hZ2UgZmNvbnRleHQgLWEgLXQgdmFyX2xvZ190ICIvdmFyL2xvZy9qb3VybmFsKC8uKik/Igpta2RpciAtcCAvdmFyL2xvZy9qb3VybmFsCgpmb3IgYXR0ZW1wdCBpbiB7MS4uNjB9OyBkbwp5dW0gLXkgaW5zdGFsbCBjbGFtYXYgYXpzZWMtY2xhbWF2IGF6c2VjLW1vbml0b3IgYXp1cmUtY2xpIGF6dXJlLW1kc2QgYXp1cmUtc2VjdXJpdHkgcG9kbWFuIHBvZG1hbi1kb2NrZXIgb3BlbnNzbC1wZXJsIHB5dGhvbjMgJiYgYnJlYWsKICAjIGhhY2sgLSB3ZSBhcmUgaW5zdGFsbGluZyBweXRob24zIG9uIGhvc3RzIGR1ZSB0byBhbiBpc3N1ZSB3aXRoIEF6dXJlIExpbnV4IEV4dGVuc2lvbnMgaHR0cHM6Ly9naXRodWIuY29tL0F6dXJlL2F6dXJlLWxpbnV4LWV4dGVuc2lvbnMvcHVsbC8xNTA1CiAgaWYgW1sgJHthdHRlbXB0fSAtbHQgNjAgXV07IHRoZW4gc2xlZXAgMzA7IGVsc2UgZXhpdCAxOyBmaQpkb25lCgojIGh0dHBzOi8vYWNjZXNzLnJlZGhhdC5jb20vc2VjdXJpdHkvY3ZlL2N2ZS0yMDIwLTEzNDAxCmVjaG8gImFwcGx5aW5nIGZpcmV3YWxsIHJ1bGVzIgpjYXQgPi9ldGMvc3lzY3RsLmQvMDItZGlzYWJsZS1hY2NlcHQtcmEuY29uZiA8PCdFT0YnCm5ldC5pcHY2LmNvbmYuYWxsLmFjY2VwdF9yYT0wCkVPRgoKY2F0ID4vZXRjL3N5c2N0bC5kLzAxLWRpc2FibGUtY29yZS5jb25mIDw8J0VPRicKa2VybmVsLmNvcmVfcGF0dGVybiA9IHwvYmluL3RydWUKRU9GCnN5c2N0bCAtLXN5c3RlbQoKZmlyZXdhbGwtY21kIC0tYWRkLXBvcnQ9NDQzL3RjcCAtLXBlcm1hbmVudApmaXJld2FsbC1jbWQgLS1hZGQtcG9ydD00NDQvdGNwIC0tcGVybWFuZW50CmZpcmV3YWxsLWNtZCAtLWFkZC1wb3J0PTIyMjIvdGNwIC0tcGVybWFuZW50CgpleHBvcnQgQVpVUkVfQ0xPVURfTkFNRT0kQVpVUkVDTE9VRE5BTUUKCmVjaG8gImxvZ2dpbmcgaW50byBwcm9kIGFjciIKYXogbG9naW4gLWkgLS1hbGxvdy1uby1zdWJzY3JpcHRpb25zCgojIFN1cHByZXNzIGVtdWxhdGlvbiBvdXRwdXQgZm9yIHBvZG1hbiBpbnN0ZWFkIG9mIGRvY2tlciBmb3IgYXogYWNyIGNvbXBhdGFiaWxpdHkKbWtkaXIgLXAgL2V0Yy9jb250YWluZXJzLwp0b3VjaCAvZXRjL2NvbnRhaW5lcnMvbm9kb2NrZXIKCm1rZGlyIC1wIC9yb290Ly5kb2NrZXIKUkVHSVNUUllfQVVUSF9GSUxFPS9yb290Ly5kb2NrZXIvY29uZmlnLmpzb24gYXogYWNyIGxvZ2luIC0tbmFtZSAiJChzZWQgLWUgJ3N8LiovfHwnIDw8PCIkQUNSUkVTT1VSQ0VJRCIpIgoKTURNSU1BR0U9IiR7UlBJTUFHRSUlLyp9LyR7TURNSU1BR0UjKi99Igpkb2NrZXIgcHVsbCAiJE1ETUlNQUdFIgpkb2NrZXIgcHVsbCAiJFJQSU1BR0UiCmRvY2tlciBwdWxsICIkRkxVRU5UQklUSU1BR0UiCgpheiBsb2dvdXQKCmVjaG8gImNvbmZpZ3VyaW5nIGZsdWVudGJpdCBzZXJ2aWNlIgpta2RpciAtcCAvZXRjL2ZsdWVudGJpdC8KbWtkaXIgLXAgL3Zhci9saWIvZmx1ZW50CgpjYXQgPi9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mIDw8J0VPRicKW0lOUFVUXQoJTmFtZSBzeXN0ZW1kCglUYWcgam91cm5hbGQKCVN5c3RlbWRfRmlsdGVyIF9DT01NPWFybwoJREIgL3Zhci9saWIvZmx1ZW50L2pvdXJuYWxkYgoKW0ZJTFRFUl0KCU5hbWUgbW9kaWZ5CglNYXRjaCBqb3VybmFsZAoJUmVtb3ZlX3dpbGRjYXJkIF8KCVJlbW92ZSBUSU1FU1RBTVAKCltGSUxURVJdCglOYW1lIHJld3JpdGVfdGFnCglNYXRjaCBqb3VybmFsZAoJUnVsZSAkTE9HS0lORCBhc3luY3FvcyBhc3luY3FvcyB0cnVlCgpbRklMVEVSXQoJTmFtZSBtb2RpZnkKCU1hdGNoIGFzeW5jcW9zCglSZW1vdmUgQ0xJRU5UX1BSSU5DSVBBTF9OQU1FCglSZW1vdmUgRklMRQoJUmVtb3ZlIENPTVBPTkVOVAoKW0ZJTFRFUl0KCU5hbWUgcmV3cml0ZV90YWcKCU1hdGNoIGpvdXJuYWxkCglSdWxlICRMT0dLSU5EIGlmeGF1ZGl0IGlmeGF1ZGl0IGZhbHNlCgpbRklMVEVSXQoJTmFtZSByZXdyaXRlX3RhZwoJTWF0Y2ggam91cm5hbGQKCVJ1bGUgJExPR0tJTkQgb3V0Ym91bmRSZXF1ZXN0cyBvdXRib3VuZFJlcXVlc3RzIGZhbHNlCgpbRklMVEVSXQoJTmFtZSBtb2RpZnkKCU1hdGNoICBvdXRib3VuZFJlcXVlc3RzCglSZW1vdmUgQ0xJRU5UX1BSSU5DSVBBTF9OQU1FCglSZW1vdmUgRklMRQoJUmVtb3ZlIENPTVBPTkVOVAoKW09VVFBVVF0KCU5hbWUgZm9yd2FyZAoJTWF0Y2ggKgoJUG9ydCAyOTIzMApFT0YKCmVjaG8gIkZMVUVOVEJJVElNQUdFPSRGTFVFTlRCSVRJTUFHRSIgPi9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdAoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL2ZsdWVudGJpdC5zZXJ2aWNlIDw8J0VPRicKW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsU2VjPTAKCltTZXJ2aWNlXQpSZXN0YXJ0U2VjPTFzCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9mbHVlbnRiaXQKRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9kb2NrZXIgcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL2RvY2tlciBydW4gXAogIC0tc2VjdXJpdHktb3B0IGxhYmVsPWRpc2FibGUgXAogIC0tZW50cnlwb2ludCAvb3B0L3RkLWFnZW50LWJpdC9iaW4vdGQtYWdlbnQtYml0IFwKICAtLW5ldD1ob3N0IFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLXYgL2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmY6L2V0Yy9mbHVlbnRiaXQvZmx1ZW50Yml0LmNvbmYgXAogIC12IC92YXIvbGliL2ZsdWVudDovdmFyL2xpYi9mbHVlbnQ6eiBcCiAgLXYgL3Zhci9sb2cvam91cm5hbDovdmFyL2xvZy9qb3VybmFsOnJvIFwKICAtdiAvZXRjL21hY2hpbmUtaWQ6L2V0Yy9tYWNoaW5lLWlkOnJvIFwKICAkRkxVRU5UQklUSU1BR0UgXAogIC1jIC9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mCgpFeGVjU3RvcD0vdXNyL2Jpbi9kb2NrZXIgc3RvcCAlTgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTUKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCm1rZGlyIC9ldGMvYXJvLXJwCmJhc2U2NCAtZCA8PDwiJEFETUlOQVBJQ0FCVU5ETEUiID4vZXRjL2Fyby1ycC9hZG1pbi1jYS1idW5kbGUucGVtCmlmIFtbIC1uICIkQVJNQVBJQ0FCVU5ETEUiIF1dOyB0aGVuCiAgYmFzZTY0IC1kIDw8PCIkQVJNQVBJQ0FCVU5ETEUiID4vZXRjL2Fyby1ycC9hcm0tY2EtYnVuZGxlLnBlbQpmaQpjaG93biAtUiAxMDAwOjEwMDAgL2V0Yy9hcm8tcnAKCmVjaG8gImNvbmZpZ3VyaW5nIG1kbSBzZXJ2aWNlIgpjYXQgPi9ldGMvc3lzY29uZmlnL21kbSA8PEVPRgpNRE1GUk9OVEVORFVSTD0nJE1ETUZST05URU5EVVJMJwpNRE1JTUFHRT0nJE1ETUlNQUdFJwpNRE1TT1VSQ0VFTlZJUk9OTUVOVD0nJExPQ0FUSU9OJwpNRE1TT1VSQ0VST0xFPXJwCk1ETVNPVVJDRVJPTEVJTlNUQU5DRT0nJChob3N0bmFtZSknCkVPRgoKbWtkaXIgL3Zhci9ldHcKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL21kbS5zZXJ2aWNlIDw8J0VPRicKW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvbWRtCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vZG9ja2VyIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9kb2NrZXIgcnVuIFwKICAtLWVudHJ5cG9pbnQgL3Vzci9zYmluL01ldHJpY3NFeHRlbnNpb24gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtbSAyZyBcCiAgLXYgL2V0Yy9tZG0ucGVtOi9ldGMvbWRtLnBlbSBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJE1ETUlNQUdFIFwKICAtQ2VydEZpbGUgL2V0Yy9tZG0ucGVtIFwKICAtRnJvbnRFbmRVcmwgJE1ETUZST05URU5EVVJMIFwKICAtTG9nZ2VyIENvbnNvbGUgXAogIC1Mb2dMZXZlbCBXYXJuaW5nIFwKICAtUHJpdmF0ZUtleUZpbGUgL2V0Yy9tZG0ucGVtIFwKICAtU291cmNlRW52aXJvbm1lbnQgJE1ETVNPVVJDRUVOVklST05NRU5UIFwKICAtU291cmNlUm9sZSAkTURNU09VUkNFUk9MRSBcCiAgLVNvdXJjZVJvbGVJbnN0YW5jZSAkTURNU09VUkNFUk9MRUlOU1RBTkNFCkV4ZWNTdG9wPS91c3IvYmluL2RvY2tlciBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0CkVPRgoKZWNobyAiY29uZmlndXJpbmcgYXJvLXJwIHNlcnZpY2UiCmNhdCA+L2V0Yy9zeXNjb25maWcvYXJvLXJwIDw8RU9GCkFDUl9SRVNPVVJDRV9JRD0nJEFDUlJFU09VUkNFSUQnCkFETUlOX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRT0nJEFETUlOQVBJQ0xJRU5UQ0VSVENPTU1PTk5BTUUnCkFSTV9BUElfQ0xJRU5UX0NFUlRfQ09NTU9OX05BTUU9JyRBUk1BUElDTElFTlRDRVJUQ09NTU9OTkFNRScKQVpVUkVfQVJNX0NMSUVOVF9JRD0nJEFSTUNMSUVOVElEJwpBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpBWlVSRV9GUF9TRVJWSUNFX1BSSU5DSVBBTF9JRD0nJEZQU0VSVklDRVBSSU5DSVBBTElEJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1SUApDTFVTVEVSX01EU0RfQUNDT1VOVD0nJENMVVNURVJNRFNEQUNDT1VOVCcKQ0xVU1RFUl9NRFNEX0NPTkZJR19WRVJTSU9OPSckQ0xVU1RFUk1EU0RDT05GSUdWRVJTSU9OJwpDTFVTVEVSX01EU0RfTkFNRVNQQUNFPSckQ0xVU1RFUk1EU0ROQU1FU1BBQ0UnCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCkRPTUFJTl9OQU1FPSckTE9DQVRJT04uJENMVVNURVJQQVJFTlRET01BSU5OQU1FJwpHQVRFV0FZX0RPTUFJTlM9JyRHQVRFV0FZRE9NQUlOUycKR0FURVdBWV9SRVNPVVJDRUdST1VQPSckR0FURVdBWVJFU09VUkNFR1JPVVBOQU1FJwpLRVlWQVVMVF9QUkVGSVg9JyRLRVlWQVVMVFBSRUZJWCcKTURNX0FDQ09VTlQ9JyRSUE1ETUFDQ09VTlQnCk1ETV9OQU1FU1BBQ0U9UlAKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKUlBfRkVBVFVSRVM9JyRSUEZFQVRVUkVTJwpSUElNQUdFPSckUlBJTUFHRScKQVJPX0lOU1RBTExfVklBX0hJVkU9JyRDTFVTVEVSU0lOU1RBTExWSUFISVZFJwpBUk9fSElWRV9ERUZBVUxUX0lOU1RBTExFUl9QVUxMU1BFQz0nJENMVVNURVJERUZBVUxUSU5TVEFMTEVSUFVMTFNQRUMnCkFST19BRE9QVF9CWV9ISVZFPSckQ0xVU1RFUlNBRE9QVEJZSElWRScKT0lEQ19BRkRfRU5EUE9JTlQ9JyRMT0NBVElPTi5vaWMuJFJQUEFSRU5URE9NQUlOTkFNRScKT0lEQ19TVE9SQUdFX0FDQ09VTlRfTkFNRT0nJE9JRENTVE9SQUdFQUNDT1VOVE5BTUUnCkVPRgoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1ycC5zZXJ2aWNlIDw8J0VPRicKW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXJwCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vZG9ja2VyIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9kb2NrZXIgcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLWUgQUNSX1JFU09VUkNFX0lEIFwKICAtZSBBRE1JTl9BUElfQ0xJRU5UX0NFUlRfQ09NTU9OX05BTUUgXAogIC1lIEFSTV9BUElfQ0xJRU5UX0NFUlRfQ09NTU9OX05BTUUgXAogIC1lIEFaVVJFX0FSTV9DTElFTlRfSUQgXAogIC1lIEFaVVJFX0ZQX0NMSUVOVF9JRCBcCiAgLWUgQ0xVU1RFUl9NRE1fQUNDT1VOVCBcCiAgLWUgQ0xVU1RFUl9NRE1fTkFNRVNQQUNFIFwKICAtZSBDTFVTVEVSX01EU0RfQUNDT1VOVCBcCiAgLWUgQ0xVU1RFUl9NRFNEX0NPTkZJR19WRVJTSU9OIFwKICAtZSBDTFVTVEVSX01EU0RfTkFNRVNQQUNFIFwKICAtZSBEQVRBQkFTRV9BQ0NPVU5UX05BTUUgXAogIC1lIERPTUFJTl9OQU1FIFwKICAtZSBHQVRFV0FZX0RPTUFJTlMgXAogIC1lIEdBVEVXQVlfUkVTT1VSQ0VHUk9VUCBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLWUgTURTRF9FTlZJUk9OTUVOVCBcCiAgLWUgUlBfRkVBVFVSRVMgXAogIC1lIEFST19JTlNUQUxMX1ZJQV9ISVZFIFwKICAtZSBBUk9fSElWRV9ERUZBVUxUX0lOU1RBTExFUl9QVUxMU1BFQyBcCiAgLWUgQVJPX0FET1BUX0JZX0hJVkUgXAogIC1lIE9JRENfQUZEX0VORFBPSU5UIFwKICAtZSBPSURDX1NUT1JBR0VfQUNDT1VOVF9OQU1FIFwKICAtbSAyZyBcCiAgLXAgNDQzOjg0NDMgXAogIC12IC9ldGMvYXJvLXJwOi9ldGMvYXJvLXJwIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJFJQSU1BR0UgXAogIHJwCkV4ZWNTdG9wPS91c3IvYmluL2RvY2tlciBzdG9wIC10IDM2MDAgJU4KVGltZW91dFN0b3BTZWM9MzYwMApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCiMgRE9NQUlOX05BTUUsIENMVVNURVJfTURTRF9BQ0NPVU5ULCBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04sIEdBVEVXQVlfRE9NQUlOUywgR0FURVdBWV9SRVNPVVJDRUdST1VQLCBNRFNEX0VOVklST05NRU5UIENMVVNURVJfTURTRF9OQU1FU1BBQ0UKIyBhcmUgbm90IHVzZWQsIGJ1dCBjYW4ndCBlYXNpbHkgYmUgcmVmYWN0b3JlZCBvdXQuIFNob3VsZCBiZSByZXZpc2l0ZWQgaW4gdGhlIGZ1dHVyZS4KZWNobyAiY29uZmlndXJpbmcgYXJvLW1vbml0b3Igc2VydmljZSIKY2F0ID4vZXRjL3N5c2NvbmZpZy9hcm8tbW9uaXRvciA8PEVPRgpBWlVSRV9GUF9DTElFTlRfSUQ9JyRGUENMSUVOVElEJwpET01BSU5fTkFNRT0nJExPQ0FUSU9OLiRDTFVTVEVSUEFSRU5URE9NQUlOTkFNRScKQ0xVU1RFUl9NRFNEX0FDQ09VTlQ9JyRDTFVTVEVSTURTREFDQ09VTlQnCkNMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTj0nJENMVVNURVJNRFNEQ09ORklHVkVSU0lPTicKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfUkVTT1VSQ0VHUk9VUD0nJEdBVEVXQVlSRVNPVVJDRUdST1VQTkFNRScKTURTRF9FTlZJUk9OTUVOVD0nJE1EU0RFTlZJUk9OTUVOVCcKQ0xVU1RFUl9NRFNEX05BTUVTUEFDRT0nJENMVVNURVJNRFNETkFNRVNQQUNFJwpDTFVTVEVSX01ETV9BQ0NPVU5UPSckQ0xVU1RFUk1ETUFDQ09VTlQnCkNMVVNURVJfTURNX05BTUVTUEFDRT1CQk0KREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPUJCTQpSUElNQUdFPSckUlBJTUFHRScKRU9GCgpjYXQgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLW1vbml0b3Iuc2VydmljZSA8PCdFT0YnCltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPS9ldGMvc3lzY29uZmlnL2Fyby1tb25pdG9yCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vZG9ja2VyIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9kb2NrZXIgcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLWUgQVpVUkVfRlBfQ0xJRU5UX0lEIFwKICAtZSBET01BSU5fTkFNRSBcCiAgLWUgQ0xVU1RFUl9NRFNEX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTiBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX1JFU09VUkNFR1JPVVAgXAogIC1lIE1EU0RfRU5WSVJPTk1FTlQgXAogIC1lIENMVVNURVJfTURTRF9OQU1FU1BBQ0UgXAogIC1lIENMVVNURVJfTURNX0FDQ09VTlQgXAogIC1lIENMVVNURVJfTURNX05BTUVTUEFDRSBcCiAgLWUgREFUQUJBU0VfQUNDT1VOVF9OQU1FIFwKICAtZSBLRVlWQVVMVF9QUkVGSVggXAogIC1lIE1ETV9BQ0NPVU5UIFwKICAtZSBNRE1fTkFNRVNQQUNFIFwKICAtbSAyLjVnIFwKICAtdiAvcnVuL3N5c3RlbWQvam91cm5hbDovcnVuL3N5c3RlbWQvam91cm5hbCBcCiAgLXYgL3Zhci9ldHc6L3Zhci9ldHc6eiBcCiAgJFJQSU1BR0UgXAogIG1vbml0b3IKUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0xClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKRU9GCgplY2hvICJjb25maWd1cmluZyBhcm8tcG9ydGFsIHNlcnZpY2UiCmNhdCA+L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbCA8PEVPRgpBWlVSRV9QT1JUQUxfQUNDRVNTX0dST1VQX0lEUz0nJFBPUlRBTEFDQ0VTU0dST1VQSURTJwpBWlVSRV9QT1JUQUxfQ0xJRU5UX0lEPSckUE9SVEFMQ0xJRU5USUQnCkFaVVJFX1BPUlRBTF9FTEVWQVRFRF9HUk9VUF9JRFM9JyRQT1JUQUxFTEVWQVRFREdST1VQSURTJwpEQVRBQkFTRV9BQ0NPVU5UX05BTUU9JyREQVRBQkFTRUFDQ09VTlROQU1FJwpLRVlWQVVMVF9QUkVGSVg9JyRLRVlWQVVMVFBSRUZJWCcKTURNX0FDQ09VTlQ9JyRSUE1ETUFDQ09VTlQnCk1ETV9OQU1FU1BBQ0U9UG9ydGFsClBPUlRBTF9IT1NUTkFNRT0nJExPQ0FUSU9OLmFkbWluLiRSUFBBUkVOVERPTUFJTk5BTUUnClJQSU1BR0U9JyRSUElNQUdFJwpFT0YKCmNhdCA+L2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tcG9ydGFsLnNlcnZpY2UgPDwnRU9GJwpbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldApTdGFydExpbWl0SW50ZXJ2YWw9MAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9hcm8tcG9ydGFsCkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vZG9ja2VyIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9kb2NrZXIgcnVuIFwKICAtLWhvc3RuYW1lICVIIFwKICAtLW5hbWUgJU4gXAogIC0tcm0gXAogIC0tY2FwLWRyb3AgbmV0X3JhdyBcCiAgLWUgQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFMgXAogIC1lIEFaVVJFX1BPUlRBTF9DTElFTlRfSUQgXAogIC1lIEFaVVJFX1BPUlRBTF9FTEVWQVRFRF9HUk9VUF9JRFMgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLWUgUE9SVEFMX0hPU1ROQU1FIFwKICAtbSAyZyBcCiAgLXAgNDQ0Ojg0NDQgXAogIC1wIDIyMjI6MjIyMiBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRSUElNQUdFIFwKICBwb3J0YWwKUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz0xCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKRU9GCgplY2hvICJjb25maWd1cmluZyBtZHNkIGFuZCBtZG0gc2VydmljZXMiCmNoY29uIC1SIHN5c3RlbV91Om9iamVjdF9yOnZhcl9sb2dfdDpzMCAvdmFyL29wdC9taWNyb3NvZnQvbGludXhtb25hZ2VudAoKbWtkaXIgLXAgL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUKCmZvciB2YXIgaW4gIm1kc2QiICJtZG0iOyBkbwpjYXQgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vZG93bmxvYWQtJHZhci1jcmVkZW50aWFscy5zZXJ2aWNlIDw8RU9GCltVbml0XQpEZXNjcmlwdGlvbj1QZXJpb2RpYyAkdmFyIGNyZWRlbnRpYWxzIHJlZnJlc2gKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoICR2YXIKRU9GCgpjYXQgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vZG93bmxvYWQtJHZhci1jcmVkZW50aWFscy50aW1lciA8PEVPRgpbVW5pdF0KRGVzY3JpcHRpb249UGVyaW9kaWMgJHZhciBjcmVkZW50aWFscyByZWZyZXNoCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltUaW1lcl0KT25Cb290U2VjPTBtaW4KT25DYWxlbmRhcj0wLzEyOjAwOjAwCkFjY3VyYWN5U2VjPTVzCgpbSW5zdGFsbF0KV2FudGVkQnk9dGltZXJzLnRhcmdldApFT0YKZG9uZQoKY2F0ID4vdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCA8PEVPRgojIS9iaW4vYmFzaApzZXQgLWV1CgpDT01QT05FTlQ9IlwkMSIKZWNobyAiRG93bmxvYWQgXCRDT01QT05FTlQgY3JlZGVudGlhbHMiCgpURU1QX0RJUj1cJChta3RlbXAgLWQpCmV4cG9ydCBBWlVSRV9DT05GSUdfRElSPVwkKG1rdGVtcCAtZCkKCmVjaG8gIkxvZ2dpbmcgaW50byBBenVyZS4uLiIKUkVUUklFUz0zCndoaWxlIFsgIlwkUkVUUklFUyIgLWd0IDAgXTsgZG8KICAgIGlmIGF6IGxvZ2luIC1pIC0tYWxsb3ctbm8tc3Vic2NyaXB0aW9ucwogICAgdGhlbgogICAgICAgIGVjaG8gImF6IGxvZ2luIHN1Y2Nlc3NmdWwiCiAgICAgICAgYnJlYWsKICAgIGVsc2UKICAgICAgICBlY2hvICJheiBsb2dpbiBmYWlsZWQuIFJldHJ5aW5nLi4uIgogICAgICAgIGxldCBSRVRSSUVTLT0xCiAgICAgICAgc2xlZXAgNQogICAgZmkKZG9uZQoKdHJhcCAiY2xlYW51cCIgRVhJVAoKY2xlYW51cCgpIHsKICBheiBsb2dvdXQKICBbWyAiXCRURU1QX0RJUiIgPX4gL3RtcC8uKyBdXSAmJiBybSAtcmYgXCRURU1QX0RJUgogIFtbICJcJEFaVVJFX0NPTkZJR19ESVIiID1+IC90bXAvLisgXV0gJiYgcm0gLXJmIFwkQVpVUkVfQ09ORklHX0RJUgp9CgppZiBbICJcJENPTVBPTkVOVCIgPSAibWRtIiBdOyB0aGVuCiAgQ1VSUkVOVF9DRVJUX0ZJTEU9Ii9ldGMvbWRtLnBlbSIKZWxpZiBbICJcJENPTVBPTkVOVCIgPSAibWRzZCIgXTsgdGhlbgogIENVUlJFTlRfQ0VSVF9GSUxFPSIvdmFyL2xpYi93YWFnZW50L01pY3Jvc29mdC5BenVyZS5LZXlWYXVsdC5TdG9yZS9tZHNkLnBlbSIKZWxzZQogIGVjaG8gSW52YWxpZCB1c2FnZSAmJiBleGl0IDEKZmkKClNFQ1JFVF9OQU1FPSJycC1cJHtDT01QT05FTlR9IgpORVdfQ0VSVF9GSUxFPSJcJFRFTVBfRElSL1wkQ09NUE9ORU5ULnBlbSIKZm9yIGF0dGVtcHQgaW4gezEuLjV9OyBkbwogIGF6IGtleXZhdWx0IHNlY3JldCBkb3dubG9hZCAtLWZpbGUgXCRORVdfQ0VSVF9GSUxFIC0taWQgImh0dHBzOi8vJEtFWVZBVUxUUFJFRklYLXN2Yy4kS0VZVkFVTFRETlNTVUZGSVgvc2VjcmV0cy9cJFNFQ1JFVF9OQU1FIiAmJiBicmVhawogIGlmIFtbIFwkYXR0ZW1wdCAtbHQgNSBdXTsgdGhlbiBzbGVlcCAxMDsgZWxzZSBleGl0IDE7IGZpCmRvbmUKCmlmIFsgLWYgXCRORVdfQ0VSVF9GSUxFIF07IHRoZW4KICBpZiBbICJcJENPTVBPTkVOVCIgPSAibWRzZCIgXTsgdGhlbgogICAgY2hvd24gc3lzbG9nOnN5c2xvZyBcJE5FV19DRVJUX0ZJTEUKICBlbHNlCiAgICBzZWQgLWkgLW5lICcxLC9FTkQgQ0VSVElGSUNBVEUvIHAnIFwkTkVXX0NFUlRfRklMRQogIGZpCgogIG5ld19jZXJ0X3NuPSJcJChvcGVuc3NsIHg1MDkgLWluICJcJE5FV19DRVJUX0ZJTEUiIC1ub291dCAtc2VyaWFsIHwgYXdrIC1GPSAne3ByaW50IFwkMn0nKSIKICBjdXJyZW50X2NlcnRfc249IlwkKG9wZW5zc2wgeDUwOSAtaW4gIlwkQ1VSUkVOVF9DRVJUX0ZJTEUiIC1ub291dCAtc2VyaWFsIHwgYXdrIC1GPSAne3ByaW50IFwkMn0nKSIKICBpZiBbWyAhIC16IFwkbmV3X2NlcnRfc24gXV0gJiYgW1sgXCRuZXdfY2VydF9zbiAhPSAiXCRjdXJyZW50X2NlcnRfc24iIF1dOyB0aGVuCiAgICBlY2hvIHVwZGF0aW5nIGNlcnRpZmljYXRlIGZvciBcJENPTVBPTkVOVAogICAgY2htb2QgMDYwMCBcJE5FV19DRVJUX0ZJTEUKICAgIG12IFwkTkVXX0NFUlRfRklMRSBcJENVUlJFTlRfQ0VSVF9GSUxFCiAgZmkKZWxzZQogIGVjaG8gRmFpbGVkIHRvIHJlZnJlc2ggY2VydGlmaWNhdGUgZm9yIFwkQ09NUE9ORU5UICYmIGV4aXQgMQpmaQpFT0YKCmNobW9kIHUreCAvdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaAoKc3lzdGVtY3RsIGVuYWJsZSBkb3dubG9hZC1tZHNkLWNyZWRlbnRpYWxzLnRpbWVyCnN5c3RlbWN0bCBlbmFibGUgZG93bmxvYWQtbWRtLWNyZWRlbnRpYWxzLnRpbWVyCgovdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaCBtZHNkCi91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoIG1kbQpNRFNEQ0VSVElGSUNBVEVTQU49JChvcGVuc3NsIHg1MDkgLWluIC92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtIC1ub291dCAtc3ViamVjdCB8IHNlZCAtZSAncy8uKkNOID0gLy8nKQoKY2F0ID4vZXRjL3N5c3RlbWQvc3lzdGVtL3dhdGNoLW1kbS1jcmVkZW50aWFscy5zZXJ2aWNlIDw8RU9GCltVbml0XQpEZXNjcmlwdGlvbj1XYXRjaCBmb3IgY2hhbmdlcyBpbiBtZG0ucGVtIGFuZCByZXN0YXJ0cyB0aGUgbWRtIHNlcnZpY2UKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvYmluL3N5c3RlbWN0bCByZXN0YXJ0IG1kbS5zZXJ2aWNlCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQKRU9GCgpjYXQgPi9ldGMvc3lzdGVtZC9zeXN0ZW0vd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGggPDxFT0YKW1BhdGhdClBhdGhNb2RpZmllZD0vZXRjL21kbS5wZW0KCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldApFT0YKCnN5c3RlbWN0bCBlbmFibGUgd2F0Y2gtbWRtLWNyZWRlbnRpYWxzLnBhdGgKc3lzdGVtY3RsIHN0YXJ0IHdhdGNoLW1kbS1jcmVkZW50aWFscy5wYXRoCgpta2RpciAvZXRjL3N5c3RlbWQvc3lzdGVtL21kc2Quc2VydmljZS5kCmNhdCA+L2V0Yy9zeXN0ZW1kL3N5c3RlbS9tZHNkLnNlcnZpY2UuZC9vdmVycmlkZS5jb25mIDw8J0VPRicKW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApFT0YKCmNhdCA+L2V0Yy9kZWZhdWx0L21kc2QgPDxFT0YKTURTRF9ST0xFX1BSRUZJWD0vdmFyL3J1bi9tZHNkL2RlZmF1bHQKTURTRF9PUFRJT05TPSItQSAtZCAtciBcJE1EU0RfUk9MRV9QUkVGSVgiCgpleHBvcnQgTU9OSVRPUklOR19HQ1NfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnCmV4cG9ydCBNT05JVE9SSU5HX0dDU19BQ0NPVU5UPSckUlBNRFNEQUNDT1VOVCcKZXhwb3J0IE1PTklUT1JJTkdfR0NTX1JFR0lPTj0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdApleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRD0nJE1EU0RDRVJUSUZJQ0FURVNBTicKZXhwb3J0IE1PTklUT1JJTkdfR0NTX05BTUVTUEFDRT0nJFJQTURTRE5BTUVTUEFDRScKZXhwb3J0IE1PTklUT1JJTkdfQ09ORklHX1ZFUlNJT049JyRSUE1EU0RDT05GSUdWRVJTSU9OJwpleHBvcnQgTU9OSVRPUklOR19VU0VfR0VORVZBX0NPTkZJR19TRVJWSUNFPXRydWUKCmV4cG9ydCBNT05JVE9SSU5HX1RFTkFOVD0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19ST0xFPXJwCmV4cG9ydCBNT05JVE9SSU5HX1JPTEVfSU5TVEFOQ0U9JyQoaG9zdG5hbWUpJwoKZXhwb3J0IE1EU0RfTVNHUEFDS19TT1JUX0NPTFVNTlM9MQpFT0YKCiMgc2V0dGluZyBNT05JVE9SSU5HX0dDU19BVVRIX0lEX1RZUEU9QXV0aEtleVZhdWx0IHNlZW1zIHRvIGhhdmUgY2F1c2VkIG1kc2Qgbm90CiMgdG8gaG9ub3VyIFNTTF9DRVJUX0ZJTEUgYW55IG1vcmUsIGhlYXZlbiBvbmx5IGtub3dzIHdoeS4KbWtkaXIgLXAgL3Vzci9saWIvc3NsL2NlcnRzCmNzcGxpdCAtZiAvdXNyL2xpYi9zc2wvY2VydHMvY2VydC0gLWIgJTAzZC5wZW0gL2V0Yy9wa2kvdGxzL2NlcnRzL2NhLWJ1bmRsZS5jcnQgL14kLzEgeyp9ID4vZGV2L251bGwKY19yZWhhc2ggL3Vzci9saWIvc3NsL2NlcnRzCgojIHdlIGxlYXZlIGNsaWVudElkIGJsYW5rIGFzIGxvbmcgYXMgb25seSAxIG1hbmFnZWQgaWRlbnRpdHkgYXNzaWduZWQgdG8gdm1zcwojIGlmIHdlIGhhdmUgbW9yZSB0aGFuIDEsIHdlIHdpbGwgbmVlZCB0byBwb3B1bGF0ZSB3aXRoIGNsaWVudElkIHVzZWQgZm9yIG9mZi1ub2RlIHNjYW5uaW5nCmNhdCA+L2V0Yy9kZWZhdWx0L3ZzYS1ub2Rlc2Nhbi1hZ2VudC5jb25maWcgPDxFT0YKewogICAgIk5pY2UiOiAxOSwKICAgICJUaW1lb3V0IjogMTA4MDAsCiAgICAiQ2xpZW50SWQiOiAiIiwKICAgICJUZW5hbnRJZCI6ICIkQVpVUkVTRUNQQUNLVlNBVEVOQU5USUQiLAogICAgIlF1YWx5c1N0b3JlQmFzZVVybCI6ICIkQVpVUkVTRUNQQUNLUVVBTFlTVVJMIiwKICAgICJQcm9jZXNzVGltZW91dCI6IDMwMCwKICAgICJDb21tYW5kRGVsYXkiOiAwCiAgfQpFT0YKCmVjaG8gImVuYWJsaW5nIGFybyBzZXJ2aWNlcyIKZm9yIHNlcnZpY2UgaW4gYXJvLW1vbml0b3IgYXJvLXBvcnRhbCBhcm8tcnAgYXVvbXMgYXpzZWNkIGF6c2VjbW9uZCBtZHNkIG1kbSBjaHJvbnlkIGZsdWVudGJpdDsgZG8KICBzeXN0ZW1jdGwgZW5hYmxlICRzZXJ2aWNlLnNlcnZpY2UKZG9uZQoKZm9yIHNjYW4gaW4gYmFzZWxpbmUgY2xhbWF2IHNvZnR3YXJlOyBkbwogIC91c3IvbG9jYWwvYmluL2F6c2VjZCBjb25maWcgLXMgJHNjYW4gLWQgUDFECmRvbmUKCmVjaG8gInJlYm9vdGluZyIKcmVzdG9yZWNvbiAtUkYgL3Zhci9sb2cvKgooc2xlZXAgMzA7IHJlYm9vdCkgJgo=')))]" + "script": "[base64(concat(base64ToString('c2V0IC1leAoK'),'ACRRESOURCEID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('acrResourceId')),''')\n','ADMINAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('adminApiClientCertCommonName')),''')\n','ARMAPICLIENTCERTCOMMONNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armApiClientCertCommonName')),''')\n','ARMCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('armClientId')),''')\n','AZURECLOUDNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureCloudName')),''')\n','AZURESECPACKQUALYSURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackQualysUrl')),''')\n','AZURESECPACKVSATENANTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('azureSecPackVSATenantId')),''')\n','CLUSTERMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdmAccount')),''')\n','CLUSTERMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdAccount')),''')\n','CLUSTERMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdConfigVersion')),''')\n','CLUSTERMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterMdsdNamespace')),''')\n','CLUSTERPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterParentDomainName')),''')\n','DATABASEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('databaseAccountName')),''')\n','FLUENTBITIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fluentbitImage')),''')\n','FPCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpClientId')),''')\n','FPSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('fpServicePrincipalId')),''')\n','GATEWAYDOMAINS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayDomains')),''')\n','GATEWAYRESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayResourceGroupName')),''')\n','GATEWAYSERVICEPRINCIPALID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('gatewayServicePrincipalId')),''')\n','KEYVAULTDNSSUFFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultDNSSuffix')),''')\n','KEYVAULTPREFIX=$(base64 -d \u003c\u003c\u003c''',base64(parameters('keyvaultPrefix')),''')\n','MDMFRONTENDURL=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdmFrontendUrl')),''')\n','MDSDENVIRONMENT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('mdsdEnvironment')),''')\n','PORTALACCESSGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalAccessGroupIds')),''')\n','PORTALCLIENTID=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalClientId')),''')\n','PORTALELEVATEDGROUPIDS=$(base64 -d \u003c\u003c\u003c''',base64(parameters('portalElevatedGroupIds')),''')\n','RPFEATURES=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpFeatures')),''')\n','RPIMAGE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpImage')),''')\n','RPMDMACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdmAccount')),''')\n','RPMDSDACCOUNT=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdAccount')),''')\n','RPMDSDCONFIGVERSION=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdConfigVersion')),''')\n','RPMDSDNAMESPACE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpMdsdNamespace')),''')\n','RPPARENTDOMAINNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('rpParentDomainName')),''')\n','OIDCSTORAGEACCOUNTNAME=$(base64 -d \u003c\u003c\u003c''',base64(parameters('oidcStorageAccountName')),''')\n','CLUSTERSINSTALLVIAHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersInstallViaHive')),''')\n','CLUSTERSADOPTBYHIVE=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clustersAdoptByHive')),''')\n','CLUSTERDEFAULTINSTALLERPULLSPEC=$(base64 -d \u003c\u003c\u003c''',base64(parameters('clusterDefaultInstallerPullspec')),''')\n','ADMINAPICABUNDLE=''',parameters('adminApiCaBundle'),'''\n','ARMAPICABUNDLE=''',parameters('armApiCaBundle'),'''\n','MDMIMAGE=''/distroless/genevamdm:2.2024.626.1539-d1a6e7-20240715t0935@sha256:372fbc981bbfdf2b9a9d0ffdca2c51ed389b291a3bcff0401e9afb0c01605823''\n','LOCATION=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().location),''')\n','SUBSCRIPTIONID=$(base64 -d \u003c\u003c\u003c''',base64(subscription().subscriptionId),''')\n','RESOURCEGROUPNAME=$(base64 -d \u003c\u003c\u003c''',base64(resourceGroup().name),''')\n','\n',base64ToString('IyEvYmluL2Jhc2gKIyBJbnRlcm5hbCBGdW5jdGlvbnMgYW5kIENvbnN0YW50cwoKIyBlbXB0eV9zdHIgLSBjb25zdGFudDsgdXNlZCBieSBmdW5jdGlvbnMgZm9yIG9wdGlvbmFsIG5hbWVyZWYgc3RyaW5nIGFyZ3VlbWVudHMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CmRlY2xhcmUgLXIgZW1wdHlfc3RyPSIiCgojIHJvbGVfZ2F0ZXdheSBpcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKZGVjbGFyZSAtciByb2xlX2dhdGV3YXk9ImdhdGV3YXkiCiMgcm9sZV9ycCBpcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBWTVNTIGlzIGJlaW5nIGJvb3RzdHJhcHBlZAojIHRoaXMgc2hvdWxkIGJlIHJlZmVyZW5jZWQgYnkgc2NyaXB0cyBzb3VyY2luZyB0aGlzIGZpbGUKZGVjbGFyZSAtciByb2xlX3JwPSJycCIKCiMgbG9nIGlzIGEgd3JhcHBlciBmb3IgZWNobyB0aGF0IGluY2x1ZGVzIHRoZSBmdW5jdGlvbiBuYW1lCiMgQXJncwojIDEpIG1zZyAtIHN0cmluZwojIDIpIHN0YWNrX2xldmVsIC0gaW50OyBvcHRpb25hbCwgZGVmYXVsdHMgdG8gY2FsbGluZyBmdW5jdGlvbgpsb2coKSB7CiAgICBsb2NhbCAtciBtc2c9IiR7MTotImxvZyBtZXNzYWdlIGlzIGVtcHR5In0iCiAgICBsb2NhbCAtciBzdGFja19sZXZlbD0iJHsyOi0xfSIKICAgIGVjaG8gIiR7RlVOQ05BTUVbJHtzdGFja19sZXZlbH1dfTogJHttc2d9Igp9CgojIGFib3J0IGlzIGEgd3JhcHBlciBmb3IgbG9nIHRoYXQgZXhpdHMgd2l0aCBhbiBlcnJvciBjb2RlCmFib3J0KCkgewogICAgbG9jYWwgLXJpIG9yaWdpbl9zdGFja2xldmVsPTIKICAgIGxvZyAiJHsxfSIgIiRvcmlnaW5fc3RhY2tsZXZlbCIKICAgIGxvZyAiRXhpdGluZyIKICAgIGV4aXQgMQp9CgojIHdyaXRlX2ZpbGUKIyBBcmdzCiMgMSkgZmlsZW5hbWUgLSBzdHJpbmcKIyAyKSBmaWxlX2NvbnRlbnRzIC0gc3RyaW5nCiMgMykgY2xvYmJlciAtIGJvb2xlYW47IG9wdGlvbmFsIC0gZGVmYXVsdHMgdG8gZmFsc2UKd3JpdGVfZmlsZSgpIHsKICAgIGxvY2FsIC1uIGZpbGVuYW1lPSIkMSIKICAgIGxvY2FsIC1uIGZpbGVfY29udGVudHM9IiQyIgogICAgbG9jYWwgLXIgY2xvYmJlcj0iJHszOi1mYWxzZX0iCgogICAgaWYgJGNsb2JiZXI7IHRoZW4KICAgICAgICBsb2cgIk92ZXJ3cml0aW5nIGZpbGUgJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+ICIkZmlsZW5hbWUiCiAgICBlbHNlCiAgICAgICAgbG9nICJBcHBlbmRpbmcgdG8gJGZpbGVuYW1lIgogICAgICAgIGVjaG8gIiRmaWxlX2NvbnRlbnRzIiA+PiAiJGZpbGVuYW1lIgogICAgZmkKfQoKIyByZXRyeSBBZGRpbmcgcmV0cnkgbG9naWMgdG8geXVtIGNvbW1hbmRzIGluIG9yZGVyIHRvIGF2b2lkIHN0YWxsaW5nIG91dCBvbiByZXNvdXJjZSBsb2NrcwojIGFyZ3M6CiMgMSkgY21kX3JldHJ5IC0gbmFtZXJlZiwgYXJyYXk7IENvbW1hbmQgYW5kIGFyZ3VlbWVudChzKSB0byByZXRyeQojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZAojIDMpIHJldHJpZXMgLSBpbnRlZ2VyLCBvcHRpb25hbDsgQW1tb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CnJldHJ5KCkgewogICAgbG9jYWwgLW4gY21kX3JldHJ5PSIkMSIKICAgIGxvY2FsIC1uIHdhaXRfdGltZT0iJDIiCiAgICBsb2NhbCAtcmkgcmV0cmllcz0iJHszOi01fSIKCiAgICBmb3IgYXR0ZW1wdCBpbiB7MS4uNX07IGRvCiAgICAgICAgbG9nICJhdHRlbXB0ICMke2F0dGVtcHR9IC0gJHtGVU5DTkFNRVsyXX0iCiAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICAgICAgJHtjbWRfcmV0cnlbQF19ICYKCiAgICAgICAgd2FpdCAkISAmJiBicmVhawogICAgICAgIGlmIFsgIiR7YXR0ZW1wdH0iIC1sZSAiJHJldHJpZXMiIF07IHRoZW4KICAgICAgICAgICAgc2xlZXAgIiR3YWl0X3RpbWUiCiAgICAgICAgZWxzZQogICAgICAgICAgICBhYm9ydCAiYXR0ZW1wdCAjJHthdHRlbXB0fSAtIEZhaWxlZCB0byB1cGRhdGUgcGFja2FnZXMiCiAgICAgICAgZmkKICAgIGRvbmUKfQoKIyB2ZXJpZnlfcm9sZQojIGFyZ3M6CiMgMSkgdGVzdF9yb2xlIC0gbmFtZXJlZjsgcm9sZSBiZWluZyB2ZXJpZmllZAojIDIpIGNlcnRzIC0gYm9vbGVhbiwgb3B0aW9uYWw7IGRlZmF1bHRzIHRvIGZhbHNlLiBTZXQgdG8gdHJ1ZSB0byBhZGQgZGV2cHJveHkgdG8gYWxsb3dlZCByb2xlcwp2ZXJpZnlfcm9sZSgpIHsKICAgIGxvY2FsIC1uIHRlc3Rfcm9sZT0iJDEiCiAgICBsb2NhbCAtciBjZXJ0cz0iJHsyOi1mYWxzZX0iCgogICAgYWxsb3dlZF9yb2xlc19nbG9iPSIoJHJvbGVfcnB8JHJvbGVfZ2F0ZXdheSkiCiAgICBpZiAkY2VydHM7IHRoZW4KICAgICAgICAjIHJlbW92ZSB0cmFpbGluZyAiKSIgYW5kIGFwcGVuZCBhZGRpdGlvbmFsIHJvbGUKICAgICAgICBhbGxvd2VkX3JvbGVzX2dsb2I9IiR7YWxsb3dlZF9yb2xlc19nbG9iJVwpKn18ZGV2cHJveHkpIgogICAgZmkKCiAgICBpZiBbWyAiJHRlc3Rfcm9sZSIgPX4gJGFsbG93ZWRfcm9sZXNfZ2xvYiBdXTsgdGhlbgogICAgICAgIGxvZyAiVmVyaWZpZWQgcm9sZSBcIiR0ZXN0X3JvbGVcIiIKICAgIGVsc2UKICAgICAgICBhYm9ydCAiZmFpbGVkIHRvIHZlcmlmeSByb2xlLCByb2xlIFwiJHt0ZXN0X3JvbGV9XCIgbm90IGluIFwiJHthbGxvd2VkX3JvbGVzX2dsb2J9XCIiCiAgICBmaQp9CgojIGdldF9rZXl2YXVsdF9zdWZmaXgKIyBhcmdzOgojIDEpIHJsIC0gbmFtZXJlZiwgc3RyaW5nOyByb2xlIHRvIGdldCBzaG9ydCByb2xlIGZvcgojIDIpIGt2X3N1ZmZpeCAtIG5hbWVyZWYsIHN0cmluZzsgc2hvcnQgcm9sZSB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoaXMgbmFtZXJlZgojIDMpIHNlY19wcmVmaXggLSBuYW1lcmVmLCBzdHJpbmc7IGtleXZhdWx0IGNlcnRpZmljYXRlIHByZWZpeCB3aWxsIGJlIGFzc2lnbmVkIHRvIHRoaXMgbmFtZXJlZgpnZXRfa2V5dmF1bHRfc3VmZml4KCkgewogICAgbG9jYWwgLW4gcmw9IiQxIgogICAgbG9jYWwgLW4ga3Zfc3VmZml4PSIkMiIKICAgIGxvY2FsIC1uIHNlY19wcmVmaXg9IiQzIgoKICAgIGxvY2FsIC1yIGtleXZhdWx0X3N1ZmZpeF9ycD0ic3ZjIgogICAgbG9jYWwgLXIga2V5dmF1bHRfcHJlZml4X2dhdGV3YXk9Imd3eSIKCiAgICBjYXNlICIkcmwiIGluCiAgICAgICAgIiRyb2xlX2dhdGV3YXkiKQogICAgICAgICAgICBrdl9zdWZmaXg9IiRrZXl2YXVsdF9wcmVmaXhfZ2F0ZXdheSIKICAgICAgICAgICAgc2VjX3ByZWZpeD0iJGtleXZhdWx0X3ByZWZpeF9nYXRld2F5IgogICAgICAgICAgICA7OwogICAgICAgICIkcm9sZV9ycCIpCiAgICAgICAgICAgIGt2X3N1ZmZpeD0iJGtleXZhdWx0X3N1ZmZpeF9ycCIKICAgICAgICAgICAgc2VjX3ByZWZpeD0iJHJvbGVfcnAiCiAgICAgICAgICAgIDs7CiAgICAgICAgKikKICAgICAgICAgICAgYWJvcnQgInVua293biByb2xlICRybCIKICAgICAgICAgICAgOzsKICAgIGVzYWMKfQoKIyByZWJvb3Rfdm0gcmVzdG9yZXMgYWxsIHNlbGludXggZmlsZSBjb250ZXh0cywgdGhlbiBzY2hlZHVsZXMgYSByZWJvb3QgZm9yIG9uZSBob3VyIGxhdGVyCiMgUmVib290cyBzaG91bGQgc2NoZWR1bGVkIGFmdGVyIGFsbCBWTSBleHRlbnNpb25zIGhhdmUgaGFkIHRpbWUgdG8gY29tcGxldGUKIyBSZWZlcmVuY2U6IGh0dHBzOi8vbGVhcm4ubWljcm9zb2Z0LmNvbS9lbi11cy9henVyZS92aXJ0dWFsLW1hY2hpbmVzL2V4dGVuc2lvbnMvY3VzdG9tLXNjcmlwdC1saW51eCN0aXBzCnJlYm9vdF92bSgpIHsKICAgIGxvZyAic3RhcnRpbmciCgogICAgKHNodXRkb3duIC1yIG5vdyAmKQp9CiMhL2Jpbi9iYXNoCiMgUmVwb3NpdG9yeSBhbmQgcGFja2FnZSBtYW5hZ2VtZW50IHJlbGF0ZWQgZnVuY3Rpb25zCgpjb25maWd1cmVfcmVwb19tYXJpbmVyX2V4dGVuZGVkKCkgewogICAgbG9jYWwgLXIgZXh0ZW5kZWRfcmVwb19jb25maWc9Imh0dHBzOi8vcGFja2FnZXMubWljcm9zb2Z0LmNvbS9jYmwtbWFyaW5lci8yLjAvcHJvZC9leHRlbmRlZC94ODZfNjQvY29uZmlnLnJlcG8iCiAgICBjdXJsIC1zU0wgIiRleHRlbmRlZF9yZXBvX2NvbmZpZyIgLW8gL2V0Yy95dW0ucmVwb3MuZC9tYXJpbmVyLWV4dGVuZGVkLnJlcG8KCiAgICBsb2NhbCAtciByZXBvX25hbWU9ImNibC1tYXJpbmVyMi4wcHJvZGV4dGVuZGVkeDg2XzY0IgoKICAgIGxvY2FsIC1yYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIHVwZGF0ZQogICAgICAgIC15CiAgICAgICAgLS1lbmFibGVyZXBvPSIkcmVwb19uYW1lIgogICAgKQoKICAgIGxvZyAiRW5hYmxpbmcgcmVwbyAkcmVwb19uYW1lIgogICAgcmV0cnkgY21kICIkMSIgIiR7MjotfSIKfQoKIyBjb25maWd1cmVfcnBtX3JlcG9zCiMgTmV3IHJlcG9zaXRvcmllcyBzaG91bGQgYmUgYWRkZWQgaW4gdGhlaXIgb3duIGZ1bmN0aW9ucywgYW5kIGNhbGxlZCBoZXJlCiMgYXJnczoKIyAxKSB3YWl0X3RpbWUgLSBuYW1lcmVmLCBpbnRlZ2VyOyBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJ5aW5nIGNvbW1hbmQKIyAyKSByZXRyaWVzIC0gaW50ZWdlciwgb3B0aW9uYWw7IEFtb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmNvbmZpZ3VyZV9ycG1fcmVwb3MoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGNvbmZpZ3VyZV9yZXBvX21hcmluZXJfZXh0ZW5kZWQgIiQxIiAiJHsyOi0xfSIKfQoKIyBkbmZfaW5zdGFsbF9wa2dzCiMgYXJnczoKIyAxKSBwa2dzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5OyBQYWNrYWdlcyB0byBiZSBpbnN0YWxsZWQKIyAyKSB3YWl0X3RpbWUgLSBuYW1lcmVmLCBpbnRlZ2VyOyBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJ5aW5nIGNvbW1hbmQKIyAzKSByZXRyaWVzIC0gaW50ZWdlciwgb3B0aW9uYWw7IEFtb3VudCBvZiB0aW1lcyB0byByZXRyeSBjb21tYW5kLCBkZWZhdWx0cyB0byA1CmRuZl9pbnN0YWxsX3BrZ3MoKSB7CiAgICBsb2NhbCAtbiBwa2dzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgbG9jYWwgLWEgY21kPSgKICAgICAgICBkbmYKICAgICAgICAteQogICAgICAgIGluc3RhbGwKICAgICkKICAgIAogICAgIyBSZWZlcmVuY2U6IGh0dHBzOi8vd3d3LnNoZWxsY2hlY2submV0L3dpa2kvU0MyMjA2CiAgICAjIGFwcGVuZCBwa2dzIGFycmF5IHRvIGNtZAogICAgbWFwZmlsZSAtTyAkKCggJHsjY21kW0BdfSArIDEgKSkgLWQgJyAnIGNtZCA8PDwgIiR7cGtnc1tAXX0iCiAgICBsb2NhbCAtciBjbWQKCiAgICBsb2cgIkF0dGVtcHRpbmcgdG8gaW5zdGFsbCBwYWNrYWdlczogJHtwa2dzWypdfSIKICAgIHJldHJ5IGNtZCAiJDIiICIkezM6LX0iCn0KCgojIGRuZl91cGRhdGVfcGtncwojIGFyZ3M6CiMgMSkgZXhjbHVkZXMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXksIG9wdGlvbmFsOyBQYWNrYWdlcyB0byBleGNsdWRlIGZyb20gdXBkYXRpbmcKIyAgICAgICBFYWNoIGluZGV4IG11c3QgYmUgcHJlZml4ZWQgd2l0aCAteCAKIyAyKSB3YWl0X3RpbWUgLSBuYW1lcmVmLCBpbnRlZ2VyOyBUaW1lIHRvIHdhaXQgYmVmb3JlIHJldHJ5aW5nIGNvbW1hbmQKIyAzKSByZXRyaWVzIC0gaW50ZWdlciwgb3B0aW9uYWw7IEFtbW91bnQgb2YgdGltZXMgdG8gcmV0cnkgY29tbWFuZCwgZGVmYXVsdHMgdG8gNQpkbmZfdXBkYXRlX3BrZ3MoKSB7CiAgICBsb2NhbCAtbiBleGNsdWRlcz0iJHsxOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYSBjbWQ9KAogICAgICAgIGRuZgogICAgICAgIC15CiAgICAgICAgIyBSZXBsYWNlZCB3aXRoIGV4Y2x1ZGVzCiAgICAgICAgIiIKICAgICAgICB1cGRhdGUKICAgICAgICAtLWFsbG93ZXJhc2luZwogICAgKQoKICAgIGlmIFsgLW4gIiR7ZXhjbHVkZXN9IiBdOyB0aGVuCiAgICAgICAgIyBSZWZlcmVuY2UgaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIyMDYKICAgICAgICBtYXBmaWxlIC1PIDIgY21kIDw8PCAiJHtleGNsdWRlc1tAXX0iCiAgICBlbHNlCiAgICAgICAgIyBSZW1vdmUgZW1wdHkgc3RyaW5nIGlmIHdlIGFyZW4ndCByZXBsYWNpbmcgdGhlbSwgcHJvYmFibHkgZG9lc24ndCBtYXR0ZXIsIGJ1dCB3aHkgbm90IGJlIHNhZmUKICAgICAgICB1bnNldCAiY21kWzJdIgogICAgZmkKICAgIGxvY2FsIC1yIGNtZAoKICAgIGxvZyAiVXBkYXRpbmcgYWxsIHBhY2thZ2VzIGV4Y2x1ZGluZyBcIiR7ZXhjbHVkZXNbKl06LX1cIiIKICAgIHJldHJ5IGNtZCAiJDIiICIkezM6LX0iCn0KCiMgY29uZmlndXJlX2RuZl9jcm9uX2pvYgojIGNyZWF0ZSBjcm9uIGpvYiB0byBhdXRvIHVwZGF0ZSBycG0gcGFja2FnZXMKY29uZmlndXJlX2RuZl9jcm9uX2pvYigpIHsKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2NhbCAtciBjcm9uX3dlZWtseV9kbmZfdXBkYXRlX2ZpbGVuYW1lPScvZXRjL2Nyb24ud2Vla2x5L2RuZnVwZGF0ZScKICAgIGxvY2FsIC1yIGNyb25fd2Vla2x5X2RuZl91cGRhdGVfZmlsZT0iIyEvYmluL2Jhc2gKZG5mIHVwZGF0ZSAteSIKCiAgICB3cml0ZV9maWxlIGNyb25fd2Vla2x5X2RuZl91cGRhdGVfZmlsZW5hbWUgY3Jvbl93ZWVrbHlfZG5mX3VwZGF0ZV9maWxlIHRydWUKICAgIGNobW9kIHUreCAiJGNyb25fd2Vla2x5X2RuZl91cGRhdGVfZmlsZW5hbWUiCn0KCiMgcnBtX2ltcG9ydF9rZXlzCiMgYXJnczoKIyAxKSBrZXlzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5OyBycG0ga2V5cyB0byBiZSBpbXBvcnRlZAojIDIpIHdhaXRfdGltZSAtIG5hbWVyZWYsIGludGVnZXI7IFRpbWUgdG8gd2FpdCBiZWZvcmUgcmV0cnlpbmcgY29tbWFuZApycG1faW1wb3J0X2tleXMoKSB7CiAgICBsb2NhbCAtbiBrZXlzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Iga2V5IGluICR7a2V5c1tAXX07IGRvCiAgICAgICAgaWYgWyAkeyNrZXlzW0BdfSAtZXEgMCBdOyB0aGVuCiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgZmkKICAgICAgICAgICAgbG9jYWwgLWEgY21kPSgKICAgICAgICAgICAgICAgIHJwbQogICAgICAgICAgICAgICAgLS1pbXBvcnQKICAgICAgICAgICAgICAgIC12CiAgICAgICAgICAgICAgICAiJGtleSIKICAgICAgICAgICAgKQoKICAgICAgICAgICAgbG9nICJJbXBvcnRpbmcgcnBtIHJlcG9zaXRvcnkga2V5ICRrZXkiCiAgICAgICAgICAgIHJldHJ5IGNtZCAiJDIiICIkezM6LX0iICYmIHVuc2V0IGtleQogICAgZG9uZQp9CiMhL2Jpbi9iYXNoCiMgQVJPIHNlcnZpY2Ugc2V0dXAgZnVuY3Rpb25zCgojIGVuYWJsZV9zZXJ2aWNlcyBlbmFibGVzIHRoZSBzeXN0ZW1kIHNlcnZpY2VzIHRoYXQgYXJlIHBhc3NlZCBpbgojIGFyZ3M6CiMgMSkgc2VydmljZXMgLSBhcnJheTsgc2VydmljZXMgdG8gYmUgZW5hYmxlZAplbmFibGVfc2VydmljZXMoKSB7CiAgICBsb2NhbCAtbiBzdmNzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgc3lzdGVtY3RsIGRhZW1vbi1yZWxvYWQKCiAgICBsb2cgImVuYWJsaW5nIHNlcnZpY2VzICR7c3Zjc1sqXX0iCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwNjgKICAgIGZvciBzdmMgaW4gJHtzdmNzW0BdfTsgZG8KICAgICAgICBsb2cgIkVuYWJsaW5nIGFuZCBzdGFydGluZyAkc3ZjIG5vdyIKICAgICAgICBzeXN0ZW1jdGwgZW5hYmxlIFwKICAgICAgICAgICAgICAgICAgLS1ub3cgXAogICAgICAgICAgICAgICAgICAiJHN2YyIKICAgIGRvbmUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fZ2F0ZXdheQojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IGNvbnRhaW5lciBpbWFnZQojIDIpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IFZNU1Mgcm9sZQojIDMpIGNvbmZfZmlsZSAtIG5hbWVyZWYsIHN0cmluZzsgYXJvIGdhdGV3YXkgZW52aXJvbm1lbnQgZmlsZQojIDQpIG5ldHdvcmsgLSBuYW1lcmVmLCBzdHJpbmc7IHBvZG1hbiBuZXR3b3JrIG5hbWUgdG8gYmUgYXR0YWNoZWQKY29uZmlndXJlX3NlcnZpY2VfYXJvX2dhdGV3YXkoKSB7CiAgICBsb2NhbCAtbiBpbWFnZT0iJDEiCiAgICBsb2NhbCAtbiByb2xlPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZfZmlsZT0iJDMiCiAgICBsb2NhbCAtbiBuZXR3b3JrPSIkNCIKICAgIGxvZyAic3RhcnRpbmciCiAgICBsb2cgIkNvbmZpZ3VyaW5nIGFyby1nYXRld2F5IHNlcnZpY2UiCgogICAgbG9jYWwgLXIgYXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLWdhdGV3YXknCgogICAgd3JpdGVfZmlsZSBhcm9fZ2F0ZXdheV9jb25mX2ZpbGVuYW1lIGNvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1nYXRld2F5LnNlcnZpY2UnCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGU9IltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0CgpbU2VydmljZV0KRW52aXJvbm1lbnRGaWxlPSR7YXJvX2dhdGV3YXlfY29uZl9maWxlbmFtZX0KRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtZSBBQ1JfUkVTT1VSQ0VfSUQgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgR0FURVdBWV9ET01BSU5TIFwKICAtZSBHQVRFV0FZX0ZFQVRVUkVTIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMmcgXAogIC0tbmV0d29yaz0kbmV0d29yayBcCiAgLXAgODA6ODA4MCBcCiAgLXAgODA4MTo4MDgxIFwKICAtcCA0NDM6ODQ0MyBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgJHtyb2xlLCx9CkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wIC10IDM2MDAgJU4KVGltZW91dFN0b3BTZWM9MzYwMApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldAogICAgIgoKICAgIHdyaXRlX2ZpbGUgYXJvX2dhdGV3YXlfc2VydmljZV9maWxlbmFtZSBhcm9fZ2F0ZXdheV9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycAojIGFyZ3M6CiMgMSkgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IFJQIGNvbnRhaW5lciBpbWFnZQojIDIpIHJvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IFZNU1Mgcm9sZQojIDMpIGNvbmZfZmlsZSAtIG5hbWVyZWYsIHN0cmluZzsgYXJvIHJwIGVudmlyb25tZW50IGZpbGUKIyA0KSBuZXR3b3JrIC0gbmFtZXJlZiwgc3RyaW5nOyBwb2RtYW4gbmV0d29yayBuYW1lIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19ycCgpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIHJvbGU9IiQyIgogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMyIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQ0IgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvLXJwIHNlcnZpY2UiCgogICAgbG9jYWwgLXIgYXJvX3JwX2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1ycCcKCiAgICB3cml0ZV9maWxlIGFyb19ycF9jb25mX2ZpbGVuYW1lIGNvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcnBfc2VydmljZV9maWxlbmFtZT0nL2V0Yy9zeXN0ZW1kL3N5c3RlbS9hcm8tcnAuc2VydmljZScKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3JwX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9JHthcm9fcnBfY29uZl9maWxlbmFtZX0KRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtZSBBQ1JfUkVTT1VSQ0VfSUQgXAogIC1lIEFETUlOX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRSBcCiAgLWUgQVJNX0FQSV9DTElFTlRfQ0VSVF9DT01NT05fTkFNRSBcCiAgLWUgQVpVUkVfQVJNX0NMSUVOVF9JRCBcCiAgLWUgQVpVUkVfRlBfQ0xJRU5UX0lEIFwKICAtZSBDTFVTVEVSX01ETV9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01ETV9OQU1FU1BBQ0UgXAogIC1lIENMVVNURVJfTURTRF9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04gXAogIC1lIENMVVNURVJfTURTRF9OQU1FU1BBQ0UgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgRE9NQUlOX05BTUUgXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9SRVNPVVJDRUdST1VQIFwKICAtZSBLRVlWQVVMVF9QUkVGSVggXAogIC1lIE1ETV9BQ0NPVU5UIFwKICAtZSBNRE1fTkFNRVNQQUNFIFwKICAtZSBNRFNEX0VOVklST05NRU5UIFwKICAtZSBSUF9GRUFUVVJFUyBcCiAgLWUgQVJPX0lOU1RBTExfVklBX0hJVkUgXAogIC1lIEFST19ISVZFX0RFRkFVTFRfSU5TVEFMTEVSX1BVTExTUEVDIFwKICAtZSBBUk9fQURPUFRfQllfSElWRSBcCiAgLWUgT0lEQ19BRkRfRU5EUE9JTlQgXAogIC1lIE9JRENfU1RPUkFHRV9BQ0NPVU5UX05BTUUgXAogIC1tIDJnIFwKICAtLW5ldHdvcms9JG5ldHdvcmsgXAogIC1wIDQ0Mzo4NDQzIFwKICAtdiAvZXRjL2Fyby1ycDovZXRjL2Fyby1ycCBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgJHtyb2xlLCx9CkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wIC10IDM2MDAgJU4KVGltZW91dFN0b3BTZWM9MzYwMApSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19ycF9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19ycF9zZXJ2aWNlX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19tb25pdG9yCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgbmV0d29yayAtIG5hbWVyZWYsIHN0cmluZzsgcG9kbWFuIG5ldHdvcmsgbmFtZSB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fbW9uaXRvcigpIHsKICAgIGxvY2FsIC1uIGltYWdlPSIkMSIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQyIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgYXJvLW1vbml0b3Igc2VydmljZSIKCiAgICAjIERPTUFJTl9OQU1FLCBDTFVTVEVSX01EU0RfQUNDT1VOVCwgQ0xVU1RFUl9NRFNEX0NPTkZJR19WRVJTSU9OLCBHQVRFV0FZX0RPTUFJTlMsIEdBVEVXQVlfUkVTT1VSQ0VHUk9VUCwgTURTRF9FTlZJUk9OTUVOVCBDTFVTVEVSX01EU0RfTkFNRVNQQUNFCiAgICAjIGFyZSBub3QgdXNlZCwgYnV0IGNhbid0IGVhc2lseSBiZSByZWZhY3RvcmVkIG91dC4gU2hvdWxkIGJlIHJldmlzaXRlZCBpbiB0aGUgZnV0dXJlLgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2Fyby1tb25pdG9yJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZT0iQVpVUkVfRlBfQ0xJRU5UX0lEPSckRlBDTElFTlRJRCcKRE9NQUlOX05BTUU9JyRMT0NBVElPTi4kQ0xVU1RFUlBBUkVOVERPTUFJTk5BTUUnCkNMVVNURVJfTURTRF9BQ0NPVU5UPSckQ0xVU1RFUk1EU0RBQ0NPVU5UJwpDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT049JyRDTFVTVEVSTURTRENPTkZJR1ZFUlNJT04nCkdBVEVXQVlfRE9NQUlOUz0nJEdBVEVXQVlET01BSU5TJwpHQVRFV0FZX1JFU09VUkNFR1JPVVA9JyRHQVRFV0FZUkVTT1VSQ0VHUk9VUE5BTUUnCk1EU0RfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnCkNMVVNURVJfTURTRF9OQU1FU1BBQ0U9JyRDTFVTVEVSTURTRE5BTUVTUEFDRScKQ0xVU1RFUl9NRE1fQUNDT1VOVD0nJENMVVNURVJNRE1BQ0NPVU5UJwpDTFVTVEVSX01ETV9OQU1FU1BBQ0U9QkJNCkRBVEFCQVNFX0FDQ09VTlRfTkFNRT0nJERBVEFCQVNFQUNDT1VOVE5BTUUnCktFWVZBVUxUX1BSRUZJWD0nJEtFWVZBVUxUUFJFRklYJwpNRE1fQUNDT1VOVD0nJFJQTURNQUNDT1VOVCcKTURNX05BTUVTUEFDRT1CQk0KUlBJTUFHRT0nJGltYWdlJyIKCiAgICB3cml0ZV9maWxlIGFyb19tb25pdG9yX3NlcnZpY2VfY29uZl9maWxlbmFtZSBhcm9fbW9uaXRvcl9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fbW9uaXRvcl9zZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2Fyby1tb25pdG9yLnNlcnZpY2UnCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLW1vbml0b3IKRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0taG9zdG5hbWUgJUggXAogIC0tbmFtZSAlTiBcCiAgLS1ybSBcCiAgLS1jYXAtZHJvcCBuZXRfcmF3IFwKICAtLW5ldHdvcms9JG5ldHdvcmsgXAogIC1lIEFaVVJFX0ZQX0NMSUVOVF9JRCBcCiAgLWUgRE9NQUlOX05BTUUgXAogIC1lIENMVVNURVJfTURTRF9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01EU0RfQ09ORklHX1ZFUlNJT04gXAogIC1lIEdBVEVXQVlfRE9NQUlOUyBcCiAgLWUgR0FURVdBWV9SRVNPVVJDRUdST1VQIFwKICAtZSBNRFNEX0VOVklST05NRU5UIFwKICAtZSBDTFVTVEVSX01EU0RfTkFNRVNQQUNFIFwKICAtZSBDTFVTVEVSX01ETV9BQ0NPVU5UIFwKICAtZSBDTFVTVEVSX01ETV9OQU1FU1BBQ0UgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLW0gMi41ZyBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgbW9uaXRvcgpSZXN0YXJ0PWFsd2F5cwpSZXN0YXJ0U2VjPTEKU3RhcnRMaW1pdEludGVydmFsPTAKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIGFyb19tb25pdG9yX3NlcnZpY2VfZmlsZW5hbWUgYXJvX21vbml0b3Jfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9hcm9fcG9ydGFsCiMgYXJnczoKIyAxKSBpbWFnZSAtIG5hbWVyZWYsIHN0cmluZzsgUlAgY29udGFpbmVyIGltYWdlCiMgMikgbmV0d29yayAtIG5hbWVyZWYsIHN0cmluZzsgcG9kbWFuIG5ldHdvcmsgbmFtZSB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9hcm9fcG9ydGFsKCkgewogICAgbG9jYWwgLW4gaW1hZ2U9IiQxIgogICAgbG9jYWwgLW4gbmV0d29yaz0iJDIiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBhcm8gcG9ydGFsIHNlcnZpY2UiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfY29uZl9maWxlbmFtZT0nL2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZT0iQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFM9JyRQT1JUQUxBQ0NFU1NHUk9VUElEUycKQVpVUkVfUE9SVEFMX0NMSUVOVF9JRD0nJFBPUlRBTENMSUVOVElEJwpBWlVSRV9QT1JUQUxfRUxFVkFURURfR1JPVVBfSURTPSckUE9SVEFMRUxFVkFURURHUk9VUElEUycKREFUQUJBU0VfQUNDT1VOVF9OQU1FPSckREFUQUJBU0VBQ0NPVU5UTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPVBvcnRhbApQT1JUQUxfSE9TVE5BTUU9JyRMT0NBVElPTi5hZG1pbi4kUlBQQVJFTlRET01BSU5OQU1FJwpSUElNQUdFPSckaW1hZ2UnIgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZW5hbWUgYXJvX3BvcnRhbF9zZXJ2aWNlX2NvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZW5hbWU9Jy9ldGMvc3lzdGVtZC9zeXN0ZW0vYXJvLXBvcnRhbC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcG9ydGFsX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkFmdGVyPW5ldHdvcmstb25saW5lLnRhcmdldApXYW50cz1uZXR3b3JrLW9ubGluZS50YXJnZXQKU3RhcnRMaW1pdEludGVydmFsPTAKCltTZXJ2aWNlXQpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvYXJvLXBvcnRhbApFeGVjU3RhcnRQcmU9LS91c3IvYmluL3BvZG1hbiBybSAtZiAlTgpFeGVjU3RhcnQ9L3Vzci9iaW4vcG9kbWFuIHJ1biBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC0tbmV0d29yaz0kbmV0d29yayBcCiAgLWUgQVpVUkVfUE9SVEFMX0FDQ0VTU19HUk9VUF9JRFMgXAogIC1lIEFaVVJFX1BPUlRBTF9DTElFTlRfSUQgXAogIC1lIEFaVVJFX1BPUlRBTF9FTEVWQVRFRF9HUk9VUF9JRFMgXAogIC1lIERBVEFCQVNFX0FDQ09VTlRfTkFNRSBcCiAgLWUgS0VZVkFVTFRfUFJFRklYIFwKICAtZSBNRE1fQUNDT1VOVCBcCiAgLWUgTURNX05BTUVTUEFDRSBcCiAgLWUgUE9SVEFMX0hPU1ROQU1FIFwKICAtbSAyZyBcCiAgLXAgNDQ0Ojg0NDQgXAogIC1wIDIyMjI6MjIyMiBcCiAgLXYgL3J1bi9zeXN0ZW1kL2pvdXJuYWw6L3J1bi9zeXN0ZW1kL2pvdXJuYWwgXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgcG9ydGFsClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgYXJvX3BvcnRhbF9zZXJ2aWNlX2ZpbGVuYW1lIGFyb19wb3J0YWxfc2VydmljZV9maWxlIHRydWUKfQoKIyBjb25maWd1cmVfc2VydmljZV9tZHNkCiMgYXJnczoKIyAxKSBtb25pdG9yaW5nX3JvbGUgLSBuYW1lcmVmLCBzdHJpbmc7IGNhbiBiZSAiZ2F0ZXdheSIgb3IgInJwIgojIDIpIG1vbml0b3JfY29uZmlnX3ZlcnNpb24gLSBuYW1lcmVmLCBzdHJpbmc7IG1kc2QgY29uZmlnIHZlcnNpb24KY29uZmlndXJlX3NlcnZpY2VfbWRzZCgpIHsKICAgIGxvY2FsIC1uIHJvbGU9IiQxIgogICAgbG9jYWwgLW4gbW9uaXRvcl9jb25maWdfdmVyc2lvbj0iJDIiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJjb25maWd1cmluZyBtZHNkIHNlcnZpY2UiCgogICAgdmVyaWZ5X3JvbGUgcm9sZQoKICAgIGxvY2FsIC1yIG1kc2Rfc2VydmljZV9kaXI9Ii9ldGMvc3lzdGVtZC9zeXN0ZW0vbWRzZC5zZXJ2aWNlLmQiCiAgICBta2RpciAtcCAiJG1kc2Rfc2VydmljZV9kaXIiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZW5hbWU9IiRtZHNkX3NlcnZpY2VfZGlyL292ZXJyaWRlLmNvbmYiCiAgICBsb2NhbCAtciBtZHNkX2NlcnRpZmljYXRlX3Nhbj0iJChvcGVuc3NsIHg1MDkgLWluIC92YXIvbGliL3dhYWdlbnQvTWljcm9zb2Z0LkF6dXJlLktleVZhdWx0LlN0b3JlL21kc2QucGVtIC1ub291dCAtc3ViamVjdCB8IHNlZCAtZSAncy8uKkNOID0gLy8nKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGU9IltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQiCgogICAgd3JpdGVfZmlsZSBtZHNkX292ZXJyaWRlX2NvbmZfZmlsZW5hbWUgbWRzZF9vdmVycmlkZV9jb25mX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZGVmYXVsdF9tZHNkX2ZpbGVuYW1lPSIvZXRjL2RlZmF1bHQvbWRzZCIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZGVmYXVsdF9tZHNkX2ZpbGU9Ik1EU0RfUk9MRV9QUkVGSVg9L3Zhci9ydW4vbWRzZC9kZWZhdWx0Ck1EU0RfT1BUSU9OUz1cIi1BIC1kIC1yIFwkTURTRF9ST0xFX1BSRUZJWFwiCgpleHBvcnQgTU9OSVRPUklOR19HQ1NfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnCmV4cG9ydCBNT05JVE9SSU5HX0dDU19BQ0NPVU5UPSckUlBNRFNEQUNDT1VOVCcKZXhwb3J0IE1PTklUT1JJTkdfR0NTX1JFR0lPTj0nJExPQ0FUSU9OJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdApleHBvcnQgTU9OSVRPUklOR19HQ1NfQVVUSF9JRD0nJG1kc2RfY2VydGlmaWNhdGVfc2FuJwpleHBvcnQgTU9OSVRPUklOR19HQ1NfTkFNRVNQQUNFPSckUlBNRFNETkFNRVNQQUNFJwpleHBvcnQgTU9OSVRPUklOR19DT05GSUdfVkVSU0lPTj0nJG1vbml0b3JfY29uZmlnX3ZlcnNpb24nCmV4cG9ydCBNT05JVE9SSU5HX1VTRV9HRU5FVkFfQ09ORklHX1NFUlZJQ0U9dHJ1ZQoKZXhwb3J0IE1PTklUT1JJTkdfVEVOQU5UPSckTE9DQVRJT04nCmV4cG9ydCBNT05JVE9SSU5HX1JPTEU9JyRyb2xlJwpleHBvcnQgTU9OSVRPUklOR19ST0xFX0lOU1RBTkNFPVwiJChob3N0bmFtZSlcIgoKZXhwb3J0IE1EU0RfTVNHUEFDS19TT1JUX0NPTFVNTlM9XCIxXCIiCgogICAgd3JpdGVfZmlsZSBkZWZhdWx0X21kc2RfZmlsZW5hbWUgZGVmYXVsdF9tZHNkX2ZpbGUgdHJ1ZQp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdAojIGFyZ3M6CiMgMSkgY29uZl9maWxlIC0gc3RyaW5nOyBmbHVlbmJpdCBjb25maWd1cmF0aW9uIGZpbGUKIyAyKSBpbWFnZSAtIHN0cmluZzsgZmx1ZW50Yml0IGNvbnRhaW5lciBpbWFnZSB0byBydW4KIyAzKSBuZXR3b3JrIC0gbmFtZXJlZiwgc3RyaW5nOyBwb2RtYW4gbmV0d29yayBuYW1lIHRvIGJlIGF0dGFjaGVkCmNvbmZpZ3VyZV9zZXJ2aWNlX2ZsdWVudGJpdCgpIHsKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLW4gY29uZl9maWxlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQzIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgZmx1ZW50Yml0IHNlcnZpY2UiCgogICAgbWtkaXIgLXAgL2V0Yy9mbHVlbnRiaXQvCiAgICBta2RpciAtcCAvdmFyL2xpYi9mbHVlbnQKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGNvbmZfZmlsZW5hbWU9Jy9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mJwogICAgd3JpdGVfZmlsZSBjb25mX2ZpbGVuYW1lIGNvbmZfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzeXNjb25maWdfZmlsZW5hbWU9Jy9ldGMvc3lzY29uZmlnL2ZsdWVudGJpdCcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX2ZpbGU9IkZMVUVOVEJJVElNQUdFPSRpbWFnZSIKCiAgICB3cml0ZV9maWxlIHN5c2NvbmZpZ19maWxlbmFtZSBzeXNjb25maWdfZmlsZSB0cnVlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzZXJ2aWNlX2ZpbGVuYW1lPScvZXRjL3N5c3RlbWQvc3lzdGVtL2ZsdWVudGJpdC5zZXJ2aWNlJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzZXJ2aWNlX2ZpbGU9IltVbml0XQpBZnRlcj1uZXR3b3JrLW9ubGluZS50YXJnZXQKV2FudHM9bmV0d29yay1vbmxpbmUudGFyZ2V0ClN0YXJ0TGltaXRJbnRlcnZhbFNlYz0wCgpbU2VydmljZV0KUmVzdGFydFNlYz0xcwpFbnZpcm9ubWVudEZpbGU9L2V0Yy9zeXNjb25maWcvZmx1ZW50Yml0CkV4ZWNTdGFydFByZT0tL3Vzci9iaW4vcG9kbWFuIHJtIC1mICVOCkV4ZWNTdGFydD0vdXNyL2Jpbi9wb2RtYW4gcnVuIFwKICAtLXNlY3VyaXR5LW9wdCBsYWJlbD1kaXNhYmxlIFwKICAtLWVudHJ5cG9pbnQgL29wdC90ZC1hZ2VudC1iaXQvYmluL3RkLWFnZW50LWJpdCBcCiAgLS1uZXQ9aG9zdCBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC12IC9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mOi9ldGMvZmx1ZW50Yml0L2ZsdWVudGJpdC5jb25mIFwKICAtdiAvdmFyL2xpYi9mbHVlbnQ6L3Zhci9saWIvZmx1ZW50OnogXAogIC12IC92YXIvbG9nL2pvdXJuYWw6L3Zhci9sb2cvam91cm5hbDpybyBcCiAgLXYgL2V0Yy9tYWNoaW5lLWlkOi9ldGMvbWFjaGluZS1pZDpybyBcCiAgJGltYWdlIFwKICAtYyAvZXRjL2ZsdWVudGJpdC9mbHVlbnRiaXQuY29uZgoKRXhlY1N0b3A9L3Vzci9iaW4vcG9kbWFuIHN0b3AgJU4KUmVzdGFydD1hbHdheXMKUmVzdGFydFNlYz01ClN0YXJ0TGltaXRJbnRlcnZhbD0wCgpbSW5zdGFsbF0KV2FudGVkQnk9bXVsdGktdXNlci50YXJnZXQiCgogICAgd3JpdGVfZmlsZSBzZXJ2aWNlX2ZpbGVuYW1lIHNlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3RpbWVyc19tZG1fbWRzZAojIGFyZ3M6CiMgMSkgcm9sZSAtIHN0cmluZzsgY2FuIGJlICJnYXRld2F5IiBvciAicnAiCmNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QoKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgdmVyaWZ5X3JvbGUgcm9sZQoKICAgIGxvY2FsIGtleXZhdWx0X3N1ZmZpeCBzZWNyZXRfcHJlZml4CiAgICBnZXRfa2V5dmF1bHRfc3VmZml4IHJvbGUga2V5dmF1bHRfc3VmZml4IHNlY3JldF9wcmVmaXgKCiAgICBmb3IgdmFyIGluICJtZHNkIiAibWRtIjsgZG8KICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc19zZXJ2aWNlX2ZpbGVuYW1lPSIvZXRjL3N5c3RlbWQvc3lzdGVtL2Rvd25sb2FkLSR2YXItY3JlZGVudGlhbHMuc2VydmljZSIKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc19zZXJ2aWNlX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1QZXJpb2RpYyAkdmFyIGNyZWRlbnRpYWxzIHJlZnJlc2gKCltTZXJ2aWNlXQpUeXBlPW9uZXNob3QKRXhlY1N0YXJ0PS91c3IvbG9jYWwvYmluL2Rvd25sb2FkLWNyZWRlbnRpYWxzLnNoICR2YXIiCgogICAgICAgIHdyaXRlX2ZpbGUgZG93bmxvYWRfY3JlZHNfc2VydmljZV9maWxlbmFtZSBkb3dubG9hZF9jcmVkc19zZXJ2aWNlX2ZpbGUgdHJ1ZQoKICAgICAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgICAgICBsb2NhbCBkb3dubG9hZF9jcmVkc190aW1lcl9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS9kb3dubG9hZC0kdmFyLWNyZWRlbnRpYWxzLnRpbWVyIgogICAgICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgICAgIGxvY2FsIGRvd25sb2FkX2NyZWRzX3RpbWVyX2ZpbGU9IltVbml0XQpEZXNjcmlwdGlvbj1QZXJpb2RpYyAkdmFyIGNyZWRlbnRpYWxzIHJlZnJlc2gKQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1RpbWVyXQpPbkJvb3RTZWM9MG1pbgpPbkNhbGVuZGFyPTAvMTI6MDA6MDAKQWNjdXJhY3lTZWM9NXMKCltJbnN0YWxsXQpXYW50ZWRCeT10aW1lcnMudGFyZ2V0IgoKICAgICAgICB3cml0ZV9maWxlIGRvd25sb2FkX2NyZWRzX3RpbWVyX2ZpbGVuYW1lIGRvd25sb2FkX2NyZWRzX3RpbWVyX2ZpbGUgdHJ1ZQogICAgZG9uZQoKICAgIGxvY2FsIC1yIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlbmFtZT0iL3Vzci9sb2NhbC9iaW4vZG93bmxvYWQtY3JlZGVudGlhbHMuc2giCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlPSIjIS9iaW4vYmFzaApzZXQgLWV1CgpDT01QT05FTlQ9XCQxCmVjaG8gXCJEb3dubG9hZCBcJENPTVBPTkVOVCBjcmVkZW50aWFsc1wiCgpURU1QX0RJUj1cIlwkKG1rdGVtcCAtZClcIgpleHBvcnQgQVpVUkVfQ09ORklHX0RJUj1cIlwkKG1rdGVtcCAtZClcIgoKZWNobyBcIkxvZ2dpbmcgaW50byBBenVyZS4uLlwiClJFVFJJRVM9Mwp3aGlsZSBbWyBcJFJFVFJJRVMgLWd0IDAgXV07IGRvCiAgICBpZiBheiBsb2dpbiAtaSAtLWFsbG93LW5vLXN1YnNjcmlwdGlvbnMKICAgIHRoZW4KICAgICAgICBlY2hvIFwiYXogbG9naW4gc3VjY2Vzc2Z1bFwiCiAgICAgICAgYnJlYWsKICAgIGVsc2UKICAgICAgICBlY2hvIFwiYXogbG9naW4gZmFpbGVkLiBSZXRyeWluZy4uLlwiCiAgICAgICAgbGV0IFJFVFJJRVMtPTEKICAgICAgICBzbGVlcCA1CiAgICBmaQpkb25lCgp0cmFwIFwiY2xlYW51cFwiIEVYSVQKCmNsZWFudXAoKSB7CiAgYXogbG9nb3V0CiAgW1sgXCRURU1QX0RJUiA9fiAvdG1wLy4rIF1dICYmIHJtIC1yZiBcJFRFTVBfRElSCiAgW1sgXCRBWlVSRV9DT05GSUdfRElSID1+IC90bXAvLisgXV0gJiYgcm0gLXJmIFwkQVpVUkVfQ09ORklHX0RJUgp9CgppZiBbWyBcJENPTVBPTkVOVCA9IFwibWRtXCIgXV07IHRoZW4KICBDVVJSRU5UX0NFUlRfRklMRT1cIi9ldGMvbWRtLnBlbVwiCmVsaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kc2RcIiBdXTsgdGhlbgogIENVUlJFTlRfQ0VSVF9GSUxFPVwiL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUvbWRzZC5wZW1cIgplbHNlCiAgZWNobyBJbnZhbGlkIHVzYWdlICYmIGV4aXQgMQpmaQoKU0VDUkVUX05BTUU9XCIkc2VjcmV0X3ByZWZpeC1cJHtDT01QT05FTlR9XCIKTkVXX0NFUlRfRklMRT1cIlwkVEVNUF9ESVIvXCRDT01QT05FTlQucGVtXCIKZm9yIGF0dGVtcHQgaW4gezEuLjV9OyBkbwogIGF6IGtleXZhdWx0IFwKICAgIHNlY3JldCBcCiAgICBkb3dubG9hZCBcCiAgICAtLWZpbGUgXCJcJE5FV19DRVJUX0ZJTEVcIiBcCiAgICAtLWlkIFwiaHR0cHM6Ly8kS0VZVkFVTFRQUkVGSVgtJGtleXZhdWx0X3N1ZmZpeC4kS0VZVkFVTFRETlNTVUZGSVgvc2VjcmV0cy9cJFNFQ1JFVF9OQU1FXCIgXAogICAgJiYgYnJlYWsKICBpZiBbWyBcJGF0dGVtcHQgLWx0IDUgXV07IHRoZW4gc2xlZXAgMTA7IGVsc2UgZXhpdCAxOyBmaQpkb25lCgppZiBbIC1mIFwkTkVXX0NFUlRfRklMRSBdOyB0aGVuCiAgaWYgW1sgXCRDT01QT05FTlQgPSBcIm1kc2RcIiBdXTsgdGhlbgogICAgY2hvd24gc3lzbG9nOnN5c2xvZyBcJE5FV19DRVJUX0ZJTEUKICBlbHNlCiAgICBzZWQgLWkgLW5lICcxLC9FTkQgQ0VSVElGSUNBVEUvIHAnIFwkTkVXX0NFUlRfRklMRQogIGZpCgogIG5ld19jZXJ0X3NuPVwiXCQob3BlbnNzbCB4NTA5IC1pbiBcIlwkTkVXX0NFUlRfRklMRVwiIC1ub291dCAtc2VyaWFsIHwgYXdrIC1GPSAne3ByaW50IFwkMn0nKVwiCiAgY3VycmVudF9jZXJ0X3NuPVwiXCQob3BlbnNzbCB4NTA5IC1pbiBcIlwkQ1VSUkVOVF9DRVJUX0ZJTEVcIiAtbm9vdXQgLXNlcmlhbCB8IGF3ayAtRj0gJ3twcmludCBcJDJ9JylcIgogIGlmIFtbICEgLXogXCRuZXdfY2VydF9zbiBdXSAmJiBbWyBcJG5ld19jZXJ0X3NuICE9IFwiXCRjdXJyZW50X2NlcnRfc25cIiBdXTsgdGhlbgogICAgZWNobyB1cGRhdGluZyBjZXJ0aWZpY2F0ZSBmb3IgXCRDT01QT05FTlQKICAgIGNobW9kIDA2MDAgXCRORVdfQ0VSVF9GSUxFCiAgICBtdiBcJE5FV19DRVJUX0ZJTEUgXCRDVVJSRU5UX0NFUlRfRklMRQogIGZpCmVsc2UKICBlY2hvIEZhaWxlZCB0byByZWZyZXNoIGNlcnRpZmljYXRlIGZvciBcJENPTVBPTkVOVCAmJiBleGl0IDEKZmkiCgogICAgd3JpdGVfZmlsZSBkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgZG93bmxvYWRfY3JlZHNfc2NyaXB0X2ZpbGUgdHJ1ZQoKICAgIGNobW9kIHUreCAvdXNyL2xvY2FsL2Jpbi9kb3dubG9hZC1jcmVkZW50aWFscy5zaAoKICAgICRkb3dubG9hZF9jcmVkc19zY3JpcHRfZmlsZW5hbWUgbWRzZCAmCiAgICB3YWl0ICIkISIKCgogICAgJGRvd25sb2FkX2NyZWRzX3NjcmlwdF9maWxlbmFtZSBtZG0gJgogICAgd2FpdCAiJCEiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciB3YXRjaF9tZG1fY3JlZHNfc2VydmljZV9maWxlbmFtZT0iL2V0Yy9zeXN0ZW1kL3N5c3RlbS93YXRjaC1tZG0tY3JlZGVudGlhbHMuc2VydmljZSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3NlcnZpY2VfZmlsZT0iW1VuaXRdCkRlc2NyaXB0aW9uPVdhdGNoIGZvciBjaGFuZ2VzIGluIG1kbS5wZW0gYW5kIHJlc3RhcnRzIHRoZSBtZG0gc2VydmljZQoKW1NlcnZpY2VdClR5cGU9b25lc2hvdApFeGVjU3RhcnQ9L3Vzci9iaW4vc3lzdGVtY3RsIHJlc3RhcnQgbWRtLnNlcnZpY2UKCltJbnN0YWxsXQpXYW50ZWRCeT1tdWx0aS11c2VyLnRhcmdldCIKCiAgICB3cml0ZV9maWxlIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGVuYW1lIHdhdGNoX21kbV9jcmVkc19zZXJ2aWNlX2ZpbGUgdHJ1ZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZW5hbWU9Jy91c3IvbGliL3N5c3RlbWQvc3lzdGVtL3dhdGNoLW1kbS1jcmVkZW50aWFscy5wYXRoJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciB3YXRjaF9tZG1fY3JlZHNfcGF0aF9maWxlPSdbUGF0aF0KUGF0aE1vZGlmaWVkPS9ldGMvbWRtLnBlbQoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0JwoKICAgIHdyaXRlX2ZpbGUgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZW5hbWUgd2F0Y2hfbWRtX2NyZWRzX3BhdGhfZmlsZSB0cnVlCgogICAgbG9jYWwgLXIgd2F0Y2hfbWRtX2NyZWRzPSd3YXRjaC1tZG0tY3JlZGVudGlhbHMucGF0aCcKICAgIHN5c3RlbWN0bCBlbmFibGUgLS1ub3cgIiR3YXRjaF9tZG1fY3JlZHMiIHx8IGFib3J0ICJmYWlsZWQgdG8gZW5hYmxlIGFuZCBzdGFydCAkd2F0Y2hfbWRtX2NyZWRzIgp9CgojIGNvbmZpZ3VyZV9zZXJ2aWNlX21kbQojIGFyZ3M6CiMgMSkgcm9sZSAtIG5hbWVyZWYsIHN0cmluZzsgY2FuIGJlICJnYXRld2F5IiBvciAicnAiCiMgMikgaW1hZ2UgLSBuYW1lcmVmLCBzdHJpbmc7IG1kbSBjb250YWluZXIgaW1hZ2UgdG8gcnVuCiMgMykgbmV0d29yayAtIG5hbWVyZWYsIHN0cmluZzsgcG9kbWFuIG5ldHdvcmsgbmFtZSB0byBiZSBhdHRhY2hlZApjb25maWd1cmVfc2VydmljZV9tZG0oKSB7CiAgICBsb2NhbCAtbiByb2xlPSIkMSIKICAgIGxvY2FsIC1uIGltYWdlPSIkMiIKICAgIGxvY2FsIC1uIG5ldHdvcms9IiQzIgogICAgbG9nICJzdGFydGluZyIKICAgIGxvZyAiQ29uZmlndXJpbmcgbWRtIHNlcnZpY2UiCgogICAgdmVyaWZ5X3JvbGUgcm9sZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgc3lzY29uZmlnX21kbV9maWxlbmFtZT0iL2V0Yy9zeXNjb25maWcvbWRtIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBzeXNjb25maWdfbWRtX2ZpbGU9Ik1ETUZST05URU5EVVJMPSckTURNRlJPTlRFTkRVUkwnCk1ETUlNQUdFPSckaW1hZ2UnCk1ETVNPVVJDRUVOVklST05NRU5UPSckTE9DQVRJT04nCk1ETVNPVVJDRVJPTEU9JyRyb2xlJwpNRE1TT1VSQ0VST0xFSU5TVEFOQ0U9XCIkKGhvc3RuYW1lKVwiIgoKICAgIHdyaXRlX2ZpbGUgc3lzY29uZmlnX21kbV9maWxlbmFtZSBzeXNjb25maWdfbWRtX2ZpbGUgdHJ1ZQoKICAgIG1rZGlyIC1wIC92YXIvZXR3CiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kbV9zZXJ2aWNlX2ZpbGVuYW1lPSIvZXRjL3N5c3RlbWQvc3lzdGVtL21kbS5zZXJ2aWNlIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1fc2VydmljZV9maWxlPSJbVW5pdF0KQWZ0ZXI9bmV0d29yay1vbmxpbmUudGFyZ2V0CldhbnRzPW5ldHdvcmstb25saW5lLnRhcmdldAoKW1NlcnZpY2VdCkVudmlyb25tZW50RmlsZT0vZXRjL3N5c2NvbmZpZy9tZG0KRXhlY1N0YXJ0UHJlPS0vdXNyL2Jpbi9wb2RtYW4gcm0gLWYgJU4KRXhlY1N0YXJ0PS91c3IvYmluL3BvZG1hbiBydW4gXAogIC0tZW50cnlwb2ludCAvdXNyL3NiaW4vTWV0cmljc0V4dGVuc2lvbiBcCiAgLS1ob3N0bmFtZSAlSCBcCiAgLS1uYW1lICVOIFwKICAtLXJtIFwKICAtLWNhcC1kcm9wIG5ldF9yYXcgXAogIC0tbmV0d29yaz0kbmV0d29yayBcCiAgLW0gMmcgXAogIC12IC9ldGMvbWRtLnBlbTovZXRjL21kbS5wZW0gXAogIC12IC92YXIvZXR3Oi92YXIvZXR3OnogXAogICRpbWFnZSBcCiAgLUNlcnRGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLUZyb250RW5kVXJsICRNRE1GUk9OVEVORFVSTCBcCiAgLUxvZ2dlciBDb25zb2xlIFwKICAtTG9nTGV2ZWwgV2FybmluZyBcCiAgLVByaXZhdGVLZXlGaWxlIC9ldGMvbWRtLnBlbSBcCiAgLVNvdXJjZUVudmlyb25tZW50ICRMT0NBVElPTiBcCiAgLVNvdXJjZVJvbGUgJHJvbGUgXAogIC1Tb3VyY2VSb2xlSW5zdGFuY2UgJEhPU1ROQU1FCkV4ZWNTdG9wPS91c3IvYmluL3BvZG1hbiBzdG9wICVOClJlc3RhcnQ9YWx3YXlzClJlc3RhcnRTZWM9MQpTdGFydExpbWl0SW50ZXJ2YWw9MAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0IgoKICAgIHdyaXRlX2ZpbGUgbWRtX3NlcnZpY2VfZmlsZW5hbWUgbWRtX3NlcnZpY2VfZmlsZSB0cnVlCn0KCiMgY29uZmlndXJlX3Ztc3NfYXJvX3NlcnZpY2UKIyBhcmdzOgojIDEpIHIgLSBuYW1lcmVmLCBzdHJpbmc7IHJvbGUgb2YgVk1TUwojIDIpIGltYWdlcyAtIG5hbWVyZWYsIGFzc29jaWF0aXZlIGFycmF5OyBBUk8gY29udGFpbmVyIGltYWdlcwojIDMpIGNvbmZpZ3MgLSBuYW1lcmVmLCBhc3NvY2lhdGl2ZSBhcnJheTsgY29uZmlndXJhdGlvbiBmaWxlcyBhbmQgdmVyc2lvbnMuIFRoZSB2YWx1ZXMgc2hvdWxkIGJlIGEgcmVmZXJlbmNlIHRvIHZhcmlhYmxlcywgbm90IGRlcmVmZXJlbmNlZC4KIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgaXMgYmVjYXVzZSB0aGUgdmFsdWUgaXMgdXNlZCB3aGVuIGNyZWF0aW5nIG5hbWVyZWYgdmFyaWFibGVzIGJ5IGhlbHBlciBmdW5jdGlvbnMuCmNvbmZpZ3VyZV92bXNzX2Fyb19zZXJ2aWNlcygpIHsKICAgIGxvY2FsIC1uIHI9IiQxIgogICAgbG9jYWwgLW4gaW1hZ2VzPSIkMiIKICAgIGxvY2FsIC1uIGNvbmZpZ3M9IiQzIgogICAgbG9nICJzdGFydGluZyIKICAgIHZlcmlmeV9yb2xlICIkMSIKCiAgICBpZiBbICIkciIgPT0gIiRyb2xlX2dhdGV3YXkiIF07IHRoZW4KICAgICAgICBjb25maWd1cmVfc2VydmljZV9hcm9fZ2F0ZXdheSAiJHtpbWFnZXNbInJwIl19IiAiJDEiICIke2NvbmZpZ3NbImdhdGV3YXlfY29uZmlnIl19IiAiJHtjb25maWdzWyJuZXR3b3JrIl19IgogICAgZWxpZiBbICIkciIgPT0gIiRyb2xlX3JwIiBdOyB0aGVuCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX3JwICIke2ltYWdlc1sicnAiXX0iICIkMSIgIiR7Y29uZmlnc1sicnBfY29uZmlnIl19IiAiJHtjb25maWdzWyJuZXR3b3JrIl19IgogICAgICAgIGNvbmZpZ3VyZV9zZXJ2aWNlX2Fyb19tb25pdG9yICIke2ltYWdlc1sicnAiXX0iICIke2NvbmZpZ3NbIm5ldHdvcmsiXX0iCiAgICAgICAgY29uZmlndXJlX3NlcnZpY2VfYXJvX3BvcnRhbCAiJHtpbWFnZXNbInJwIl19IiAiJHtjb25maWdzWyJuZXR3b3JrIl19IgogICAgZmkKCiAgICBjb25maWd1cmVfc2VydmljZV9mbHVlbnRiaXQgIiR7Y29uZmlnc1siZmx1ZW50Yml0Il19IiAiJHtpbWFnZXNbImZsdWVudGJpdCJdfSIgIiR7Y29uZmlnc1sibmV0d29yayJdfSIKICAgIGNvbmZpZ3VyZV90aW1lcnNfbWRtX21kc2QgIiQxIgogICAgY29uZmlndXJlX3NlcnZpY2VfbWRtICIkMSIgIiR7aW1hZ2VzWyJtZG0iXX0iICIke2NvbmZpZ3NbIm5ldHdvcmsiXX0iCiAgICBjb25maWd1cmVfc2VydmljZV9tZHNkICIkMSIgIiR7Y29uZmlnc1sibWRzZCJdfSIKICAgIHJ1bl9henNlY2RfY29uZmlnX3NjYW4KfQoKdXRpbF9jb21tb249InV0aWwtY29tbW9uLnNoIgppZiBbIC1mICIkdXRpbF9jb21tb24iIF07IHRoZW4KICAgICMgc2hlbGxjaGVjayBzb3VyY2U9dXRpbC1jb21tb24uc2gKICAgIHNvdXJjZSAiJHV0aWxfY29tbW9uIgpmaQojIS9iaW4vYmFzaAojIFRoaXMgZmlsZSBpcyBpbnRlbmRlZCB0byBiZSBzb3VyY2VkIGJ5IGJvb3RzdHJhcHBpbmcgc2NyaXB0cyBmb3IgY29tbW9ubHkgdXNlZCBmdW5jdGlvbnMKCiMgY29uZmlndXJlX3NzaGQKIyBXZSBuZWVkIHRvIGNvbmZpZ3VyZSBQYXNzd29yZEF1dGhlbnRpY2F0aW9uIHRvIHllcyBpbiBvcmRlciBmb3IgdGhlIFZNU1MgQWNjZXNzIEpJVCB0byB3b3JrCmNvbmZpZ3VyZV9zc2hkKCkgewogICAgbG9nICJzdGFydGluZyIKICAgIGxvY2FsIC1yIHNzaGRfY29uZmlnPSIvZXRjL3NzaC9zc2hkX2NvbmZpZyIKCiAgICBsb2cgIkVkaXRpbmcgJHNzaGRfY29uZmlnIHRvIGFsbG93IHBhc3N3b3JkIGF1dGhlbnRpY2F0aW9uIgogICAgc2VkIC1pICdzL1Bhc3N3b3JkQXV0aGVudGljYXRpb24gbm8vUGFzc3dvcmRBdXRoZW50aWNhdGlvbiB5ZXMvZycgIiRzc2hkX2NvbmZpZyIKCiAgICBzeXN0ZW1jdGwgcmVsb2FkIHNzaGQuc2VydmljZSB8fCBhYm9ydCAic3NoZCBmYWlsZWQgdG8gcmVsb2FkIgp9CgojIGNvbmZpZ3VyZV9sb2dyb3RhdGUgY2xvYmJlcnMgL2V0Yy9sb2dyb3RhdGUuY29uZgojIGFyZ3M6CiMgMSkgZHJvcGluX2ZpbGVzIC0gbmFtZXJlZiwgYXNzb2NpYXRpdmUgYXJyYXksIG9wdGlvbmFsOyBsb2dyb3RhdGUgZmlsZXMgdG8gd3JpdGUgdG8gL2V0Yy9sb2dyb3RhdGUuZAojICAgICAgIEtleSBuYW1lIGRpY3RhdGVzIGZpbGVuYW1lcyB3cml0dGVuIHRvIC9ldGMvbG9ncm90YXRlLmQuCiMgRXhhbXBsZTogCiMgICBLZXkgZGljdGF0ZXMgdGhlIGZpbGVuYW1lIHdyaXR0ZW4gaW4gL2V0Yy9sb2dyb3RhdGUuZAojICAgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAojICAgbG9jYWwgLXJBIGxvZ3JvdGF0ZV9kcm9waW5zPSgKIyAgICAgIFsiZ2F0ZXdheSJdPSIkZ2F0ZXdheV9sb2dfZmlsZSIKIyAgICkKY29uZmlndXJlX2xvZ3JvdGF0ZSgpIHsKICAgIGxvY2FsIC1uIGRyb3Bpbl9maWxlcz0iJHsxOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIGxvZ3JvdGF0ZV9jb25mX2ZpbGVuYW1lPScvZXRjL2xvZ3JvdGF0ZS5jb25mJwogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBsb2dyb3RhdGVfY29uZl9maWxlPScjIHNlZSAibWFuIGxvZ3JvdGF0ZSIgZm9yIGRldGFpbHMKIyByb3RhdGUgbG9nIGZpbGVzIHdlZWtseQp3ZWVrbHkKCiMga2VlcCAyIHdlZWtzIHdvcnRoIG9mIGJhY2tsb2dzCnJvdGF0ZSAyCgojIGNyZWF0ZSBuZXcgKGVtcHR5KSBsb2cgZmlsZXMgYWZ0ZXIgcm90YXRpbmcgb2xkIG9uZXMKY3JlYXRlCgojIHVzZSBkYXRlIGFzIGEgc3VmZml4IG9mIHRoZSByb3RhdGVkIGZpbGUKZGF0ZWV4dAoKIyB1bmNvbW1lbnQgdGhpcyBpZiB5b3Ugd2FudCB5b3VyIGxvZyBmaWxlcyBjb21wcmVzc2VkCmNvbXByZXNzCgojIFJQTSBwYWNrYWdlcyBkcm9wIGxvZyByb3RhdGlvbiBpbmZvcm1hdGlvbiBpbnRvIHRoaXMgZGlyZWN0b3J5CmluY2x1ZGUgL2V0Yy9sb2dyb3RhdGUuZAoKIyBubyBwYWNrYWdlcyBvd24gd3RtcCBhbmQgYnRtcCAtLSB3ZSB3aWxsIHJvdGF0ZSB0aGVtIGhlcmUKL3Zhci9sb2cvd3RtcCB7CiAgICBtb250aGx5CiAgICBjcmVhdGUgMDY2NCByb290IHV0bXAKICAgICAgICBtaW5zaXplIDFNCiAgICByb3RhdGUgMQp9CgovdmFyL2xvZy9idG1wIHsKICAgIG1pc3NpbmdvawogICAgbW9udGhseQogICAgY3JlYXRlIDA2MDAgcm9vdCB1dG1wCiAgICByb3RhdGUgMQp9JwoKICAgIHdyaXRlX2ZpbGUgbG9ncm90YXRlX2NvbmZfZmlsZW5hbWUgbG9ncm90YXRlX2NvbmZfZmlsZSB0cnVlCgogICAgaWYgWyAtbiAiJHtkcm9waW5fZmlsZXNbKl19IiBdOyB0aGVuCiAgICAgICAgbG9jYWwgLXIgbG9ncm90YXRlX2Q9Ii9ldGMvbG9ncm90YXRlLmQiCiAgICAgICAgbG9nICJXcml0aW5nIGxvZ3JvdGF0ZSBmaWxlcyB0byAkbG9ncm90YXRlX2QiCiAgICAgICAgZm9yIGRyb3Bpbl9uYW1lIGluICIkeyFkcm9waW5fZmlsZXNbQF19IjsgZG8KICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlbmFtZT0iJGxvZ3JvdGF0ZV9kLyRkcm9waW5fbmFtZSIKICAgICAgICAgICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICAgICAgICAgIGxvY2FsIC1yIGRyb3Bpbl9maWxlPSIke2Ryb3Bpbl9maWxlc1siJGRyb3Bpbl9uYW1lIl19IgogICAgICAgICAgICB3cml0ZV9maWxlIGRyb3Bpbl9maWxlbmFtZSBkcm9waW5fZmlsZSB0cnVlCiAgICAgICAgZG9uZQogICAgZmkKfQoKIyBwdWxsX2NvbnRhaW5lcl9pbWFnZXMKIyBhcmdzOgojIDEpIHB1bGxfaW1hZ2VzIC0gbmFtZXJlZiwgc3RyaW5nIGFycmF5CiMgMikgcmVnaXN0cnlfY29uZiAtIG5hbWVyZWYsIHN0cmluZywgb3B0aW9uYWw7IHBhdGggdG8gZG9ja2VyL3BvZG1hbiBjb25maWd1cmF0aW9uIGZpbGUKcHVsbF9jb250YWluZXJfaW1hZ2VzKCkgewogICAgbG9jYWwgLW4gcHVsbF9pbWFnZXM9IiQxIgogICAgbG9jYWwgLW4gcmVnaXN0cnlfY29uZj0iJHsyOi1lbXB0eV9zdHJ9IgogICAgbG9nICJzdGFydGluZyIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yaSByZXRyeV90aW1lPTMwCiAgICAjIFRoZSBtYW5hZ2VkIGlkZW50aXR5IHRoYXQgdGhlIFZNIHJ1bnMgYXMgb25seSBoYXMgYSBzaW5nbGUgcm9sZWFzc2lnbm1lbnQuCiAgICAjIFRoaXMgcm9sZSBhc3NpZ25tZW50IGlzIEFDUlB1bGwgd2hpY2ggaXMgbm90IG5lY2Vzc2FyaWx5IHByZXNlbnQgaW4gdGhlCiAgICAjIHN1YnNjcmlwdGlvbiB3ZSdyZSBkZXBsb3lpbmcgaW50by4gIElmIHRoZSBpZGVudGl0eSBkb2VzIG5vdCBoYXZlIGFueQogICAgIyByb2xlIGFzc2lnbm1lbnRzIHNjb3BlZCBvbiB0aGUgc3Vic2NyaXB0aW9uIHdlJ3JlIGRlcGxveWluZyBpbnRvLCBpdCB3aWxsCiAgICAjIG5vdCBzaG93IG9uIGF6IGxvZ2luIC1pLCB3aGljaCBpcyB3aHkgdGhlIGJlbG93IGxpbmUgaXMgY29tbWVudGVkLgogICAgIyBheiBhY2NvdW50IHNldCAtcyAiJFNVQlNDUklQVElPTklEIgogICAgY21kPSgKICAgICAgICBhegogICAgICAgIGxvZ2luCiAgICAgICAgLWkKICAgICAgICAtLWFsbG93LW5vLXN1YnNjcmlwdGlvbnMKICAgICkKCiAgICBsb2cgIlJ1bm5pbmcgYXogbG9naW4gd2l0aCByZXRyaWVzIgogICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKCiAgICAjIFN1cHByZXNzIGVtdWxhdGlvbiBvdXRwdXQgZm9yIHBvZG1hbiBpbnN0ZWFkIG9mIGRvY2tlciBmb3IgYXogYWNyIGNvbXBhdGFiaWxpdHkKICAgIG1rZGlyIC1wIC9ldGMvY29udGFpbmVycy8KICAgIG1rZGlyIC1wIC9yb290Ly5kb2NrZXIKICAgIHRvdWNoIC9ldGMvY29udGFpbmVycy9ub2RvY2tlcgoKICAgICMgVGhpcyBuYW1lIGlzIHVzZWQgaW4gdGhlIGNhc2UgdGhhdCBheiBhY3IgbG9naW4gc2VhcmNoZXMgZm9yIHRoaXMgaW4gaXQncyBlbnZpcm9ubWVudAogICAgZXhwb3J0IFJFR0lTVFJZX0FVVEhfRklMRT0iL3Jvb3QvLmRvY2tlci9jb25maWcuanNvbiIKICAgIAogICAgaWYgWyAtbiAiJHtyZWdpc3RyeV9jb25mfSIgXTsgdGhlbgogICAgICAgIHdyaXRlX2ZpbGUgUkVHSVNUUllfQVVUSF9GSUxFIHJlZ2lzdHJ5X2NvbmYgdHJ1ZQogICAgZmkKCiAgICBsb2cgImxvZ2dpbmcgaW50byBwcm9kIGFjciIKICAgIGNtZD0oCiAgICAgICAgYXoKICAgICAgICBhY3IKICAgICAgICBsb2dpbgogICAgICAgIC0tbmFtZQogICAgICAgICMgVE9ETyByZXBsYWNlIHRoaXMgd2l0aCB2YXJpYWJsZSBleHBhbnNpb24KICAgICAgICAjIFJlZmVyZW5jZTogaHR0cHM6Ly93d3cuc2hlbGxjaGVjay5uZXQvd2lraS9TQzIwMDEKICAgICAgICAiJChzZWQgLWUgJ3N8LiovfHwnIDw8PCIkQUNSUkVTT1VSQ0VJRCIpIgogICAgKQoKICAgIHJldHJ5IGNtZCByZXRyeV90aW1lCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgaSBpbiAke3B1bGxfaW1hZ2VzW0BdfTsgZG8KICAgICAgICBsb2NhbCAtbiBpbWFnZT0iJGkiCiAgICAgICAgY21kPSgKICAgICAgICAgICAgcG9kbWFuCiAgICAgICAgICAgIHB1bGwKICAgICAgICAgICAgIiRpbWFnZSIKICAgICAgICApCgogICAgICAgIGxvZyAiUHVsbGluZyBpbWFnZSAkaW1hZ2Ugd2l0aCByZXRyaWVzIG5vdyIKICAgICAgICByZXRyeSBjbWQgcmV0cnlfdGltZQogICAgZG9uZQoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgY21kPSgKICAgICAgICBhegogICAgICAgIGxvZ291dAogICAgKQoKICAgIGxvZyAiUnVubmluZyBheiBsb2dvdXQgd2l0aCByZXRyaWVzIgogICAgcmV0cnkgY21kIHJldHJ5X3RpbWUKfQoKIyBjb25maWd1cmVfY2VydHMKIyBhcmdzOgojIDEpIHJvbGUgLSBzdHJpbmc7IGNhbiBiZSAiZGV2cHJveHkiIG9yICJycCIKY29uZmlndXJlX2NlcnRzKCkgewogICAgbG9jYWwgLW4gcm9sZT0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgogICAgbG9nICJDb25maWd1cmluZyBjZXJ0aWZpY2F0ZXMgZm9yICRyb2xlIgoKICAgIHZlcmlmeV9yb2xlIHJvbGUgdHJ1ZQoKICAgIGlmIFsgIiRyb2xlIiA9PSAiZGV2cHJveHkiIF07IHRoZW4KICAgICAgICBsb2NhbCAtciBwcm94eV9jZXJ0c19iYXNlZGlyPSIvZXRjL3Byb3h5IgogICAgICAgIG1rZGlyIC1wICIkcHJveHlfY2VydHNfYmFzZWRpciIKICAgICAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUNFUlQiID4gIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmNydCIKICAgICAgICBiYXNlNjQgLWQgPDw8IiRQUk9YWUtFWSIgPiAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHkua2V5IgogICAgICAgIGJhc2U2NCAtZCA8PDwiJFBST1hZQ0xJRU5UQ0VSVCIgPiAiJHByb3h5X2NlcnRzX2Jhc2VkaXIvcHJveHktY2xpZW50LmNydCIKICAgICAgICBjaG93biAtUiAxMDAwOjEwMDAgL2V0Yy9wcm94eQogICAgICAgIGNobW9kIDA2MDAgIiRwcm94eV9jZXJ0c19iYXNlZGlyL3Byb3h5LmtleSIKICAgICAgICByZXR1cm4gMAogICAgZmkKCiAgICBpZiBbICIkcm9sZSIgPT0gInJwIiBdOyB0aGVuCiAgICAgICAgbG9jYWwgLXIgcnBfY2VydHNfYmFzZWRpcj0iL2V0Yy9hcm8tcnAiCiAgICAgICAgbWtkaXIgLXAgIiRycF9jZXJ0c19iYXNlZGlyIgogICAgICAgIGJhc2U2NCAtZCA8PDwiJEFETUlOQVBJQ0FCVU5ETEUiID4gIiRycF9jZXJ0c19iYXNlZGlyL2FkbWluLWNhLWJ1bmRsZS5wZW0iCiAgICAgICAgaWYgW1sgLW4gIiRBUk1BUElDQUJVTkRMRSIgXV07IHRoZW4KICAgICAgICBiYXNlNjQgLWQgPDw8IiRBUk1BUElDQUJVTkRMRSIgPiAiJHJwX2NlcnRzX2Jhc2VkaXIvYXJtLWNhLWJ1bmRsZS5wZW0iCiAgICAgICAgZmkKICAgICAgICBjaG93biAtUiAxMDAwOjEwMDAgIiRycF9jZXJ0c19iYXNlZGlyIgogICAgZmkKCiAgICAjIHNldHRpbmcgTU9OSVRPUklOR19HQ1NfQVVUSF9JRF9UWVBFPUF1dGhLZXlWYXVsdCBzZWVtcyB0byBoYXZlIGNhdXNlZCBtZHNkIG5vdAogICAgIyB0byBob25vdXIgU1NMX0NFUlRfRklMRSBhbnkgbW9yZSwgaGVhdmVuIG9ubHkga25vd3Mgd2h5LgogICAgbG9jYWwgLXIgc3NsX2NlcnRzX2Jhc2VkaXI9Ii91c3IvbGliL3NzbC9jZXJ0cyIKICAgIG1rZGlyIC1wICIkc3NsX2NlcnRzX2Jhc2VkaXIiCiAgICBjc3BsaXQgLWYgIiRzc2xfY2VydHNfYmFzZWRpci9jZXJ0LSIgLWIgJTAzZC5wZW0gL2V0Yy9wa2kvdGxzL2NlcnRzL2NhLWJ1bmRsZS5jcnQgL14kLzEgInsqfSIgMT4vZGV2L251bGwKICAgIGNfcmVoYXNoICIkc3NsX2NlcnRzX2Jhc2VkaXIiCgogICAgIyB3ZSBsZWF2ZSBjbGllbnRJZCBibGFuayBhcyBsb25nIGFzIG9ubHkgMSBtYW5hZ2VkIGlkZW50aXR5IGFzc2lnbmVkIHRvIHZtc3MKICAgICMgaWYgd2UgaGF2ZSBtb3JlIHRoYW4gMSwgd2Ugd2lsbCBuZWVkIHRvIHBvcHVsYXRlIHdpdGggY2xpZW50SWQgdXNlZCBmb3Igb2ZmLW5vZGUgc2Nhbm5pbmcKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgbm9kZXNjYW5fYWdlbnRfZmlsZW5hbWU9Ii9ldGMvZGVmYXVsdC92c2Etbm9kZXNjYW4tYWdlbnQuY29uZmlnIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBub2Rlc2Nhbl9hZ2VudF9maWxlPSJ7CiAgICBcIk5pY2VcIjogMTksCiAgICBcIlRpbWVvdXRcIjogMTA4MDAsCiAgICBcIkNsaWVudElkXCI6IFwiXCIsCiAgICBcIlRlbmFudElkXCI6ICRBWlVSRVNFQ1BBQ0tWU0FURU5BTlRJRCwKICAgIFwiUXVhbHlzU3RvcmVCYXNlVXJsXCI6ICRBWlVSRVNFQ1BBQ0tRVUFMWVNVUkwsCiAgICBcIlByb2Nlc3NUaW1lb3V0XCI6IDMwMCwKICAgIFwiQ29tbWFuZERlbGF5XCI6IDAKICB9IgoKICAgIHdyaXRlX2ZpbGUgbm9kZXNjYW5fYWdlbnRfZmlsZW5hbWUgbm9kZXNjYW5fYWdlbnRfZmlsZSB0cnVlCn0KCiMgcnVuX2F6c2VjZF9jb25maWdfc2NhbgpydW5fYXpzZWNkX2NvbmZpZ19zY2FuKCkgewogICAgbG9nICJzdGFydGluZyIKCiAgICBsb2NhbCAtYXIgY29uZmlncz0oCiAgICAgICAgImJhc2VsaW5lIgogICAgICAgICJjbGFtYXYiCiAgICAgICAgInNvZnR3YXJlIgogICAgKQoKICAgIGxvZyAiU2Nhbm5pbmcgY29uZmlndXJhdGlvbiBmaWxlcyB3aXRoIGF6c2VjZCAke2NvbmZpZ3NbKl19IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3Igc2NhbiBpbiAke2NvbmZpZ3NbQF19OyBkbwogICAgICAgIGxvZyAiU2Nhbm5pbmcgY29uZmlnIGZpbGUgJHNjYW4gbm93IgogICAgICAgIC91c3IvbG9jYWwvYmluL2F6c2VjZCBjb25maWcgLXMgIiRzY2FuIiAtZCBQMUQKICAgIGRvbmUKfQoKIyBjcmVhdGVfcmVxdWlyZWRfZGlycwpjcmVhdGVfcmVxdWlyZWRfZGlycygpIHsKICAgIGNyZWF0ZV9kaXJzPSgKICAgICAgICAvdmFyL2xvZy9qb3VybmFsCiAgICAgICAgL3Zhci9saWIvd2FhZ2VudC9NaWNyb3NvZnQuQXp1cmUuS2V5VmF1bHQuU3RvcmUKICAgICAgICAjIERvZXMgbm90IGV4aXN0IG9uIGRldlByb3h5Vk1TUwogICAgICAgIC92YXIvb3B0L21pY3Jvc29mdC9saW51eG1vbmFnZW50CiAgICApCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgZCBpbiAke2NyZWF0ZV9kaXJzW0BdfTsgZG8KICAgICAgICBsb2cgIkNyZWF0aW5nIGRpcmVjdG9yeSAkZCIKICAgICAgICBta2RpciAtcCAiJGQiIHx8IGFib3J0ICJmYWlsZWQgdG8gY3JlYXRlIGRpcmVjdG9yeSAkZCIKICAgIGRvbmUKfQoKIyBjcmVhdGVfcG9kbWFuX25ldHdvcmtzKCkKIyBhcmdzOgojIDEpIG5ldHMgLSBuYW1lcmVmLCBhc3NvY2lhdGl2ZSBhcnJheTsgTmV0d29ya3MgdG8gYmUgY3JlYXRlZAojICAgICAgIEtleSBpcyB0aGUgbmV0d29yayBuYW1lLCB2YWx1ZSBpcyB0aGUgc3VibmV0IHdpdGggY2lkciBub3RhdGlvbgpjcmVhdGVfcG9kbWFuX25ldHdvcmtzKCkgewogICAgbG9jYWwgLW4gbmV0cz0iJDEiCiAgICBsb2cgInN0YXJ0aW5nIgoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjA2OAogICAgZm9yIG4gaW4gJHshbmV0c1tAXX07IGRvCiAgICAgICAgbG9nICJDcmVhdGluZyBwb2RtYW4gbmV0d29yayBcIiRuXCIgd2l0aCBzdWJuZXQgXCIke25ldHNbJG5dfVwiIgogICAgICAgIHBvZG1hbiBuZXR3b3JrIFwKICAgICAgICAgICAgY3JlYXRlIFwKICAgICAgICAgICAgLS1zdWJuZXQgIiR7bmV0c1siJG4iXX0iIFwKICAgICAgICAgICAgIiRuIgogICAgZG9uZQp9CgojIGZpcmV3YWxsZF9jb25maWd1cmVfYmFja2VuZApmaXJld2FsbGRfY29uZmlndXJlX2JhY2tlbmQoKSB7CiAgICBsb2cgInN0YXJ0aW5nIgoKICAgIGxvZyAiQ2hhbmdpbmcgZmlyZXdhbGxkIGJhY2tlbmQgdG8gaXB0YWJsZXMiCiAgICBjb25mX2ZpbGU9Ii9ldGMvZmlyZXdhbGxkL2ZpcmV3YWxsZC5jb25mIgogICAgc2VkIC1pICdzL0ZpcmV3YWxsQmFja2VuZD1uZnRhYmxlcy9GaXJld2FsbEJhY2tlbmQ9aXB0YWJsZXMvZycgIiRjb25mX2ZpbGUiCn0KCiMgZmlyZXdhbGxkX2NvbmZpZ3VyZQojIGFyZ3M6CiMgMSkgcG9ydHMgLSBuYW1lcmVmLCBzdHJpbmcgYXJyYXk7IHBvcnRzIHRvIGJlIGVuYWJsZWQuCiMgICAgICAgUG9ydHMgbXVzdCBiZSBwb3N0Zml4ZWQgd2l0aCAvdGNwIG9yIC91ZHAKZmlyZXdhbGxkX2NvbmZpZ3VyZSgpIHsKICAgIGxvY2FsIC1uIHBvcnRzPSIkMSIKICAgIGxvZyAic3RhcnRpbmciCgogICAgZmlyZXdhbGxkX2NvbmZpZ3VyZV9iYWNrZW5kCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgc2VydmljZT0oCiAgICAgICAgImZpcmV3YWxsZCIKICAgICkKICAgIGVuYWJsZV9zZXJ2aWNlcyBzZXJ2aWNlCgogICAgbG9nICJFbmFibGluZyBwb3J0cyAke3BvcnRzWypdfSBvbiBkZWZhdWx0IGZpcmV3YWxsZCB6b25lIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDY4CiAgICBmb3IgcG9ydCBpbiAke3BvcnRzW0BdfTsgZG8KICAgICAgICBsb2cgIkVuYWJsaW5nIHBvcnQgJHBvcnQgbm93IgogICAgICAgIGZpcmV3YWxsLWNtZCAiLS1hZGQtcG9ydD0kcG9ydCIgXAogICAgICAgICAgICAgICAgICAgICAtLXBlcm1hbmVudAogICAgZG9uZQoKICAgIGxvZyAiV3JpdGluZyBydW50aW1lIGNvbmZpZyB0byBwZXJtYW5lbnQgY29uZmlnIgogICAgZmlyZXdhbGwtY21kIC0tcnVudGltZS10by1wZXJtYW5lbnQKfQoKI1N0YXJ0IG9mIHJwVk1TUy5zaAojIS9iaW4vYmFzaAoKc2V0IC1vIGVycmV4aXQgXAogICAgLW8gcGlwZWZhaWwgXAogICAgLW8gbm91bnNldAoKbWFpbigpIHsKICAgICMgdHJhbnNhY3Rpb24gYXR0ZW1wdCByZXRyeSB0aW1lIGluIHNlY29uZHMKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJpIHJldHJ5X3dhaXRfdGltZT0zMAogICAgbG9jYWwgLXJpIHBrZ19yZXRyeV9jb3VudD02MAoKICAgIGNyZWF0ZV9yZXF1aXJlZF9kaXJzCiAgICBjb25maWd1cmVfc3NoZAogICAgY29uZmlndXJlX3JwbV9yZXBvcyByZXRyeV93YWl0X3RpbWUgXAogICAgICAgICAgICAgICAgICAgICAgICAiJHBrZ19yZXRyeV9jb3VudCIKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1hciBleGNsdWRlX3BrZ3M9KAogICAgICAgICIteCBXQUxpbnV4QWdlbnQiCiAgICAgICAgIi14IFdBTGludXhBZ2VudC11ZGV2IgogICAgKQoKICAgIGRuZl91cGRhdGVfcGtncyBleGNsdWRlX3BrZ3MgXAogICAgICAgICAgICAgICAgICAgIHJldHJ5X3dhaXRfdGltZSBcCiAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtcmEgaW5zdGFsbF9wa2dzPSgKICAgICAgICBhenVyZS1jbGkKICAgICAgICBjbGFtYXYKICAgICAgICBhenNlYy1jbGFtYXYKICAgICAgICBhenVyZS1jbGkKICAgICAgICBhenVyZS1tZHNkCiAgICAgICAgYXp1cmUtc2VjdXJpdHkKICAgICAgICBwb2RtYW4KICAgICAgICBwb2RtYW4tZG9ja2VyCiAgICAgICAgb3BlbnNzbC1wZXJsCiAgICAgICAgIyBoYWNrIC0gd2UgYXJlIGluc3RhbGxpbmcgcHl0aG9uMyBvbiBob3N0cyBkdWUgdG8gYW4gaXNzdWUgd2l0aCBBenVyZSBMaW51eCBFeHRlbnNpb25zIGh0dHBzOi8vZ2l0aHViLmNvbS9BenVyZS9henVyZS1saW51eC1leHRlbnNpb25zL3B1bGwvMTUwNQogICAgICAgIHB5dGhvbjMKICAgICAgICAjIHJlcXVpcmVkIGZvciBwb2RtYW4gbmV0d29ya2luZwogICAgICAgIGZpcmV3YWxsZAogICAgKQoKICAgIGRuZl9pbnN0YWxsX3BrZ3MgaW5zdGFsbF9wa2dzIFwKICAgICAgICAgICAgICAgICAgICAgcmV0cnlfd2FpdF90aW1lIFwKICAgICAgICAgICAgICAgICAgICAgIiRwa2dfcmV0cnlfY291bnQiCgogICAgIyBUT0RPIHJlbW92ZSB0aGlzIG9uY2UgTWljcm9zb2Z0Q0JMTWFyaW5lcjpjYmwtbWFyaW5lcjpjYmwtbWFyaW5lci0yLWdlbjItZmlwcyBzdXBwb3J0cyBhdXRvbWF0aWMgdXBkYXRlcwogICAgIyBSZWZlcmVuY2U6IGh0dHBzOi8vbGVhcm4ubWljcm9zb2Z0LmNvbS9lbi11cy9henVyZS92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy92aXJ0dWFsLW1hY2hpbmUtc2NhbGUtc2V0cy1hdXRvbWF0aWMtdXBncmFkZSNzdXBwb3J0ZWQtb3MtaW1hZ2VzCiAgICBjb25maWd1cmVfZG5mX2Nyb25fam9iCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTE5CiAgICBjb25maWd1cmVfbG9ncm90YXRlCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTUzIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBtZG1pbWFnZT0iJHtSUElNQUdFJSUvKn0vJHtNRE1JTUFHRSMqL30iCiAgICBsb2NhbCAtciBycGltYWdlPSIkUlBJTUFHRSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXIgZmx1ZW50Yml0X2ltYWdlPSIkRkxVRU5UQklUSU1BR0UiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yQSBhcm9faW1hZ2VzPSgKICAgICAgICBbIm1kbSJdPSJtZG1pbWFnZSIKICAgICAgICBbInJwIl09InJwaW1hZ2UiCiAgICAgICAgWyJmbHVlbnRiaXQiXT0iZmx1ZW50Yml0X2ltYWdlIgogICAgKQoKICAgIHB1bGxfY29udGFpbmVyX2ltYWdlcyBhcm9faW1hZ2VzCgogICAgbG9jYWwgLXIgYXJvX25ldHdvcms9ImFybyIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJBIG5ldHdvcmtzPSgKICAgICAgICBbIiRhcm9fbmV0d29yayJdPSIxOTIuMTY4LjI1NC4wLzI0IgogICAgKQogICAgY3JlYXRlX3BvZG1hbl9uZXR3b3JrcyBuZXR3b3JrcwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJhIGVuYWJsZV9wb3J0cz0oCiAgICAgICAgIyBSUCBmcm9udGVuZAogICAgICAgICI0NDMvdGNwIgogICAgICAgICMgUG9ydGFsIHdlYgogICAgICAgICI0NDQvdGNwIgogICAgICAgICMgUG9ydGFsIHNzaAogICAgICAgICIyMjIyL3RjcCIKICAgICAgICAjIEpJVCBzc2gKICAgICAgICAiMjIvdGNwIgogICAgKQoKICAgIGZpcmV3YWxsZF9jb25maWd1cmUgZW5hYmxlX3BvcnRzCgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBmbHVlbnRiaXRfY29uZl9maWxlPSJbSU5QVVRdCk5hbWUgc3lzdGVtZApUYWcgam91cm5hbGQKU3lzdGVtZF9GaWx0ZXIgX0NPTU09YXJvCkRCIC92YXIvbGliL2ZsdWVudC9qb3VybmFsZGIKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggam91cm5hbGQKCVJlbW92ZV93aWxkY2FyZCBfCglSZW1vdmUgVElNRVNUQU1QCgpbRklMVEVSXQoJTmFtZSByZXdyaXRlX3RhZwoJTWF0Y2ggam91cm5hbGQKCVJ1bGUgXCRMT0dLSU5EIGFzeW5jcW9zIGFzeW5jcW9zIHRydWUKCltGSUxURVJdCglOYW1lIG1vZGlmeQoJTWF0Y2ggYXN5bmNxb3MKCVJlbW92ZSBDTElFTlRfUFJJTkNJUEFMX05BTUUKCVJlbW92ZSBGSUxFCglSZW1vdmUgQ09NUE9ORU5UCgpbRklMVEVSXQoJTmFtZSByZXdyaXRlX3RhZwoJTWF0Y2ggam91cm5hbGQKCVJ1bGUgXCRMT0dLSU5EIGlmeGF1ZGl0IGlmeGF1ZGl0IGZhbHNlCgpbT1VUUFVUXQoJTmFtZSBmb3J3YXJkCglNYXRjaCAqCglQb3J0IDI5MjMwIgoKCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICAgIGxvY2FsIC1yIG1kc2RfY29uZmlnX3ZlcnNpb249IiRSUE1EU0RDT05GSUdWRVJTSU9OIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgICBsb2NhbCAtciBhcm9fcnBfY29uZl9maWxlPSJBQ1JfUkVTT1VSQ0VfSUQ9JyRBQ1JSRVNPVVJDRUlEJwpBRE1JTl9BUElfQ0xJRU5UX0NFUlRfQ09NTU9OX05BTUU9JyRBRE1JTkFQSUNMSUVOVENFUlRDT01NT05OQU1FJwpBUk1fQVBJX0NMSUVOVF9DRVJUX0NPTU1PTl9OQU1FPSckQVJNQVBJQ0xJRU5UQ0VSVENPTU1PTk5BTUUnCkFaVVJFX0FSTV9DTElFTlRfSUQ9JyRBUk1DTElFTlRJRCcKQVpVUkVfRlBfQ0xJRU5UX0lEPSckRlBDTElFTlRJRCcKQVpVUkVfRlBfU0VSVklDRV9QUklOQ0lQQUxfSUQ9JyRGUFNFUlZJQ0VQUklOQ0lQQUxJRCcKQ0xVU1RFUl9NRE1fQUNDT1VOVD0nJENMVVNURVJNRE1BQ0NPVU5UJwpDTFVTVEVSX01ETV9OQU1FU1BBQ0U9UlAKQ0xVU1RFUl9NRFNEX0FDQ09VTlQ9JyRDTFVTVEVSTURTREFDQ09VTlQnCkNMVVNURVJfTURTRF9DT05GSUdfVkVSU0lPTj0nJENMVVNURVJNRFNEQ09ORklHVkVSU0lPTicKQ0xVU1RFUl9NRFNEX05BTUVTUEFDRT0nJENMVVNURVJNRFNETkFNRVNQQUNFJwpEQVRBQkFTRV9BQ0NPVU5UX05BTUU9JyREQVRBQkFTRUFDQ09VTlROQU1FJwpET01BSU5fTkFNRT0nJExPQ0FUSU9OLiRDTFVTVEVSUEFSRU5URE9NQUlOTkFNRScKR0FURVdBWV9ET01BSU5TPSckR0FURVdBWURPTUFJTlMnCkdBVEVXQVlfUkVTT1VSQ0VHUk9VUD0nJEdBVEVXQVlSRVNPVVJDRUdST1VQTkFNRScKS0VZVkFVTFRfUFJFRklYPSckS0VZVkFVTFRQUkVGSVgnCk1ETV9BQ0NPVU5UPSckUlBNRE1BQ0NPVU5UJwpNRE1fTkFNRVNQQUNFPScke3JvbGVfcnBeXn0nCk1EU0RfRU5WSVJPTk1FTlQ9JyRNRFNERU5WSVJPTk1FTlQnClJQX0ZFQVRVUkVTPSckUlBGRUFUVVJFUycKUlBJTUFHRT0nJHJwaW1hZ2UnCkFST19JTlNUQUxMX1ZJQV9ISVZFPSckQ0xVU1RFUlNJTlNUQUxMVklBSElWRScKQVJPX0hJVkVfREVGQVVMVF9JTlNUQUxMRVJfUFVMTFNQRUM9JyRDTFVTVEVSREVGQVVMVElOU1RBTExFUlBVTExTUEVDJwpBUk9fQURPUFRfQllfSElWRT0nJENMVVNURVJTQURPUFRCWUhJVkUnCk9JRENfQUZEX0VORFBPSU5UPSckTE9DQVRJT04ub2ljLiRSUFBBUkVOVERPTUFJTk5BTUUnCk9JRENfU1RPUkFHRV9BQ0NPVU5UX05BTUU9JyRPSURDU1RPUkFHRUFDQ09VTlROQU1FJwoiCgogICAgIyB2YWx1ZXMgYXJlIHJlZmVyZW5jZXMgdG8gdmFyaWFibGVzLCB0aGV5IHNob3VsZCBub3QgYmUgZGVyZWZlcmVuY2VkIGhlcmUKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJBIGFyb19jb25maWdzPSgKICAgICAgICBbInJwX2NvbmZpZyJdPSJhcm9fcnBfY29uZl9maWxlIgogICAgICAgIFsiZmx1ZW50Yml0Il09ImZsdWVudGJpdF9jb25mX2ZpbGUiCiAgICAgICAgWyJtZHNkIl09Im1kc2RfY29uZmlnX3ZlcnNpb24iCiAgICAgICAgWyJuZXR3b3JrIl09ImFyb19uZXR3b3JrIgogICAgKQoKICAgIGNvbmZpZ3VyZV92bXNzX2Fyb19zZXJ2aWNlcyByb2xlX3JwIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm9faW1hZ2VzIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcm9fY29uZmlncwoKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogICAgbG9jYWwgLXJhIGFyb19zZXJ2aWNlcz0oCiAgICAgICAgImFyby1tb25pdG9yIgogICAgICAgICJhcm8tcG9ydGFsIgogICAgICAgICJhcm8tcnAiCiAgICAgICAgImF6c2VjZCIKICAgICAgICAibWRzZCIKICAgICAgICAibWRtIgogICAgICAgICJjaHJvbnlkIgogICAgICAgICJmbHVlbnRiaXQiCiAgICAgICAgImRvd25sb2FkLW1kc2QtY3JlZGVudGlhbHMudGltZXIiCiAgICAgICAgImRvd25sb2FkLW1kbS1jcmVkZW50aWFscy50aW1lciIKICAgICAgICAiZmlyZXdhbGxkIgogICAgKQoKICAgIGVuYWJsZV9zZXJ2aWNlcyBhcm9fc2VydmljZXMKCiAgICByZWJvb3Rfdm0KfQoKZXhwb3J0IEFaVVJFX0NMT1VEX05BTUU9IiR7QVpVUkVDTE9VRE5BTUU6PyJGYWlsZWQgdG8gY2Fycnkgb3ZlciB2YXJpYWJsZXMifSIKCiMgdXRpbC5zaCBkb2VzIG5vdCBleGlzdCB3aGVuIGRlcGxveWVkIHRvIFZNU1MgdmlhIFZNU1MgZXh0ZW5zaW9ucwojIFRoaXMgaXMgYmVjYXVzZSBjb21tb25WTVNTLnNoIGlzIGNvbmNhdGVuYXRlZCB3aXRoIHRoaXMgc2NyaXB0CnV0aWw9InV0aWwuc2giCmlmIFsgLWYgIiR1dGlsIiBdOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPXV0aWwuc2gKICAgIHNvdXJjZSAiJHV0aWwiCmZpCgptYWluICIkQCIK')))]" + } + } + }, + { + "name": "AzureMonitorLinuxAgent", + "properties": { + "publisher": "Microsoft.Azure.Monitor", + "type": "AzureMonitorLinuxAgent", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "enableAutomaticUpgrade": true, + "settings": { + "GCS_AUTO_CONFIG": true } } } diff --git a/pkg/deploy/generator/resources_dev.go b/pkg/deploy/generator/resources_dev.go index 1bdb461e6da..a7864df136a 100644 --- a/pkg/deploy/generator/resources_dev.go +++ b/pkg/deploy/generator/resources_dev.go @@ -101,7 +101,11 @@ func (g *generator) devProxyVMSS() *arm.Resource { ) } - trailer := base64.StdEncoding.EncodeToString(scriptDevProxyVMSS) + var sb strings.Builder + + sb.WriteString(string(scriptDevProxyVMSS)) + + trailer := base64.StdEncoding.EncodeToString([]byte(sb.String())) parts = append(parts, "'\n'", fmt.Sprintf("base64ToString('%s')", trailer)) diff --git a/pkg/deploy/generator/resources_gateway.go b/pkg/deploy/generator/resources_gateway.go index ab3d1869e27..2fea65b04df 100644 --- a/pkg/deploy/generator/resources_gateway.go +++ b/pkg/deploy/generator/resources_gateway.go @@ -241,7 +241,19 @@ func (g *generator) gatewayVMSS() *arm.Resource { "''')\n'", ) - trailer := base64.StdEncoding.EncodeToString(scriptGatewayVMSS) + var sb strings.Builder + + // VMSS extensions only support one custom script + // Because of this, the util-*.sh scripts are prefixed to the bootstrapping script + // main is called at the end of the bootstrapping script, so appending them will not work + sb.WriteString(string(scriptUtilCommon)) + sb.WriteString(string(scriptUtilPackages)) + sb.WriteString(string(scriptUtilServices)) + sb.WriteString(string(scriptUtilSystem)) + sb.WriteString("\n#Start of gatewayVMSS.sh\n") + sb.WriteString(string(scriptGatewayVMSS)) + + trailer := base64.StdEncoding.EncodeToString([]byte(sb.String())) parts = append(parts, "'\n'", fmt.Sprintf("base64ToString('%s')", trailer)) @@ -340,6 +352,23 @@ func (g *generator) gatewayVMSS() *arm.Resource { }, }, }, + { + // az-secmonitor package no longer needs to be manually installed + // References: + // https://eng.ms/docs/products/azure-linux/gettingstarted/aks/monitoring + // https://msazure.visualstudio.com/ASMDocs/_wiki/wikis/ASMDocs.wiki/179541/Linux-AzSecPack-AutoConfig-Onboarding-(manual-for-C-AI)?anchor=3.1.1-using-arm-template-resource-elements + Name: to.StringPtr("AzureMonitorLinuxAgent"), + VirtualMachineScaleSetExtensionProperties: &mgmtcompute.VirtualMachineScaleSetExtensionProperties{ + Publisher: to.StringPtr("Microsoft.Azure.Monitor"), + EnableAutomaticUpgrade: to.BoolPtr(true), + AutoUpgradeMinorVersion: to.BoolPtr(true), + TypeHandlerVersion: to.StringPtr("1.0"), + Type: to.StringPtr("AzureMonitorLinuxAgent"), + Settings: map[string]interface{}{ + "GCS_AUTO_CONFIG": true, + }, + }, + }, }, }, DiagnosticsProfile: &mgmtcompute.DiagnosticsProfile{ diff --git a/pkg/deploy/generator/resources_rp.go b/pkg/deploy/generator/resources_rp.go index 9dcf881a97c..03bb2c8dc56 100644 --- a/pkg/deploy/generator/resources_rp.go +++ b/pkg/deploy/generator/resources_rp.go @@ -441,7 +441,19 @@ func (g *generator) rpVMSS() *arm.Resource { "''')\n'", ) - trailer := base64.StdEncoding.EncodeToString(scriptRpVMSS) + var sb strings.Builder + + // VMSS extensions only support one custom script + // Because of this, the util-*.sh scripts are prefixed to the bootstrapping script + // main is called at the end of the bootstrapping script, so appending them will not work + sb.WriteString(string(scriptUtilCommon)) + sb.WriteString(string(scriptUtilPackages)) + sb.WriteString(string(scriptUtilServices)) + sb.WriteString(string(scriptUtilSystem)) + sb.WriteString("\n#Start of rpVMSS.sh\n") + sb.WriteString(string(scriptRpVMSS)) + + trailer := base64.StdEncoding.EncodeToString([]byte(sb.String())) parts = append(parts, "'\n'", fmt.Sprintf("base64ToString('%s')", trailer)) @@ -476,6 +488,7 @@ func (g *generator) rpVMSS() *arm.Resource { }, }, StorageProfile: &mgmtcompute.VirtualMachineScaleSetStorageProfile{ + // https://eng.ms/docs/products/azure-linux/gettingstarted/azurevm/azurevm ImageReference: &mgmtcompute.ImageReference{ Publisher: to.StringPtr("RedHat"), Offer: to.StringPtr("RHEL"), @@ -537,6 +550,23 @@ func (g *generator) rpVMSS() *arm.Resource { }, }, }, + { + // az-secmonitor package no longer needs to be manually installed + // References: + // https://eng.ms/docs/products/azure-linux/gettingstarted/aks/monitoring + // https://msazure.visualstudio.com/ASMDocs/_wiki/wikis/ASMDocs.wiki/179541/Linux-AzSecPack-AutoConfig-Onboarding-(manual-for-C-AI)?anchor=3.1.1-using-arm-template-resource-elements + Name: to.StringPtr("AzureMonitorLinuxAgent"), + VirtualMachineScaleSetExtensionProperties: &mgmtcompute.VirtualMachineScaleSetExtensionProperties{ + Publisher: to.StringPtr("Microsoft.Azure.Monitor"), + EnableAutomaticUpgrade: to.BoolPtr(true), + AutoUpgradeMinorVersion: to.BoolPtr(true), + TypeHandlerVersion: to.StringPtr("1.0"), + Type: to.StringPtr("AzureMonitorLinuxAgent"), + Settings: map[string]interface{}{ + "GCS_AUTO_CONFIG": true, + }, + }, + }, }, }, DiagnosticsProfile: &mgmtcompute.DiagnosticsProfile{ diff --git a/pkg/deploy/generator/scripts.go b/pkg/deploy/generator/scripts.go index a60f9fefb73..c07f7ca9167 100644 --- a/pkg/deploy/generator/scripts.go +++ b/pkg/deploy/generator/scripts.go @@ -15,3 +15,15 @@ var scriptGatewayVMSS []byte //go:embed scripts/rpVMSS.sh var scriptRpVMSS []byte + +//go:embed scripts/util-system.sh +var scriptUtilSystem []byte + +//go:embed scripts/util-services.sh +var scriptUtilServices []byte + +//go:embed scripts/util-packages.sh +var scriptUtilPackages []byte + +//go:embed scripts/util-common.sh +var scriptUtilCommon []byte diff --git a/pkg/deploy/generator/scripts/devProxyVMSS.sh b/pkg/deploy/generator/scripts/devProxyVMSS.sh index f09c9f57f78..659c149bb0e 100644 --- a/pkg/deploy/generator/scripts/devProxyVMSS.sh +++ b/pkg/deploy/generator/scripts/devProxyVMSS.sh @@ -1,3 +1,4 @@ +#!/bin/bash #Adding retry logic to yum commands in order to avoid stalling out on resource locks echo "installing moby-engine (docker)" for attempt in {1..60}; do diff --git a/pkg/deploy/generator/scripts/gatewayVMSS.sh b/pkg/deploy/generator/scripts/gatewayVMSS.sh index 15faeab8e23..64fd6f88723 100644 --- a/pkg/deploy/generator/scripts/gatewayVMSS.sh +++ b/pkg/deploy/generator/scripts/gatewayVMSS.sh @@ -1,172 +1,100 @@ #!/bin/bash -echo "setting ssh password authentication" -# We need to manually set PasswordAuthentication to true in order for the VMSS Access JIT to work -sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' /etc/ssh/sshd_config -systemctl reload sshd.service - -#Adding retry logic to yum commands in order to avoid stalling out on resource locks -echo "running RHUI fix" -for attempt in {1..60}; do - yum update -y --disablerepo='*' --enablerepo='rhui-microsoft-azure*' && break - if [[ ${attempt} -lt 60 ]]; then sleep 30; else exit 1; fi -done - -echo "running yum update" -for attempt in {1..60}; do - yum -y -x WALinuxAgent -x WALinuxAgent-udev update --allowerasing && break - if [[ ${attempt} -lt 60 ]]; then sleep 30; else exit 1; fi -done - -echo "extending partition table" -# Linux block devices are inconsistently named -# it's difficult to tie the lvm pv to the physical disk using /dev/disk files, which is why lvs is used here -physical_disk="$(lvs -o devices -a | head -n2 | tail -n1 | cut -d ' ' -f 3 | cut -d \( -f 1 | tr -d '[:digit:]')" -growpart "$physical_disk" 2 - -echo "extending filesystems" -lvextend -l +20%FREE /dev/rootvg/rootlv -xfs_growfs / - -lvextend -l +100%FREE /dev/rootvg/varlv -xfs_growfs /var - -rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8 -rpm --import https://packages.microsoft.com/keys/microsoft.asc - -for attempt in {1..60}; do - yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm && break - if [[ ${attempt} -lt 60 ]]; then sleep 30; else exit 1; fi -done - -echo "configuring logrotate" - -# gateway_logdir is a readonly variable that specifies the host path mount point for the gateway container log file -# for the purpose of rotating the gateway logs -declare -r gateway_logdir='/var/log/aro-gateway' - -cat >/etc/logrotate.conf </etc/yum.repos.d/azure.repo <<'EOF' -[azure-cli] -name=azure-cli -baseurl=https://packages.microsoft.com/yumrepos/azure-cli -enabled=yes -gpgcheck=yes - -[azurecore] -name=azurecore -baseurl=https://packages.microsoft.com/yumrepos/azurecore -enabled=yes -gpgcheck=no -EOF - -semanage fcontext -a -t var_log_t "/var/log/journal(/.*)?" -mkdir -p /var/log/journal - -for attempt in {1..60}; do - yum -y install clamav azsec-clamav azsec-monitor azure-cli azure-mdsd azure-security podman-docker openssl-perl python3 && break - # hack - we are installing python3 on hosts due to an issue with Azure Linux Extensions https://github.com/Azure/azure-linux-extensions/pull/1505 - if [[ ${attempt} -lt 60 ]]; then sleep 30; else exit 1; fi -done - -echo "applying firewall rules" -# https://access.redhat.com/security/cve/cve-2020-13401 -cat >/etc/sysctl.d/02-disable-accept-ra.conf <<'EOF' -net.ipv6.conf.all.accept_ra=0 -EOF - -cat >/etc/sysctl.d/01-disable-core.conf <<'EOF' -kernel.core_pattern = |/bin/true -EOF -sysctl --system - -firewall-cmd --add-port=80/tcp --permanent -firewall-cmd --add-port=8081/tcp --permanent -firewall-cmd --add-port=443/tcp --permanent - -echo "logging into prod acr" -export AZURE_CLOUD_NAME=$AZURECLOUDNAME -az login -i --allow-no-subscriptions - -# The managed identity that the VM runs as only has a single roleassignment. -# This role assignment is ACRPull which is not necessarily present in the -# subscription we're deploying into. If the identity does not have any -# role assignments scoped on the subscription we're deploying into, it will -# not show on az login -i, which is why the below line is commented. -# az account set -s "$SUBSCRIPTIONID" - -# Suppress emulation output for podman instead of docker for az acr compatability -mkdir -p /etc/containers/ -touch /etc/containers/nodocker - -mkdir -p /root/.docker -REGISTRY_AUTH_FILE=/root/.docker/config.json az acr login --name "$(sed -e 's|.*/||' <<<"$ACRRESOURCEID")" - -MDMIMAGE="${RPIMAGE%%/*}/${MDMIMAGE#*/}" -docker pull "$MDMIMAGE" -docker pull "$RPIMAGE" -docker pull "$FLUENTBITIMAGE" - -az logout - -echo "configuring fluentbit service" -mkdir -p /etc/fluentbit/ -mkdir -p /var/lib/fluent - -cat >/etc/fluentbit/fluentbit.conf <<'EOF' -[INPUT] - Name systemd - Tag journald - Systemd_Filter _COMM=aro - DB /var/lib/fluent/journaldb +set -o errexit \ + -o pipefail \ + -o nounset + +main() { + # transaction attempt retry time in seconds + # shellcheck disable=SC2034 + local -ri retry_wait_time=30 + # shellcheck disable=SC2068 + local -ri pkg_retry_count=60 + + create_required_dirs + configure_sshd + configure_rpm_repos retry_wait_time \ + "$pkg_retry_count" + + # shellcheck disable=SC2034 + local -ar exclude_pkgs=( + "-x WALinuxAgent" + "-x WALinuxAgent-udev" + ) + + dnf_update_pkgs exclude_pkgs \ + retry_wait_time \ + "$pkg_retry_count" + + # shellcheck disable=SC2034 + local -ra install_pkgs=( + azure-cli + clamav + azsec-clamav + azure-cli + azure-mdsd + azure-security + podman + podman-docker + openssl-perl + # hack - we are installing python3 on hosts due to an issue with Azure Linux Extensions https://github.com/Azure/azure-linux-extensions/pull/1505 + python3 + # required for podman networking + firewalld + ) + + dnf_install_pkgs install_pkgs \ + retry_wait_time \ + "$pkg_retry_count" + + # TODO remove this once MicrosoftCBLMariner:cbl-mariner:cbl-mariner-2-gen2-fips supports automatic updates + # Reference: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-automatic-upgrade#supported-os-images + configure_dnf_cron_job + + # shellcheck disable=SC2119 + configure_logrotate + + # shellcheck disable=SC2034 disable=SC2153 + local -r mdmimage="${RPIMAGE%%/*}/${MDMIMAGE#*/}" + local -r rpimage="$RPIMAGE" + # shellcheck disable=SC2034 + local -r fluentbit_image="$FLUENTBITIMAGE" + # values are references to variables, they should not be dereferenced here + # shellcheck disable=SC2034 + local -rA aro_images=( + ["mdm"]="mdmimage" + ["rp"]="rpimage" + ["fluentbit"]="fluentbit_image" + ) + + pull_container_images aro_images + + local -r aro_network="aro" + # shellcheck disable=SC2034 + local -rA networks=( + ["$aro_network"]="192.168.254.0/24" + ) + create_podman_networks networks + + # shellcheck disable=SC2034 + local -ra enable_ports=( + # RP gateway + "80/tcp" + "8081/tcp" + "443/tcp" + # JIT ssh + "22/tcp" + ) + + firewalld_configure enable_ports + + + # shellcheck disable=SC2034 + local -r fluentbit_conf_file="[INPUT] +Name systemd +Tag journald +Systemd_Filter _COMM=aro +DB /var/lib/fluent/journaldb [FILTER] Name modify @@ -177,324 +105,59 @@ cat >/etc/fluentbit/fluentbit.conf <<'EOF' [OUTPUT] Name forward Match * - Port 29230 -EOF - -echo "FLUENTBITIMAGE=$FLUENTBITIMAGE" >/etc/sysconfig/fluentbit - -cat >/etc/systemd/system/fluentbit.service <<'EOF' -[Unit] -After=network-online.target -Wants=network-online.target -StartLimitIntervalSec=0 - -[Service] -RestartSec=1s -EnvironmentFile=/etc/sysconfig/fluentbit -ExecStartPre=-/usr/bin/docker rm -f %N -ExecStart=/usr/bin/docker run \ - --security-opt label=disable \ - --entrypoint /opt/td-agent-bit/bin/td-agent-bit \ - --net=host \ - --hostname %H \ - --name %N \ - --rm \ - --cap-drop net_raw \ - -v /etc/fluentbit/fluentbit.conf:/etc/fluentbit/fluentbit.conf \ - -v /var/lib/fluent:/var/lib/fluent:z \ - -v /var/log/journal:/var/log/journal:ro \ - -v /etc/machine-id:/etc/machine-id:ro \ - $FLUENTBITIMAGE \ - -c /etc/fluentbit/fluentbit.conf - -ExecStop=/usr/bin/docker stop %N -Restart=always -RestartSec=5 -StartLimitInterval=0 - -[Install] -WantedBy=multi-user.target -EOF - -echo "configuring mdm service" -cat >/etc/sysconfig/mdm </etc/systemd/system/mdm.service <<'EOF' -[Unit] -After=network-online.target -Wants=network-online.target - -[Service] -EnvironmentFile=/etc/sysconfig/mdm -ExecStartPre=-/usr/bin/docker rm -f %N -ExecStart=/usr/bin/docker run \ - --entrypoint /usr/sbin/MetricsExtension \ - --hostname %H \ - --name %N \ - --rm \ - --cap-drop net_raw \ - -m 2g \ - -v /etc/mdm.pem:/etc/mdm.pem \ - -v /var/etw:/var/etw:z \ - $MDMIMAGE \ - -CertFile /etc/mdm.pem \ - -FrontEndUrl $MDMFRONTENDURL \ - -Logger Console \ - -LogLevel Warning \ - -PrivateKeyFile /etc/mdm.pem \ - -SourceEnvironment $MDMSOURCEENVIRONMENT \ - -SourceRole $MDMSOURCEROLE \ - -SourceRoleInstance $MDMSOURCEROLEINSTANCE -ExecStop=/usr/bin/docker stop %N -Restart=always -RestartSec=1 -StartLimitInterval=0 - -[Install] -WantedBy=multi-user.target -EOF - -echo "configuring aro-gateway service" -cat >/etc/sysconfig/aro-gateway </etc/systemd/system/aro-gateway.service </etc/systemd/system/download-$var-credentials.service </etc/systemd/system/download-$var-credentials.timer </usr/local/bin/download-credentials.sh </etc/systemd/system/watch-mdm-credentials.service </etc/systemd/system/watch-mdm-credentials.path </etc/systemd/system/mdsd.service.d/override.conf <<'EOF' -[Unit] -After=network-online.target -EOF - -cat >/etc/default/mdsd </dev/null -c_rehash /usr/lib/ssl/certs - -# we leave clientId blank as long as only 1 managed identity assigned to vmss -# if we have more than 1, we will need to populate with clientId used for off-node scanning -cat >/etc/default/vsa-nodescan-agent.config </etc/logrotate.conf <<'EOF' -# see "man logrotate" for details -# rotate log files weekly -weekly - -# keep 2 weeks worth of backlogs -rotate 2 - -# create new (empty) log files after rotating old ones -create - -# use date as a suffix of the rotated file -dateext - -# uncomment this if you want your log files compressed -compress - -# RPM packages drop log rotation information into this directory -include /etc/logrotate.d - -# no packages own wtmp and btmp -- we'll rotate them here -/var/log/wtmp { - monthly - create 0664 root utmp - minsize 1M - rotate 1 -} - -/var/log/btmp { - missingok - monthly - create 0600 root utmp - rotate 1 -} -EOF - -echo "configuring yum repository and running yum update" -cat >/etc/yum.repos.d/azure.repo <<'EOF' -[azure-cli] -name=azure-cli -baseurl=https://packages.microsoft.com/yumrepos/azure-cli -enabled=yes -gpgcheck=yes - -[azurecore] -name=azurecore -baseurl=https://packages.microsoft.com/yumrepos/azurecore -enabled=yes -gpgcheck=no -EOF - -semanage fcontext -a -t var_log_t "/var/log/journal(/.*)?" -mkdir -p /var/log/journal - -for attempt in {1..60}; do -yum -y install clamav azsec-clamav azsec-monitor azure-cli azure-mdsd azure-security podman podman-docker openssl-perl python3 && break - # hack - we are installing python3 on hosts due to an issue with Azure Linux Extensions https://github.com/Azure/azure-linux-extensions/pull/1505 - if [[ ${attempt} -lt 60 ]]; then sleep 30; else exit 1; fi -done - -# https://access.redhat.com/security/cve/cve-2020-13401 -echo "applying firewall rules" -cat >/etc/sysctl.d/02-disable-accept-ra.conf <<'EOF' -net.ipv6.conf.all.accept_ra=0 -EOF - -cat >/etc/sysctl.d/01-disable-core.conf <<'EOF' -kernel.core_pattern = |/bin/true -EOF -sysctl --system - -firewall-cmd --add-port=443/tcp --permanent -firewall-cmd --add-port=444/tcp --permanent -firewall-cmd --add-port=2222/tcp --permanent - -export AZURE_CLOUD_NAME=$AZURECLOUDNAME - -echo "logging into prod acr" -az login -i --allow-no-subscriptions - -# Suppress emulation output for podman instead of docker for az acr compatability -mkdir -p /etc/containers/ -touch /etc/containers/nodocker - -mkdir -p /root/.docker -REGISTRY_AUTH_FILE=/root/.docker/config.json az acr login --name "$(sed -e 's|.*/||' <<<"$ACRRESOURCEID")" - -MDMIMAGE="${RPIMAGE%%/*}/${MDMIMAGE#*/}" -docker pull "$MDMIMAGE" -docker pull "$RPIMAGE" -docker pull "$FLUENTBITIMAGE" - -az logout - -echo "configuring fluentbit service" -mkdir -p /etc/fluentbit/ -mkdir -p /var/lib/fluent - -cat >/etc/fluentbit/fluentbit.conf <<'EOF' -[INPUT] - Name systemd - Tag journald - Systemd_Filter _COMM=aro - DB /var/lib/fluent/journaldb +set -o errexit \ + -o pipefail \ + -o nounset + +main() { + # transaction attempt retry time in seconds + # shellcheck disable=SC2034 + local -ri retry_wait_time=30 + local -ri pkg_retry_count=60 + + create_required_dirs + configure_sshd + configure_rpm_repos retry_wait_time \ + "$pkg_retry_count" + + # shellcheck disable=SC2034 + local -ar exclude_pkgs=( + "-x WALinuxAgent" + "-x WALinuxAgent-udev" + ) + + dnf_update_pkgs exclude_pkgs \ + retry_wait_time \ + "$pkg_retry_count" + + # shellcheck disable=SC2034 + local -ra install_pkgs=( + azure-cli + clamav + azsec-clamav + azure-cli + azure-mdsd + azure-security + podman + podman-docker + openssl-perl + # hack - we are installing python3 on hosts due to an issue with Azure Linux Extensions https://github.com/Azure/azure-linux-extensions/pull/1505 + python3 + # required for podman networking + firewalld + ) + + dnf_install_pkgs install_pkgs \ + retry_wait_time \ + "$pkg_retry_count" + + # TODO remove this once MicrosoftCBLMariner:cbl-mariner:cbl-mariner-2-gen2-fips supports automatic updates + # Reference: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-automatic-upgrade#supported-os-images + configure_dnf_cron_job + + # shellcheck disable=SC2119 + configure_logrotate + + # shellcheck disable=SC2153 disable=SC2034 + local -r mdmimage="${RPIMAGE%%/*}/${MDMIMAGE#*/}" + local -r rpimage="$RPIMAGE" + # shellcheck disable=SC2034 + local -r fluentbit_image="$FLUENTBITIMAGE" + # shellcheck disable=SC2034 + local -rA aro_images=( + ["mdm"]="mdmimage" + ["rp"]="rpimage" + ["fluentbit"]="fluentbit_image" + ) + + pull_container_images aro_images + + local -r aro_network="aro" + # shellcheck disable=SC2034 + local -rA networks=( + ["$aro_network"]="192.168.254.0/24" + ) + create_podman_networks networks + + # shellcheck disable=SC2034 + local -ra enable_ports=( + # RP frontend + "443/tcp" + # Portal web + "444/tcp" + # Portal ssh + "2222/tcp" + # JIT ssh + "22/tcp" + ) + + firewalld_configure enable_ports + + # shellcheck disable=SC2034 + local -r fluentbit_conf_file="[INPUT] +Name systemd +Tag journald +Systemd_Filter _COMM=aro +DB /var/lib/fluent/journaldb [FILTER] Name modify @@ -155,7 +104,7 @@ cat >/etc/fluentbit/fluentbit.conf <<'EOF' [FILTER] Name rewrite_tag Match journald - Rule $LOGKIND asyncqos asyncqos true + Rule \$LOGKIND asyncqos asyncqos true [FILTER] Name modify @@ -167,117 +116,18 @@ cat >/etc/fluentbit/fluentbit.conf <<'EOF' [FILTER] Name rewrite_tag Match journald - Rule $LOGKIND ifxaudit ifxaudit false - -[FILTER] - Name rewrite_tag - Match journald - Rule $LOGKIND outboundRequests outboundRequests false - -[FILTER] - Name modify - Match outboundRequests - Remove CLIENT_PRINCIPAL_NAME - Remove FILE - Remove COMPONENT + Rule \$LOGKIND ifxaudit ifxaudit false [OUTPUT] Name forward Match * - Port 29230 -EOF - -echo "FLUENTBITIMAGE=$FLUENTBITIMAGE" >/etc/sysconfig/fluentbit + Port 29230" -cat >/etc/systemd/system/fluentbit.service <<'EOF' -[Unit] -After=network-online.target -Wants=network-online.target -StartLimitIntervalSec=0 -[Service] -RestartSec=1s -EnvironmentFile=/etc/sysconfig/fluentbit -ExecStartPre=-/usr/bin/docker rm -f %N -ExecStart=/usr/bin/docker run \ - --security-opt label=disable \ - --entrypoint /opt/td-agent-bit/bin/td-agent-bit \ - --net=host \ - --hostname %H \ - --name %N \ - --rm \ - --cap-drop net_raw \ - -v /etc/fluentbit/fluentbit.conf:/etc/fluentbit/fluentbit.conf \ - -v /var/lib/fluent:/var/lib/fluent:z \ - -v /var/log/journal:/var/log/journal:ro \ - -v /etc/machine-id:/etc/machine-id:ro \ - $FLUENTBITIMAGE \ - -c /etc/fluentbit/fluentbit.conf - -ExecStop=/usr/bin/docker stop %N -Restart=always -RestartSec=5 -StartLimitInterval=0 - -[Install] -WantedBy=multi-user.target -EOF - -mkdir /etc/aro-rp -base64 -d <<<"$ADMINAPICABUNDLE" >/etc/aro-rp/admin-ca-bundle.pem -if [[ -n "$ARMAPICABUNDLE" ]]; then - base64 -d <<<"$ARMAPICABUNDLE" >/etc/aro-rp/arm-ca-bundle.pem -fi -chown -R 1000:1000 /etc/aro-rp - -echo "configuring mdm service" -cat >/etc/sysconfig/mdm </etc/systemd/system/mdm.service <<'EOF' -[Unit] -After=network-online.target -Wants=network-online.target - -[Service] -EnvironmentFile=/etc/sysconfig/mdm -ExecStartPre=-/usr/bin/docker rm -f %N -ExecStart=/usr/bin/docker run \ - --entrypoint /usr/sbin/MetricsExtension \ - --hostname %H \ - --name %N \ - --rm \ - --cap-drop net_raw \ - -m 2g \ - -v /etc/mdm.pem:/etc/mdm.pem \ - -v /var/etw:/var/etw:z \ - $MDMIMAGE \ - -CertFile /etc/mdm.pem \ - -FrontEndUrl $MDMFRONTENDURL \ - -Logger Console \ - -LogLevel Warning \ - -PrivateKeyFile /etc/mdm.pem \ - -SourceEnvironment $MDMSOURCEENVIRONMENT \ - -SourceRole $MDMSOURCEROLE \ - -SourceRoleInstance $MDMSOURCEROLEINSTANCE -ExecStop=/usr/bin/docker stop %N -Restart=always -RestartSec=1 -StartLimitInterval=0 - -[Install] -WantedBy=multi-user.target -EOF - -echo "configuring aro-rp service" -cat >/etc/sysconfig/aro-rp </etc/sysconfig/aro-monitor </etc/systemd/system/aro-monitor.service <<'EOF' -[Unit] -After=network-online.target -Wants=network-online.target - -[Service] -EnvironmentFile=/etc/sysconfig/aro-monitor -ExecStartPre=-/usr/bin/docker rm -f %N -ExecStart=/usr/bin/docker run \ - --hostname %H \ - --name %N \ - --rm \ - --cap-drop net_raw \ - -e AZURE_FP_CLIENT_ID \ - -e DOMAIN_NAME \ - -e CLUSTER_MDSD_ACCOUNT \ - -e CLUSTER_MDSD_CONFIG_VERSION \ - -e GATEWAY_DOMAINS \ - -e GATEWAY_RESOURCEGROUP \ - -e MDSD_ENVIRONMENT \ - -e CLUSTER_MDSD_NAMESPACE \ - -e CLUSTER_MDM_ACCOUNT \ - -e CLUSTER_MDM_NAMESPACE \ - -e DATABASE_ACCOUNT_NAME \ - -e KEYVAULT_PREFIX \ - -e MDM_ACCOUNT \ - -e MDM_NAMESPACE \ - -m 2.5g \ - -v /run/systemd/journal:/run/systemd/journal \ - -v /var/etw:/var/etw:z \ - $RPIMAGE \ - monitor -Restart=always -RestartSec=1 -StartLimitInterval=0 - -[Install] -WantedBy=multi-user.target -EOF - -echo "configuring aro-portal service" -cat >/etc/sysconfig/aro-portal </etc/systemd/system/aro-portal.service <<'EOF' -[Unit] -After=network-online.target -Wants=network-online.target -StartLimitInterval=0 - -[Service] -EnvironmentFile=/etc/sysconfig/aro-portal -ExecStartPre=-/usr/bin/docker rm -f %N -ExecStart=/usr/bin/docker run \ - --hostname %H \ - --name %N \ - --rm \ - --cap-drop net_raw \ - -e AZURE_PORTAL_ACCESS_GROUP_IDS \ - -e AZURE_PORTAL_CLIENT_ID \ - -e AZURE_PORTAL_ELEVATED_GROUP_IDS \ - -e DATABASE_ACCOUNT_NAME \ - -e KEYVAULT_PREFIX \ - -e MDM_ACCOUNT \ - -e MDM_NAMESPACE \ - -e PORTAL_HOSTNAME \ - -m 2g \ - -p 444:8444 \ - -p 2222:2222 \ - -v /run/systemd/journal:/run/systemd/journal \ - -v /var/etw:/var/etw:z \ - $RPIMAGE \ - portal -Restart=always -RestartSec=1 - -[Install] -WantedBy=multi-user.target -EOF - -echo "configuring mdsd and mdm services" -chcon -R system_u:object_r:var_log_t:s0 /var/opt/microsoft/linuxmonagent - -mkdir -p /var/lib/waagent/Microsoft.Azure.KeyVault.Store - -for var in "mdsd" "mdm"; do -cat >/etc/systemd/system/download-$var-credentials.service </etc/systemd/system/download-$var-credentials.timer </usr/local/bin/download-credentials.sh </etc/systemd/system/watch-mdm-credentials.service </etc/systemd/system/watch-mdm-credentials.path </etc/systemd/system/mdsd.service.d/override.conf <<'EOF' -[Unit] -After=network-online.target -EOF - -cat >/etc/default/mdsd </dev/null -c_rehash /usr/lib/ssl/certs - -# we leave clientId blank as long as only 1 managed identity assigned to vmss -# if we have more than 1, we will need to populate with clientId used for off-node scanning -cat >/etc/default/vsa-nodescan-agent.config < "$filename" + else + log "Appending to $filename" + echo "$file_contents" >> "$filename" + fi +} + +# retry Adding retry logic to yum commands in order to avoid stalling out on resource locks +# args: +# 1) cmd_retry - nameref, array; Command and arguement(s) to retry +# 2) wait_time - nameref, integer; Time to wait before retrying command +# 3) retries - integer, optional; Ammount of times to retry command, defaults to 5 +retry() { + local -n cmd_retry="$1" + local -n wait_time="$2" + local -ri retries="${3:-5}" + + for attempt in {1..5}; do + log "attempt #${attempt} - ${FUNCNAME[2]}" + # shellcheck disable=SC2068 + ${cmd_retry[@]} & + + wait $! && break + if [ "${attempt}" -le "$retries" ]; then + sleep "$wait_time" + else + abort "attempt #${attempt} - Failed to update packages" + fi + done +} + +# verify_role +# args: +# 1) test_role - nameref; role being verified +# 2) certs - boolean, optional; defaults to false. Set to true to add devproxy to allowed roles +verify_role() { + local -n test_role="$1" + local -r certs="${2:-false}" + + allowed_roles_glob="($role_rp|$role_gateway)" + if $certs; then + # remove trailing ")" and append additional role + allowed_roles_glob="${allowed_roles_glob%\)*}|devproxy)" + fi + + if [[ "$test_role" =~ $allowed_roles_glob ]]; then + log "Verified role \"$test_role\"" + else + abort "failed to verify role, role \"${test_role}\" not in \"${allowed_roles_glob}\"" + fi +} + +# get_keyvault_suffix +# args: +# 1) rl - nameref, string; role to get short role for +# 2) kv_suffix - nameref, string; short role will be assigned to this nameref +# 3) sec_prefix - nameref, string; keyvault certificate prefix will be assigned to this nameref +get_keyvault_suffix() { + local -n rl="$1" + local -n kv_suffix="$2" + local -n sec_prefix="$3" + + local -r keyvault_suffix_rp="svc" + local -r keyvault_prefix_gateway="gwy" + + case "$rl" in + "$role_gateway") + kv_suffix="$keyvault_prefix_gateway" + sec_prefix="$keyvault_prefix_gateway" + ;; + "$role_rp") + kv_suffix="$keyvault_suffix_rp" + sec_prefix="$role_rp" + ;; + *) + abort "unkown role $rl" + ;; + esac +} + +# reboot_vm restores all selinux file contexts, then schedules a reboot for one hour later +# Reboots should scheduled after all VM extensions have had time to complete +# Reference: https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/custom-script-linux#tips +reboot_vm() { + log "starting" + + (shutdown -r now &) +} diff --git a/pkg/deploy/generator/scripts/util-packages.sh b/pkg/deploy/generator/scripts/util-packages.sh new file mode 100644 index 00000000000..7d059697d84 --- /dev/null +++ b/pkg/deploy/generator/scripts/util-packages.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# Repository and package management related functions + +configure_repo_mariner_extended() { + local -r extended_repo_config="https://packages.microsoft.com/cbl-mariner/2.0/prod/extended/x86_64/config.repo" + curl -sSL "$extended_repo_config" -o /etc/yum.repos.d/mariner-extended.repo + + local -r repo_name="cbl-mariner2.0prodextendedx86_64" + + local -ra cmd=( + dnf + update + -y + --enablerepo="$repo_name" + ) + + log "Enabling repo $repo_name" + retry cmd "$1" "${2:-}" +} + +# configure_rpm_repos +# New repositories should be added in their own functions, and called here +# args: +# 1) wait_time - nameref, integer; Time to wait before retrying command +# 2) retries - integer, optional; Amount of times to retry command, defaults to 5 +configure_rpm_repos() { + log "starting" + + configure_repo_mariner_extended "$1" "${2:-1}" +} + +# dnf_install_pkgs +# args: +# 1) pkgs - nameref, string array; Packages to be installed +# 2) wait_time - nameref, integer; Time to wait before retrying command +# 3) retries - integer, optional; Amount of times to retry command, defaults to 5 +dnf_install_pkgs() { + local -n pkgs="$1" + log "starting" + + local -a cmd=( + dnf + -y + install + ) + + # Reference: https://www.shellcheck.net/wiki/SC2206 + # append pkgs array to cmd + mapfile -O $(( ${#cmd[@]} + 1 )) -d ' ' cmd <<< "${pkgs[@]}" + local -r cmd + + log "Attempting to install packages: ${pkgs[*]}" + retry cmd "$2" "${3:-}" +} + + +# dnf_update_pkgs +# args: +# 1) excludes - nameref, string array, optional; Packages to exclude from updating +# Each index must be prefixed with -x +# 2) wait_time - nameref, integer; Time to wait before retrying command +# 3) retries - integer, optional; Ammount of times to retry command, defaults to 5 +dnf_update_pkgs() { + local -n excludes="${1:-empty_str}" + log "starting" + + local -a cmd=( + dnf + -y + # Replaced with excludes + "" + update + --allowerasing + ) + + if [ -n "${excludes}" ]; then + # Reference https://www.shellcheck.net/wiki/SC2206 + mapfile -O 2 cmd <<< "${excludes[@]}" + else + # Remove empty string if we aren't replacing them, probably doesn't matter, but why not be safe + unset "cmd[2]" + fi + local -r cmd + + log "Updating all packages excluding \"${excludes[*]:-}\"" + retry cmd "$2" "${3:-}" +} + +# configure_dnf_cron_job +# create cron job to auto update rpm packages +configure_dnf_cron_job() { + log "starting" + local -r cron_weekly_dnf_update_filename='/etc/cron.weekly/dnfupdate' + local -r cron_weekly_dnf_update_file="#!/bin/bash +dnf update -y" + + write_file cron_weekly_dnf_update_filename cron_weekly_dnf_update_file true + chmod u+x "$cron_weekly_dnf_update_filename" +} + +# rpm_import_keys +# args: +# 1) keys - nameref, string array; rpm keys to be imported +# 2) wait_time - nameref, integer; Time to wait before retrying command +rpm_import_keys() { + local -n keys="$1" + log "starting" + + # shellcheck disable=SC2068 + for key in ${keys[@]}; do + if [ ${#keys[@]} -eq 0 ]; then + break + fi + + local -a cmd=( + rpm + --import + -v + "$key" + ) + + log "Importing rpm repository key $key" + retry cmd "$2" "${3:-}" && unset key + done +} diff --git a/pkg/deploy/generator/scripts/util-services.sh b/pkg/deploy/generator/scripts/util-services.sh new file mode 100644 index 00000000000..d4fc2c436c0 --- /dev/null +++ b/pkg/deploy/generator/scripts/util-services.sh @@ -0,0 +1,673 @@ +#!/bin/bash +# ARO service setup functions + +# enable_services enables the systemd services that are passed in +# args: +# 1) services - array; services to be enabled +enable_services() { + local -n svcs="$1" + log "starting" + + systemctl daemon-reload + + log "enabling services ${svcs[*]}" + # shellcheck disable=SC2068 + for svc in ${svcs[@]}; do + log "Enabling and starting $svc now" + systemctl enable \ + --now \ + "$svc" + done +} + +# configure_service_aro_gateway +# args: +# 1) image - nameref, string; container image +# 2) role - nameref, string; VMSS role +# 3) conf_file - nameref, string; aro gateway environment file +# 4) network - nameref, string; podman network name to be attached +configure_service_aro_gateway() { + local -n image="$1" + local -n role="$2" + local -n conf_file="$3" + local -n network="$4" + log "starting" + log "Configuring aro-gateway service" + + local -r aro_gateway_conf_filename='/etc/sysconfig/aro-gateway' + + write_file aro_gateway_conf_filename conf_file true + + # shellcheck disable=SC2034 + local -r aro_gateway_service_filename='/etc/systemd/system/aro-gateway.service' + + # shellcheck disable=SC2034 + local -r aro_gateway_service_file="[Unit] +After=network-online.target +Wants=network-online.target + +[Service] +EnvironmentFile=${aro_gateway_conf_filename} +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --hostname %H \ + --name %N \ + --rm \ + --cap-drop net_raw \ + -e ACR_RESOURCE_ID \ + -e DATABASE_ACCOUNT_NAME \ + -e GATEWAY_DOMAINS \ + -e GATEWAY_FEATURES \ + -e MDM_ACCOUNT \ + -e MDM_NAMESPACE \ + -m 2g \ + --network=$network \ + -p 80:8080 \ + -p 8081:8081 \ + -p 443:8443 \ + -v /run/systemd/journal:/run/systemd/journal \ + -v /var/etw:/var/etw:z \ + $image \ + ${role,,} +ExecStop=/usr/bin/podman stop -t 3600 %N +TimeoutStopSec=3600 +Restart=always +RestartSec=1 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target + " + + write_file aro_gateway_service_filename aro_gateway_service_file true +} + +# configure_service_aro_rp +# args: +# 1) image - nameref, string; RP container image +# 2) role - nameref, string; VMSS role +# 3) conf_file - nameref, string; aro rp environment file +# 4) network - nameref, string; podman network name to be attached +configure_service_aro_rp() { + local -n image="$1" + local -n role="$2" + local -n conf_file="$3" + local -n network="$4" + log "starting" + log "Configuring aro-rp service" + + local -r aro_rp_conf_filename='/etc/sysconfig/aro-rp' + + write_file aro_rp_conf_filename conf_file true + + # shellcheck disable=SC2034 + local -r aro_rp_service_filename='/etc/systemd/system/aro-rp.service' + # shellcheck disable=SC2034 + local -r aro_rp_service_file="[Unit] +After=network-online.target +Wants=network-online.target + +[Service] +EnvironmentFile=${aro_rp_conf_filename} +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --hostname %H \ + --name %N \ + --rm \ + --cap-drop net_raw \ + -e ACR_RESOURCE_ID \ + -e ADMIN_API_CLIENT_CERT_COMMON_NAME \ + -e ARM_API_CLIENT_CERT_COMMON_NAME \ + -e AZURE_ARM_CLIENT_ID \ + -e AZURE_FP_CLIENT_ID \ + -e CLUSTER_MDM_ACCOUNT \ + -e CLUSTER_MDM_NAMESPACE \ + -e CLUSTER_MDSD_ACCOUNT \ + -e CLUSTER_MDSD_CONFIG_VERSION \ + -e CLUSTER_MDSD_NAMESPACE \ + -e DATABASE_ACCOUNT_NAME \ + -e DOMAIN_NAME \ + -e GATEWAY_DOMAINS \ + -e GATEWAY_RESOURCEGROUP \ + -e KEYVAULT_PREFIX \ + -e MDM_ACCOUNT \ + -e MDM_NAMESPACE \ + -e MDSD_ENVIRONMENT \ + -e RP_FEATURES \ + -e ARO_INSTALL_VIA_HIVE \ + -e ARO_HIVE_DEFAULT_INSTALLER_PULLSPEC \ + -e ARO_ADOPT_BY_HIVE \ + -e OIDC_AFD_ENDPOINT \ + -e OIDC_STORAGE_ACCOUNT_NAME \ + -m 2g \ + --network=$network \ + -p 443:8443 \ + -v /etc/aro-rp:/etc/aro-rp \ + -v /run/systemd/journal:/run/systemd/journal \ + -v /var/etw:/var/etw:z \ + $image \ + ${role,,} +ExecStop=/usr/bin/podman stop -t 3600 %N +TimeoutStopSec=3600 +Restart=always +RestartSec=1 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target" + + write_file aro_rp_service_filename aro_rp_service_file true +} + +# configure_service_aro_monitor +# args: +# 1) image - nameref, string; RP container image +# 2) network - nameref, string; podman network name to be attached +configure_service_aro_monitor() { + local -n image="$1" + local -n network="$2" + log "starting" + log "Configuring aro-monitor service" + + # DOMAIN_NAME, CLUSTER_MDSD_ACCOUNT, CLUSTER_MDSD_CONFIG_VERSION, GATEWAY_DOMAINS, GATEWAY_RESOURCEGROUP, MDSD_ENVIRONMENT CLUSTER_MDSD_NAMESPACE + # are not used, but can't easily be refactored out. Should be revisited in the future. + # shellcheck disable=SC2034 + local -r aro_monitor_service_conf_filename='/etc/sysconfig/aro-monitor' + # shellcheck disable=SC2034 + local -r aro_monitor_service_conf_file="AZURE_FP_CLIENT_ID='$FPCLIENTID' +DOMAIN_NAME='$LOCATION.$CLUSTERPARENTDOMAINNAME' +CLUSTER_MDSD_ACCOUNT='$CLUSTERMDSDACCOUNT' +CLUSTER_MDSD_CONFIG_VERSION='$CLUSTERMDSDCONFIGVERSION' +GATEWAY_DOMAINS='$GATEWAYDOMAINS' +GATEWAY_RESOURCEGROUP='$GATEWAYRESOURCEGROUPNAME' +MDSD_ENVIRONMENT='$MDSDENVIRONMENT' +CLUSTER_MDSD_NAMESPACE='$CLUSTERMDSDNAMESPACE' +CLUSTER_MDM_ACCOUNT='$CLUSTERMDMACCOUNT' +CLUSTER_MDM_NAMESPACE=BBM +DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME' +KEYVAULT_PREFIX='$KEYVAULTPREFIX' +MDM_ACCOUNT='$RPMDMACCOUNT' +MDM_NAMESPACE=BBM +RPIMAGE='$image'" + + write_file aro_monitor_service_conf_filename aro_monitor_service_conf_file true + + # shellcheck disable=SC2034 + local -r aro_monitor_service_filename='/etc/systemd/system/aro-monitor.service' + # shellcheck disable=SC2034 + local -r aro_monitor_service_file="[Unit] +After=network-online.target +Wants=network-online.target + +[Service] +EnvironmentFile=/etc/sysconfig/aro-monitor +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --hostname %H \ + --name %N \ + --rm \ + --cap-drop net_raw \ + --network=$network \ + -e AZURE_FP_CLIENT_ID \ + -e DOMAIN_NAME \ + -e CLUSTER_MDSD_ACCOUNT \ + -e CLUSTER_MDSD_CONFIG_VERSION \ + -e GATEWAY_DOMAINS \ + -e GATEWAY_RESOURCEGROUP \ + -e MDSD_ENVIRONMENT \ + -e CLUSTER_MDSD_NAMESPACE \ + -e CLUSTER_MDM_ACCOUNT \ + -e CLUSTER_MDM_NAMESPACE \ + -e DATABASE_ACCOUNT_NAME \ + -e KEYVAULT_PREFIX \ + -e MDM_ACCOUNT \ + -e MDM_NAMESPACE \ + -m 2.5g \ + -v /run/systemd/journal:/run/systemd/journal \ + -v /var/etw:/var/etw:z \ + $image \ + monitor +Restart=always +RestartSec=1 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target" + + write_file aro_monitor_service_filename aro_monitor_service_file true +} + +# configure_service_aro_portal +# args: +# 1) image - nameref, string; RP container image +# 2) network - nameref, string; podman network name to be attached +configure_service_aro_portal() { + local -n image="$1" + local -n network="$2" + log "starting" + log "Configuring aro portal service" + + # shellcheck disable=SC2034 + local -r aro_portal_service_conf_filename='/etc/sysconfig/aro-portal' + # shellcheck disable=SC2034 + local -r aro_portal_service_conf_file="AZURE_PORTAL_ACCESS_GROUP_IDS='$PORTALACCESSGROUPIDS' +AZURE_PORTAL_CLIENT_ID='$PORTALCLIENTID' +AZURE_PORTAL_ELEVATED_GROUP_IDS='$PORTALELEVATEDGROUPIDS' +DATABASE_ACCOUNT_NAME='$DATABASEACCOUNTNAME' +KEYVAULT_PREFIX='$KEYVAULTPREFIX' +MDM_ACCOUNT='$RPMDMACCOUNT' +MDM_NAMESPACE=Portal +PORTAL_HOSTNAME='$LOCATION.admin.$RPPARENTDOMAINNAME' +RPIMAGE='$image'" + + write_file aro_portal_service_conf_filename aro_portal_service_conf_file true + + # shellcheck disable=SC2034 + local -r aro_portal_service_filename='/etc/systemd/system/aro-portal.service' + # shellcheck disable=SC2034 + local -r aro_portal_service_file="[Unit] +After=network-online.target +Wants=network-online.target +StartLimitInterval=0 + +[Service] +EnvironmentFile=/etc/sysconfig/aro-portal +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --hostname %H \ + --name %N \ + --rm \ + --cap-drop net_raw \ + --network=$network \ + -e AZURE_PORTAL_ACCESS_GROUP_IDS \ + -e AZURE_PORTAL_CLIENT_ID \ + -e AZURE_PORTAL_ELEVATED_GROUP_IDS \ + -e DATABASE_ACCOUNT_NAME \ + -e KEYVAULT_PREFIX \ + -e MDM_ACCOUNT \ + -e MDM_NAMESPACE \ + -e PORTAL_HOSTNAME \ + -m 2g \ + -p 444:8444 \ + -p 2222:2222 \ + -v /run/systemd/journal:/run/systemd/journal \ + -v /var/etw:/var/etw:z \ + $image \ + portal +Restart=always +RestartSec=1 + +[Install] +WantedBy=multi-user.target" + + write_file aro_portal_service_filename aro_portal_service_file true +} + +# configure_service_mdsd +# args: +# 1) monitoring_role - nameref, string; can be "gateway" or "rp" +# 2) monitor_config_version - nameref, string; mdsd config version +configure_service_mdsd() { + local -n role="$1" + local -n monitor_config_version="$2" + log "starting" + log "configuring mdsd service" + + verify_role role + + local -r mdsd_service_dir="/etc/systemd/system/mdsd.service.d" + mkdir -p "$mdsd_service_dir" + + # shellcheck disable=SC2034 + local -r mdsd_override_conf_filename="$mdsd_service_dir/override.conf" + local -r mdsd_certificate_san="$(openssl x509 -in /var/lib/waagent/Microsoft.Azure.KeyVault.Store/mdsd.pem -noout -subject | sed -e 's/.*CN = //')" + # shellcheck disable=SC2034 + local -r mdsd_override_conf_file="[Unit] +After=network-online.target" + + write_file mdsd_override_conf_filename mdsd_override_conf_file true + + # shellcheck disable=SC2034 + local -r default_mdsd_filename="/etc/default/mdsd" + # shellcheck disable=SC2034 + local -r default_mdsd_file="MDSD_ROLE_PREFIX=/var/run/mdsd/default +MDSD_OPTIONS=\"-A -d -r \$MDSD_ROLE_PREFIX\" + +export MONITORING_GCS_ENVIRONMENT='$MDSDENVIRONMENT' +export MONITORING_GCS_ACCOUNT='$RPMDSDACCOUNT' +export MONITORING_GCS_REGION='$LOCATION' +export MONITORING_GCS_AUTH_ID_TYPE=AuthKeyVault +export MONITORING_GCS_AUTH_ID='$mdsd_certificate_san' +export MONITORING_GCS_NAMESPACE='$RPMDSDNAMESPACE' +export MONITORING_CONFIG_VERSION='$monitor_config_version' +export MONITORING_USE_GENEVA_CONFIG_SERVICE=true + +export MONITORING_TENANT='$LOCATION' +export MONITORING_ROLE='$role' +export MONITORING_ROLE_INSTANCE=\"$(hostname)\" + +export MDSD_MSGPACK_SORT_COLUMNS=\"1\"" + + write_file default_mdsd_filename default_mdsd_file true +} + +# configure_service_fluentbit +# args: +# 1) conf_file - string; fluenbit configuration file +# 2) image - string; fluentbit container image to run +# 3) network - nameref, string; podman network name to be attached +configure_service_fluentbit() { + # shellcheck disable=SC2034 + local -n conf_file="$1" + local -n image="$2" + local -n network="$3" + log "starting" + log "Configuring fluentbit service" + + mkdir -p /etc/fluentbit/ + mkdir -p /var/lib/fluent + + # shellcheck disable=SC2034 + local -r conf_filename='/etc/fluentbit/fluentbit.conf' + write_file conf_filename conf_file true + + # shellcheck disable=SC2034 + local -r sysconfig_filename='/etc/sysconfig/fluentbit' + # shellcheck disable=SC2034 + local -r sysconfig_file="FLUENTBITIMAGE=$image" + + write_file sysconfig_filename sysconfig_file true + + # shellcheck disable=SC2034 + local -r service_filename='/etc/systemd/system/fluentbit.service' + # shellcheck disable=SC2034 + local -r service_file="[Unit] +After=network-online.target +Wants=network-online.target +StartLimitIntervalSec=0 + +[Service] +RestartSec=1s +EnvironmentFile=/etc/sysconfig/fluentbit +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --security-opt label=disable \ + --entrypoint /opt/td-agent-bit/bin/td-agent-bit \ + --net=host \ + --hostname %H \ + --name %N \ + --rm \ + --cap-drop net_raw \ + -v /etc/fluentbit/fluentbit.conf:/etc/fluentbit/fluentbit.conf \ + -v /var/lib/fluent:/var/lib/fluent:z \ + -v /var/log/journal:/var/log/journal:ro \ + -v /etc/machine-id:/etc/machine-id:ro \ + $image \ + -c /etc/fluentbit/fluentbit.conf + +ExecStop=/usr/bin/podman stop %N +Restart=always +RestartSec=5 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target" + + write_file service_filename service_file true +} + +# configure_timers_mdm_mdsd +# args: +# 1) role - string; can be "gateway" or "rp" +configure_timers_mdm_mdsd() { + local -n role="$1" + log "starting" + + verify_role role + + local keyvault_suffix secret_prefix + get_keyvault_suffix role keyvault_suffix secret_prefix + + for var in "mdsd" "mdm"; do + # shellcheck disable=SC2034 + local download_creds_service_filename="/etc/systemd/system/download-$var-credentials.service" + # shellcheck disable=SC2034 + local download_creds_service_file="[Unit] +Description=Periodic $var credentials refresh + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/download-credentials.sh $var" + + write_file download_creds_service_filename download_creds_service_file true + + # shellcheck disable=SC2034 + local download_creds_timer_filename="/etc/systemd/system/download-$var-credentials.timer" + # shellcheck disable=SC2034 + local download_creds_timer_file="[Unit] +Description=Periodic $var credentials refresh +After=network-online.target +Wants=network-online.target + +[Timer] +OnBootSec=0min +OnCalendar=0/12:00:00 +AccuracySec=5s + +[Install] +WantedBy=timers.target" + + write_file download_creds_timer_filename download_creds_timer_file true + done + + local -r download_creds_script_filename="/usr/local/bin/download-credentials.sh" + # shellcheck disable=SC2034 + local -r download_creds_script_file="#!/bin/bash +set -eu + +COMPONENT=\$1 +echo \"Download \$COMPONENT credentials\" + +TEMP_DIR=\"\$(mktemp -d)\" +export AZURE_CONFIG_DIR=\"\$(mktemp -d)\" + +echo \"Logging into Azure...\" +RETRIES=3 +while [[ \$RETRIES -gt 0 ]]; do + if az login -i --allow-no-subscriptions + then + echo \"az login successful\" + break + else + echo \"az login failed. Retrying...\" + let RETRIES-=1 + sleep 5 + fi +done + +trap \"cleanup\" EXIT + +cleanup() { + az logout + [[ \$TEMP_DIR =~ /tmp/.+ ]] && rm -rf \$TEMP_DIR + [[ \$AZURE_CONFIG_DIR =~ /tmp/.+ ]] && rm -rf \$AZURE_CONFIG_DIR +} + +if [[ \$COMPONENT = \"mdm\" ]]; then + CURRENT_CERT_FILE=\"/etc/mdm.pem\" +elif [[ \$COMPONENT = \"mdsd\" ]]; then + CURRENT_CERT_FILE=\"/var/lib/waagent/Microsoft.Azure.KeyVault.Store/mdsd.pem\" +else + echo Invalid usage && exit 1 +fi + +SECRET_NAME=\"$secret_prefix-\${COMPONENT}\" +NEW_CERT_FILE=\"\$TEMP_DIR/\$COMPONENT.pem\" +for attempt in {1..5}; do + az keyvault \ + secret \ + download \ + --file \"\$NEW_CERT_FILE\" \ + --id \"https://$KEYVAULTPREFIX-$keyvault_suffix.$KEYVAULTDNSSUFFIX/secrets/\$SECRET_NAME\" \ + && break + if [[ \$attempt -lt 5 ]]; then sleep 10; else exit 1; fi +done + +if [ -f \$NEW_CERT_FILE ]; then + if [[ \$COMPONENT = \"mdsd\" ]]; then + chown syslog:syslog \$NEW_CERT_FILE + else + sed -i -ne '1,/END CERTIFICATE/ p' \$NEW_CERT_FILE + fi + + new_cert_sn=\"\$(openssl x509 -in \"\$NEW_CERT_FILE\" -noout -serial | awk -F= '{print \$2}')\" + current_cert_sn=\"\$(openssl x509 -in \"\$CURRENT_CERT_FILE\" -noout -serial | awk -F= '{print \$2}')\" + if [[ ! -z \$new_cert_sn ]] && [[ \$new_cert_sn != \"\$current_cert_sn\" ]]; then + echo updating certificate for \$COMPONENT + chmod 0600 \$NEW_CERT_FILE + mv \$NEW_CERT_FILE \$CURRENT_CERT_FILE + fi +else + echo Failed to refresh certificate for \$COMPONENT && exit 1 +fi" + + write_file download_creds_script_filename download_creds_script_file true + + chmod u+x /usr/local/bin/download-credentials.sh + + $download_creds_script_filename mdsd & + wait "$!" + + + $download_creds_script_filename mdm & + wait "$!" + + # shellcheck disable=SC2034 + local -r watch_mdm_creds_service_filename="/etc/systemd/system/watch-mdm-credentials.service" + # shellcheck disable=SC2034 + local -r watch_mdm_creds_service_file="[Unit] +Description=Watch for changes in mdm.pem and restarts the mdm service + +[Service] +Type=oneshot +ExecStart=/usr/bin/systemctl restart mdm.service + +[Install] +WantedBy=multi-user.target" + + write_file watch_mdm_creds_service_filename watch_mdm_creds_service_file true + + # shellcheck disable=SC2034 + local -r watch_mdm_creds_path_filename='/usr/lib/systemd/system/watch-mdm-credentials.path' + # shellcheck disable=SC2034 + local -r watch_mdm_creds_path_file='[Path] +PathModified=/etc/mdm.pem + +[Install] +WantedBy=multi-user.target' + + write_file watch_mdm_creds_path_filename watch_mdm_creds_path_file true + + local -r watch_mdm_creds='watch-mdm-credentials.path' + systemctl enable --now "$watch_mdm_creds" || abort "failed to enable and start $watch_mdm_creds" +} + +# configure_service_mdm +# args: +# 1) role - nameref, string; can be "gateway" or "rp" +# 2) image - nameref, string; mdm container image to run +# 3) network - nameref, string; podman network name to be attached +configure_service_mdm() { + local -n role="$1" + local -n image="$2" + local -n network="$3" + log "starting" + log "Configuring mdm service" + + verify_role role + + # shellcheck disable=SC2034 + local -r sysconfig_mdm_filename="/etc/sysconfig/mdm" + # shellcheck disable=SC2034 + local -r sysconfig_mdm_file="MDMFRONTENDURL='$MDMFRONTENDURL' +MDMIMAGE='$image' +MDMSOURCEENVIRONMENT='$LOCATION' +MDMSOURCEROLE='$role' +MDMSOURCEROLEINSTANCE=\"$(hostname)\"" + + write_file sysconfig_mdm_filename sysconfig_mdm_file true + + mkdir -p /var/etw + # shellcheck disable=SC2034 + local -r mdm_service_filename="/etc/systemd/system/mdm.service" + # shellcheck disable=SC2034 + local -r mdm_service_file="[Unit] +After=network-online.target +Wants=network-online.target + +[Service] +EnvironmentFile=/etc/sysconfig/mdm +ExecStartPre=-/usr/bin/podman rm -f %N +ExecStart=/usr/bin/podman run \ + --entrypoint /usr/sbin/MetricsExtension \ + --hostname %H \ + --name %N \ + --rm \ + --cap-drop net_raw \ + --network=$network \ + -m 2g \ + -v /etc/mdm.pem:/etc/mdm.pem \ + -v /var/etw:/var/etw:z \ + $image \ + -CertFile /etc/mdm.pem \ + -FrontEndUrl $MDMFRONTENDURL \ + -Logger Console \ + -LogLevel Warning \ + -PrivateKeyFile /etc/mdm.pem \ + -SourceEnvironment $LOCATION \ + -SourceRole $role \ + -SourceRoleInstance $HOSTNAME +ExecStop=/usr/bin/podman stop %N +Restart=always +RestartSec=1 +StartLimitInterval=0 + +[Install] +WantedBy=multi-user.target" + + write_file mdm_service_filename mdm_service_file true +} + +# configure_vmss_aro_service +# args: +# 1) r - nameref, string; role of VMSS +# 2) images - nameref, associative array; ARO container images +# 3) configs - nameref, associative array; configuration files and versions. The values should be a reference to variables, not dereferenced. +# This is because the value is used when creating nameref variables by helper functions. +configure_vmss_aro_services() { + local -n r="$1" + local -n images="$2" + local -n configs="$3" + log "starting" + verify_role "$1" + + if [ "$r" == "$role_gateway" ]; then + configure_service_aro_gateway "${images["rp"]}" "$1" "${configs["gateway_config"]}" "${configs["network"]}" + elif [ "$r" == "$role_rp" ]; then + configure_service_aro_rp "${images["rp"]}" "$1" "${configs["rp_config"]}" "${configs["network"]}" + configure_service_aro_monitor "${images["rp"]}" "${configs["network"]}" + configure_service_aro_portal "${images["rp"]}" "${configs["network"]}" + fi + + configure_service_fluentbit "${configs["fluentbit"]}" "${images["fluentbit"]}" "${configs["network"]}" + configure_timers_mdm_mdsd "$1" + configure_service_mdm "$1" "${images["mdm"]}" "${configs["network"]}" + configure_service_mdsd "$1" "${configs["mdsd"]}" + run_azsecd_config_scan +} + +util_common="util-common.sh" +if [ -f "$util_common" ]; then + # shellcheck source=util-common.sh + source "$util_common" +fi diff --git a/pkg/deploy/generator/scripts/util-system.sh b/pkg/deploy/generator/scripts/util-system.sh new file mode 100644 index 00000000000..551bdefdf00 --- /dev/null +++ b/pkg/deploy/generator/scripts/util-system.sh @@ -0,0 +1,300 @@ +#!/bin/bash +# This file is intended to be sourced by bootstrapping scripts for commonly used functions + +# configure_sshd +# We need to configure PasswordAuthentication to yes in order for the VMSS Access JIT to work +configure_sshd() { + log "starting" + local -r sshd_config="/etc/ssh/sshd_config" + + log "Editing $sshd_config to allow password authentication" + sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/g' "$sshd_config" + + systemctl reload sshd.service || abort "sshd failed to reload" +} + +# configure_logrotate clobbers /etc/logrotate.conf +# args: +# 1) dropin_files - nameref, associative array, optional; logrotate files to write to /etc/logrotate.d +# Key name dictates filenames written to /etc/logrotate.d. +# Example: +# Key dictates the filename written in /etc/logrotate.d +# shellcheck disable=SC2034 +# local -rA logrotate_dropins=( +# ["gateway"]="$gateway_log_file" +# ) +configure_logrotate() { + local -n dropin_files="${1:-empty_str}" + log "starting" + + # shellcheck disable=SC2034 + local -r logrotate_conf_filename='/etc/logrotate.conf' + # shellcheck disable=SC2034 + local -r logrotate_conf_file='# see "man logrotate" for details +# rotate log files weekly +weekly + +# keep 2 weeks worth of backlogs +rotate 2 + +# create new (empty) log files after rotating old ones +create + +# use date as a suffix of the rotated file +dateext + +# uncomment this if you want your log files compressed +compress + +# RPM packages drop log rotation information into this directory +include /etc/logrotate.d + +# no packages own wtmp and btmp -- we will rotate them here +/var/log/wtmp { + monthly + create 0664 root utmp + minsize 1M + rotate 1 +} + +/var/log/btmp { + missingok + monthly + create 0600 root utmp + rotate 1 +}' + + write_file logrotate_conf_filename logrotate_conf_file true + + if [ -n "${dropin_files[*]}" ]; then + local -r logrotate_d="/etc/logrotate.d" + log "Writing logrotate files to $logrotate_d" + for dropin_name in "${!dropin_files[@]}"; do + # shellcheck disable=SC2034 + local -r dropin_filename="$logrotate_d/$dropin_name" + # shellcheck disable=SC2034 + local -r dropin_file="${dropin_files["$dropin_name"]}" + write_file dropin_filename dropin_file true + done + fi +} + +# pull_container_images +# args: +# 1) pull_images - nameref, string array +# 2) registry_conf - nameref, string, optional; path to docker/podman configuration file +pull_container_images() { + local -n pull_images="$1" + local -n registry_conf="${2:-empty_str}" + log "starting" + + # shellcheck disable=SC2034 + local -ri retry_time=30 + # The managed identity that the VM runs as only has a single roleassignment. + # This role assignment is ACRPull which is not necessarily present in the + # subscription we're deploying into. If the identity does not have any + # role assignments scoped on the subscription we're deploying into, it will + # not show on az login -i, which is why the below line is commented. + # az account set -s "$SUBSCRIPTIONID" + cmd=( + az + login + -i + --allow-no-subscriptions + ) + + log "Running az login with retries" + retry cmd retry_time + + # Suppress emulation output for podman instead of docker for az acr compatability + mkdir -p /etc/containers/ + mkdir -p /root/.docker + touch /etc/containers/nodocker + + # This name is used in the case that az acr login searches for this in it's environment + export REGISTRY_AUTH_FILE="/root/.docker/config.json" + + if [ -n "${registry_conf}" ]; then + write_file REGISTRY_AUTH_FILE registry_conf true + fi + + log "logging into prod acr" + cmd=( + az + acr + login + --name + # TODO replace this with variable expansion + # Reference: https://www.shellcheck.net/wiki/SC2001 + "$(sed -e 's|.*/||' <<<"$ACRRESOURCEID")" + ) + + retry cmd retry_time + + # shellcheck disable=SC2068 + for i in ${pull_images[@]}; do + local -n image="$i" + cmd=( + podman + pull + "$image" + ) + + log "Pulling image $image with retries now" + retry cmd retry_time + done + + # shellcheck disable=SC2034 + cmd=( + az + logout + ) + + log "Running az logout with retries" + retry cmd retry_time +} + +# configure_certs +# args: +# 1) role - string; can be "devproxy" or "rp" +configure_certs() { + local -n role="$1" + log "starting" + log "Configuring certificates for $role" + + verify_role role true + + if [ "$role" == "devproxy" ]; then + local -r proxy_certs_basedir="/etc/proxy" + mkdir -p "$proxy_certs_basedir" + base64 -d <<<"$PROXYCERT" > "$proxy_certs_basedir/proxy.crt" + base64 -d <<<"$PROXYKEY" > "$proxy_certs_basedir/proxy.key" + base64 -d <<<"$PROXYCLIENTCERT" > "$proxy_certs_basedir/proxy-client.crt" + chown -R 1000:1000 /etc/proxy + chmod 0600 "$proxy_certs_basedir/proxy.key" + return 0 + fi + + if [ "$role" == "rp" ]; then + local -r rp_certs_basedir="/etc/aro-rp" + mkdir -p "$rp_certs_basedir" + base64 -d <<<"$ADMINAPICABUNDLE" > "$rp_certs_basedir/admin-ca-bundle.pem" + if [[ -n "$ARMAPICABUNDLE" ]]; then + base64 -d <<<"$ARMAPICABUNDLE" > "$rp_certs_basedir/arm-ca-bundle.pem" + fi + chown -R 1000:1000 "$rp_certs_basedir" + fi + + # setting MONITORING_GCS_AUTH_ID_TYPE=AuthKeyVault seems to have caused mdsd not + # to honour SSL_CERT_FILE any more, heaven only knows why. + local -r ssl_certs_basedir="/usr/lib/ssl/certs" + mkdir -p "$ssl_certs_basedir" + csplit -f "$ssl_certs_basedir/cert-" -b %03d.pem /etc/pki/tls/certs/ca-bundle.crt /^$/1 "{*}" 1>/dev/null + c_rehash "$ssl_certs_basedir" + + # we leave clientId blank as long as only 1 managed identity assigned to vmss + # if we have more than 1, we will need to populate with clientId used for off-node scanning + # shellcheck disable=SC2034 + local -r nodescan_agent_filename="/etc/default/vsa-nodescan-agent.config" + # shellcheck disable=SC2034 + local -r nodescan_agent_file="{ + \"Nice\": 19, + \"Timeout\": 10800, + \"ClientId\": \"\", + \"TenantId\": $AZURESECPACKVSATENANTID, + \"QualysStoreBaseUrl\": $AZURESECPACKQUALYSURL, + \"ProcessTimeout\": 300, + \"CommandDelay\": 0 + }" + + write_file nodescan_agent_filename nodescan_agent_file true +} + +# run_azsecd_config_scan +run_azsecd_config_scan() { + log "starting" + + local -ar configs=( + "baseline" + "clamav" + "software" + ) + + log "Scanning configuration files with azsecd ${configs[*]}" + # shellcheck disable=SC2068 + for scan in ${configs[@]}; do + log "Scanning config file $scan now" + /usr/local/bin/azsecd config -s "$scan" -d P1D + done +} + +# create_required_dirs +create_required_dirs() { + create_dirs=( + /var/log/journal + /var/lib/waagent/Microsoft.Azure.KeyVault.Store + # Does not exist on devProxyVMSS + /var/opt/microsoft/linuxmonagent + ) + + # shellcheck disable=SC2068 + for d in ${create_dirs[@]}; do + log "Creating directory $d" + mkdir -p "$d" || abort "failed to create directory $d" + done +} + +# create_podman_networks() +# args: +# 1) nets - nameref, associative array; Networks to be created +# Key is the network name, value is the subnet with cidr notation +create_podman_networks() { + local -n nets="$1" + log "starting" + + # shellcheck disable=SC2068 + for n in ${!nets[@]}; do + log "Creating podman network \"$n\" with subnet \"${nets[$n]}\"" + podman network \ + create \ + --subnet "${nets["$n"]}" \ + "$n" + done +} + +# firewalld_configure_backend +firewalld_configure_backend() { + log "starting" + + log "Changing firewalld backend to iptables" + conf_file="/etc/firewalld/firewalld.conf" + sed -i 's/FirewallBackend=nftables/FirewallBackend=iptables/g' "$conf_file" +} + +# firewalld_configure +# args: +# 1) ports - nameref, string array; ports to be enabled. +# Ports must be postfixed with /tcp or /udp +firewalld_configure() { + local -n ports="$1" + log "starting" + + firewalld_configure_backend + + # shellcheck disable=SC2034 + local -ra service=( + "firewalld" + ) + enable_services service + + log "Enabling ports ${ports[*]} on default firewalld zone" + # shellcheck disable=SC2068 + for port in ${ports[@]}; do + log "Enabling port $port now" + firewall-cmd "--add-port=$port" \ + --permanent + done + + log "Writing runtime config to permanent config" + firewall-cmd --runtime-to-permanent +} diff --git a/pkg/deploy/generator/scripts/util.sh b/pkg/deploy/generator/scripts/util.sh new file mode 100644 index 00000000000..ca1f36304ea --- /dev/null +++ b/pkg/deploy/generator/scripts/util.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# File to be sourced by *VMSS.sh scripts +# This is only present for the ability to manaully run the VMSS setup scripts seperate from the deploy process. +# e. g. scp copying the script to a test VM +# During normal deployment operations, the other util-*.sh files are prefixed to the VMSS scripts + +if [ "${DEBUG:-false}" == true ]; then + set -x +fi + +util_common="util-common.sh" +if [ -f "$util_common" ]; then + # shellcheck source=util-common.sh + source "$util_common" +fi + +util_system="util-system.sh" +if [ -f "$util_system" ]; then + # shellcheck source=util-system.sh + source "$util_system" +fi + +util_services="util-services.sh" +if [ -f "$util_services" ]; then + # shellcheck source=util-services.sh + source "$util_services" +fi + +util_pkgs="util-packages.sh" +if [ -f "$util_pkgs" ]; then + # shellcheck source=util-packages.sh + source "$util_pkgs" +fi