From 307996531f4a752cf72bac737f4f1b325d975530 Mon Sep 17 00:00:00 2001
From: Jericho Tolentino <jericht@amazon.com>
Date: Mon, 19 Apr 2021 03:11:49 +0000
Subject: [PATCH 1/2] feat(deadline): add ability to import repository settings

---
 .../aws-rfdk/lib/deadline/lib/repository.ts   | 33 +++++++++++++++----
 .../scripts/bash/installDeadlineRepository.sh | 14 +++++++-
 .../lib/deadline/test/repository.test.ts      | 19 +++++++++++
 3 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/packages/aws-rfdk/lib/deadline/lib/repository.ts b/packages/aws-rfdk/lib/deadline/lib/repository.ts
index f6acdd732..347dba3cf 100644
--- a/packages/aws-rfdk/lib/deadline/lib/repository.ts
+++ b/packages/aws-rfdk/lib/deadline/lib/repository.ts
@@ -42,6 +42,9 @@ import {
 import {
   PolicyStatement,
 } from '@aws-cdk/aws-iam';
+import {
+  Asset,
+} from '@aws-cdk/aws-s3-assets';
 import {
   Annotations,
   Construct,
@@ -376,6 +379,12 @@ export interface RepositoryProps {
    * Options to add additional security groups to the Repository.
    */
   readonly securityGroupsOptions?: RepositorySecurityGroupsOptions;
+
+  /**
+   * The Deadline Repository settings file to import.
+   * @see https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/repository-settings-importer-exporter.html
+   */
+  readonly repositorySettings?: Asset;
 }
 
 /**
@@ -657,6 +666,7 @@ export class Repository extends Construct implements IRepository {
       this.installerGroup,
       repositoryInstallationPath,
       props.version,
+      props.repositorySettings,
     );
 
     this.configureSelfTermination();
@@ -887,7 +897,8 @@ export class Repository extends Construct implements IRepository {
   private configureRepositoryInstallerScript(
     installerGroup: AutoScalingGroup,
     installPath: string,
-    version: IVersion) {
+    version: IVersion,
+    settings?: Asset) {
     const installerScriptAsset = ScriptAsset.fromPathConvention(this, 'DeadlineRepositoryInstallerScript', {
       osType: installerGroup.osType,
       baseName: 'installDeadlineRepository',
@@ -902,13 +913,23 @@ export class Repository extends Construct implements IRepository {
 
     version.linuxInstallers.repository.s3Bucket.grantRead(installerGroup, version.linuxInstallers.repository.objectKey);
 
+    const installerArgs = [
+      `"s3://${version.linuxInstallers.repository.s3Bucket.bucketName}/${version.linuxInstallers.repository.objectKey}"`,
+      `"${installPath}"`,
+      version.linuxFullVersionString(),
+    ];
+
+    if (settings) {
+      const repositorySettingsFilePath = installerGroup.userData.addS3DownloadCommand({
+        bucket: settings.bucket,
+        bucketKey: settings.s3ObjectKey,
+      });
+      installerArgs.push(repositorySettingsFilePath);
+    }
+
     installerScriptAsset.executeOn({
       host: installerGroup,
-      args: [
-        `"s3://${version.linuxInstallers.repository.s3Bucket.bucketName}/${version.linuxInstallers.repository.objectKey}"`,
-        `"${installPath}"`,
-        version.linuxFullVersionString(),
-      ],
+      args: installerArgs,
     });
   }
 }
diff --git a/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh b/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh
index fdff63d11..b8317ac5b 100644
--- a/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh
+++ b/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh
@@ -8,6 +8,7 @@
 # $1: s3 path for the deadline repository installer.
 # $2: Path where deadline repository needs to be installed.
 # $3: Deadline Repository Version being installed.
+# $4: (Optional) Deadline Repository settings file to import.
 
 # exit when any command fails
 set -xeuo pipefail
@@ -15,6 +16,7 @@ set -xeuo pipefail
 S3PATH=$1
 PREFIX=$2
 DEADLINE_REPOSITORY_VERSION=$3
+DEADLINE_REPOSITORY_SETTINGS_FILE=${4:-}
 shift;shift;
 
 # check if repository is already installed at the given path
@@ -69,7 +71,17 @@ set +x
 
 INSTALLER_DB_ARGS_STRING=''
 for key in "${!INSTALLER_DB_ARGS[@]}"; do INSTALLER_DB_ARGS_STRING=$INSTALLER_DB_ARGS_STRING"${key} ${INSTALLER_DB_ARGS[$key]} "; done
-$REPO_INSTALLER --mode unattended --setpermissions false --prefix "$PREFIX" --installmongodb false --backuprepo false ${INSTALLER_DB_ARGS_STRING}
+
+REPOSITORY_SETTINGS_ARG_STRING=''
+if [ ! -z "$DEADLINE_REPOSITORY_SETTINGS_FILE" ]; then
+  if [ ! -f "$DEADLINE_REPOSITORY_SETTINGS_FILE" ]; then
+    echo "WARNING: Repository settings file was specified but is not a file: $DEADLINE_REPOSITORY_SETTINGS_FILE. Repository settings will not be imported."
+  else
+    REPOSITORY_SETTINGS_ARG_STRING="--importrepositorysettings true --repositorysettingsimportoperation append --repositorysettingsimportfile \"$DEADLINE_REPOSITORY_SETTINGS_FILE\""
+  fi
+fi
+
+$REPO_INSTALLER --mode unattended --setpermissions false --prefix "$PREFIX" --installmongodb false --backuprepo false ${INSTALLER_DB_ARGS_STRING} $REPOSITORY_SETTINGS_ARG_STRING
 
 set -x
 
diff --git a/packages/aws-rfdk/lib/deadline/test/repository.test.ts b/packages/aws-rfdk/lib/deadline/test/repository.test.ts
index 1300a60da..4114e7218 100644
--- a/packages/aws-rfdk/lib/deadline/test/repository.test.ts
+++ b/packages/aws-rfdk/lib/deadline/test/repository.test.ts
@@ -35,6 +35,7 @@ import {
   FileSystem as EfsFileSystem,
 } from '@aws-cdk/aws-efs';
 import { Bucket } from '@aws-cdk/aws-s3';
+import { Asset } from '@aws-cdk/aws-s3-assets';
 import {
   App,
   CfnElement,
@@ -1205,3 +1206,21 @@ test('throws an error if supplied a MountableEfs with no Access Point', () => {
   // THEN
   expect(when).toThrow('When using EFS with the Repository, you must provide an EFS Access Point');
 });
+
+test('imports repository settings', () => {
+  // GIVEN
+  const repositorySettings = new Asset(stack, 'RepositorySettingsAsset', {
+    path: __filename,
+  });
+
+  // WHEN
+  const repository = new Repository(stack, 'Repository', {
+    vpc,
+    version,
+    repositorySettings,
+  });
+
+  // THEN
+  const installerGroup = repository.node.tryFindChild('Installer') as AutoScalingGroup;
+  expect(installerGroup.userData.render()).toContain(`aws s3 cp '${repositorySettings.s3ObjectUrl}'`);
+});

From 98026e4094cd2b05cbdfeb531feb2ca1077674ba Mon Sep 17 00:00:00 2001
From: Jericho Tolentino <jericht@amazon.com>
Date: Mon, 19 Apr 2021 18:55:39 +0000
Subject: [PATCH 2/2] code cleanup and fail on missing repository settings file

---
 packages/aws-rfdk/lib/deadline/lib/repository.ts             | 5 ++++-
 .../lib/deadline/scripts/bash/installDeadlineRepository.sh   | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/packages/aws-rfdk/lib/deadline/lib/repository.ts b/packages/aws-rfdk/lib/deadline/lib/repository.ts
index 347dba3cf..2ddc7d1c6 100644
--- a/packages/aws-rfdk/lib/deadline/lib/repository.ts
+++ b/packages/aws-rfdk/lib/deadline/lib/repository.ts
@@ -383,6 +383,8 @@ export interface RepositoryProps {
   /**
    * The Deadline Repository settings file to import.
    * @see https://docs.thinkboxsoftware.com/products/deadline/10.1/1_User%20Manual/manual/repository-settings-importer-exporter.html
+   *
+   * @default Repository settings are not imported.
    */
   readonly repositorySettings?: Asset;
 }
@@ -898,7 +900,8 @@ export class Repository extends Construct implements IRepository {
     installerGroup: AutoScalingGroup,
     installPath: string,
     version: IVersion,
-    settings?: Asset) {
+    settings?: Asset,
+  ) {
     const installerScriptAsset = ScriptAsset.fromPathConvention(this, 'DeadlineRepositoryInstallerScript', {
       osType: installerGroup.osType,
       baseName: 'installDeadlineRepository',
diff --git a/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh b/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh
index b8317ac5b..e6d0491fa 100644
--- a/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh
+++ b/packages/aws-rfdk/lib/deadline/scripts/bash/installDeadlineRepository.sh
@@ -75,7 +75,8 @@ for key in "${!INSTALLER_DB_ARGS[@]}"; do INSTALLER_DB_ARGS_STRING=$INSTALLER_DB
 REPOSITORY_SETTINGS_ARG_STRING=''
 if [ ! -z "$DEADLINE_REPOSITORY_SETTINGS_FILE" ]; then
   if [ ! -f "$DEADLINE_REPOSITORY_SETTINGS_FILE" ]; then
-    echo "WARNING: Repository settings file was specified but is not a file: $DEADLINE_REPOSITORY_SETTINGS_FILE. Repository settings will not be imported."
+    echo "ERROR: Repository settings file was specified but is not a file: $DEADLINE_REPOSITORY_SETTINGS_FILE."
+    exit 1
   else
     REPOSITORY_SETTINGS_ARG_STRING="--importrepositorysettings true --repositorysettingsimportoperation append --repositorysettingsimportfile \"$DEADLINE_REPOSITORY_SETTINGS_FILE\""
   fi