Skip to content

Commit

Permalink
feat: Update stage-deadline script with new version index (#139)
Browse files Browse the repository at this point in the history
* feat: add version-provider

* feat: update stage-deadline script with new version index

* fix: move version provider logic in separate script from handler

Co-authored-by: Eugene Kozlov <kozlove@dev-dsk-kozlove-2b-2198d727.us-west-2.amazon.com>
  • Loading branch information
kozlove-aws and Eugene Kozlov committed Oct 8, 2020
1 parent cee7099 commit fcb926e
Show file tree
Hide file tree
Showing 6 changed files with 829 additions and 70 deletions.
49 changes: 49 additions & 0 deletions packages/aws-rfdk/bin/index-test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"Deadline": {
"versions": {
"10": {
"1": {
"8": {
"5": {
"linux": {
"bundle": "s3://thinkbox-installers/Deadline/10.1.8.5/Linux/Deadline-10.1.8.5-linux-installers.tar",
"clientInstaller": "s3://thinkbox-installers/Deadline/10.1.8.5/Linux/DeadlineClient-10.1.8.5-linux-x64-installer.run",
"repositoryInstaller": "s3://thinkbox-installers/Deadline/10.1.8.5/Linux/DeadlineRepository-10.1.8.5-linux-x64-installer.run"
},
"mac": {
"bundle": "s3://thinkbox-installers/Deadline/10.1.8.5/Mac/Deadline-10.1.8.5-osx-installers.dmg"
},
"windows": {
"bundle": "s3://thinkbox-installers/Deadline/10.1.8.5/Windows/Deadline-10.1.8.5-windows-installers.zip",
"clientInstaller": "s3://thinkbox-installers/Deadline/10.1.8.5/Windows/DeadlineClient-10.1.8.5-windows-installer.exe",
"repositoryInstaller": "s3://thinkbox-installers/Deadline/10.1.8.5/Windows/DeadlineRepository-10.1.8.5-windows-installer.exe"
}
}
},
"9": {
"2": {
"linux": {
"bundle": "s3://thinkbox-installers/Deadline/10.1.9.2/Linux/Deadline-10.1.9.2-linux-installers.tar",
"clientInstaller": "s3://thinkbox-installers/Deadline/10.1.9.2/Linux/DeadlineClient-10.1.9.2-linux-x64-installer.run",
"repositoryInstaller": "s3://thinkbox-installers/Deadline/10.1.9.2/Linux/DeadlineRepository-10.1.9.2-linux-x64-installer.run"
},
"mac": {
"bundle": "s3://thinkbox-installers/Deadline/10.1.9.2/Mac/Deadline-10.1.9.2-osx-installers.dmg"
},
"windows": {
"bundle": "s3://thinkbox-installers/Deadline/10.1.9.2/Windows/Deadline-10.1.9.2-windows-installers.zip",
"clientInstaller": "s3://thinkbox-installers/Deadline/10.1.9.2/Windows/DeadlineClient-10.1.9.2-windows-installer.exe",
"repositoryInstaller": "s3://thinkbox-installers/Deadline/10.1.9.2/Windows/DeadlineRepository-10.1.9.2-windows-installer.exe"
}
}
}
}
}
},
"latest": {
"linux": "10.1.9.2",
"mac": "10.1.9.2",
"windows": "10.1.8.5"
}
}
}
218 changes: 148 additions & 70 deletions packages/aws-rfdk/bin/stage-deadline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as fs from 'fs';
import * as path from 'path';
import * as url from 'url';
import { types } from 'util';
import {IUris, Platform, Product, VersionProvider } from '../lib/core/lambdas/nodejs/version-provider';
import { Version } from '../lib/deadline';

const args = process.argv.slice(2);
Expand Down Expand Up @@ -56,88 +57,138 @@ while (n < args.length) {
n++;
}

// Automatically populate the installer & recipe URI using the version, if it is provided.
if (deadlineReleaseVersion !== '') {
try {
const version = Version.parse(deadlineReleaseVersion);
if(version.isLessThan(Version.MINIMUM_SUPPORTED_DEADLINE_VERSION)) {
console.error(`ERROR: Unsupported Deadline Version ${version.toString()}. Minimum supported version is ${Version.MINIMUM_SUPPORTED_DEADLINE_VERSION} \n`);
usage(1);
}
} catch(e) {
console.error(`ERROR: ${(e as Error).message} \n`);
usage(1);
}

// populate installer URI
if (deadlineInstallerURI && deadlineInstallerURI.length > 0) {
console.info('INFO: Since deadline release version is provided, "deadlineInstallerURI" will be ignored.');
}
deadlineInstallerURI = `s3://thinkbox-installers/Deadline/${deadlineReleaseVersion}/Linux/DeadlineClient-${deadlineReleaseVersion}-linux-x64-installer.run`;

// populate docker recipe URI
if (dockerRecipesURI && dockerRecipesURI.length > 0) {
console.info('INFO: Since deadline release version is provided, "dockerRecipesURI" will be ignored.');
}
dockerRecipesURI = `s3://thinkbox-installers/DeadlineDocker/${deadlineReleaseVersion}/DeadlineDocker-${deadlineReleaseVersion}.tar.gz`;
if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder);
} else if (fs.readdirSync(outputFolder).length > 0) {
console.error('The target directory is not empty.');
process.exit(1);
}

// Show help if URI for deadline installer or URI for docker is not specified.
if (deadlineInstallerURI === '' || dockerRecipesURI === '') {
usage(1);
const handler = new VersionProvider();

// populate installer URI
if (deadlineInstallerURI === '') {
handler.getVersionUris({ platform: Platform.linux, product: Product.deadline, versionString: deadlineReleaseVersion})
.then(result => {
const installerVersion = result.get(Platform.linux);
if (installerVersion) {
validateDeadlineVersion(`${installerVersion.MajorVersion}.${installerVersion.MinorVersion}.${installerVersion.ReleaseVersion}.${installerVersion.PatchVersion}`);
const installerUrl = (<IUris>installerVersion.Uris).clientInstaller;
if (installerUrl) {
getDeadlineInstaller(installerUrl);
}
}
else {
console.error(`Deadline installer for version ${deadlineReleaseVersion} was not found.`);
exitAndCleanup(1);
}
})
.catch(error => {
console.error(error.message);
exitAndCleanup(error.code);
});
}
else {
getDeadlineInstaller(deadlineInstallerURI);
}

const deadlineInstallerURL = new url.URL(deadlineInstallerURI);
const dockerRecipeURL = new url.URL(dockerRecipesURI);

if (deadlineInstallerURL.protocol !== 's3:') {
console.error(`ERROR: Invalid URI protocol ("${deadlineInstallerURL.protocol}") for --deadlineInstallerURI. Only "s3:" URIs are supported.`);
usage(1);
// populate docker recipe URI
if (dockerRecipesURI === '') {
handler.getVersionUris({ platform: Platform.linux, product: Product.deadlineDocker, versionString: deadlineReleaseVersion})
.then(result => {
const installerVersion = result.get(Platform.linux);
if (installerVersion) {
getDockerRecipe((<IUris>installerVersion.Uris).bundle);
}
else {
console.error(`Docker recipies for version ${deadlineReleaseVersion} was not found.`);
exitAndCleanup(1);
}
})
.catch(error => {
console.error(error.message);
exitAndCleanup(error.code);
});
}

if (dockerRecipeURL.protocol !== 's3:') {
console.error(`ERROR: Invalid URI protocol ("${dockerRecipeURL.protocol}") for --dockerRecipeURL. Only "s3:" URIs are supported.`);
usage(1);
else {
getDockerRecipe(dockerRecipesURI);
}

if (!validateBucketName(deadlineInstallerURL.hostname) || !validateBucketName(dockerRecipeURL.hostname)) {
usage(1);
}
/**
* Download Deadline installer
*
* @param deadlineInstallerUri - Specifies a URI pointing to the Deadline Linux Client installer. This currently supports S3 URIs.
*/
function getDeadlineInstaller(deadlineInstallerUri: string) {
const deadlineInstallerURL = new url.URL(deadlineInstallerUri);

if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder);
} else if (fs.readdirSync(outputFolder).length > 0) {
console.error('The target directory is not empty.');
process.exit(1);
if (deadlineInstallerURL.protocol !== 's3:') {
console.error(`ERROR: Invalid URI protocol ("${deadlineInstallerURL.protocol}") for --deadlineInstallerURI. Only "s3:" URIs are supported.`);
usage(1);
}

if (!validateBucketName(deadlineInstallerURL.hostname)) {
usage(1);
}

try {
// Get Deadline client installer
const deadlineInstallerPath = getFile({
uri: deadlineInstallerURL,
targetFolder: path.join(outputFolder, 'bin'),
verbose,
});

// Make installer executable
makeExecutable(deadlineInstallerPath);
} catch (e) {
let errorMsg: string;
if (types.isNativeError(e)) {
errorMsg = e.message;
} else {
errorMsg = e.toString();
}
console.error(`ERROR: ${errorMsg}`);
exitAndCleanup(1);
}
}

try {
// Get Docker recipe
getAndExtractArchive({
uri: dockerRecipeURL,
targetFolder: outputFolder,
verbose,
tarOptions: [`-x${verbose ? 'v' : ''}z`],
});
/**
* Download and extract Docker recipe.
*
* @param dockerRecipesUri - Specifies a URI pointing to the Deadline Docker recipes. This currently supports S3 URIs.
*/
function getDockerRecipe(dockerRecipesUri: string) {
const dockerRecipeURL = new url.URL(dockerRecipesUri);

// Get Deadline client installer
const deadlineInstallerPath = getFile({
uri: deadlineInstallerURL,
targetFolder: path.join(outputFolder, 'bin'),
verbose,
});
if (dockerRecipeURL.protocol !== 's3:') {
console.error(`ERROR: Invalid URI protocol ("${dockerRecipeURL.protocol}") for --dockerRecipeURL. Only "s3:" URIs are supported.`);
usage(1);
}

// Make installer executable
makeExecutable(deadlineInstallerPath);
} catch (e) {
let errorMsg: string;
if (types.isNativeError(e)) {
errorMsg = e.message;
} else {
errorMsg = e.toString();
if (!validateBucketName(dockerRecipeURL.hostname)) {
usage(1);
}

try {
// Get Docker recipe
getAndExtractArchive({
uri: dockerRecipeURL,
targetFolder: outputFolder,
verbose,
tarOptions: [`-x${verbose ? 'v' : ''}z`],
});
} catch (e) {
let errorMsg: string;
if (types.isNativeError(e)) {
errorMsg = e.message;
} else {
errorMsg = e.toString();
}
console.error(`ERROR: ${errorMsg}`);
exitAndCleanup(1);
}
console.error(`ERROR: ${errorMsg}`);
process.exit(1);
}

/**
Expand Down Expand Up @@ -221,8 +272,7 @@ Usage: stage-deadline [--output <output_dir>] [--verbose]
Arguments:
<deadline_release_version>
Specifies the official release of Deadline that should be staged. This must be of the form a.b.c.d.
Both '-d' or '-c' arguments will be ignored if provided with this value.
Specifies the official release of Deadline that should be staged. This must be of the form "a.b.c.d", "a.b.c", "a.b" or "a".
Note: The minimum supported deadline version is ${Version.MINIMUM_SUPPORTED_DEADLINE_VERSION}
Expand All @@ -231,11 +281,15 @@ Arguments:
s3://thinkbox-installers/Deadline/10.1.x.y/Linux/DeadlineClient-10.1.x.y-linux-x64-installer.run
If this argument is provided <deadline_release_version> will be ignored for Deadline Linux Client.
-c, --dockerRecipesURI <deadline_recipes_uri>
Specifies a URI pointing to the Deadline Docker recipes. This currently supports S3 URIs of the form:
s3://thinkbox-installers/DeadlineDocker/10.1.x.y/DeadlineDocker-10.1.x.y.tar.gz
If this argument is provided <deadline_release_version> will be ignored for Deadline Docker recipes.
Options:
-o, --output <output_dir>
Specifies a path to an output directory where Deadline will be staged. The default is to use a "stage"
Expand All @@ -244,6 +298,16 @@ Options:
--verbose
Increases the verbosity of the output
`.trimLeft());
exitAndCleanup(errorCode);
}

/**
* Exit with error code and remove output folder.
*
* @param errorCode - THe code of error that will be returned.
*/
function exitAndCleanup(errorCode: number) {
fs.rmdirSync(outputFolder, {recursive: true});
process.exit(errorCode);
}

Expand Down Expand Up @@ -350,3 +414,17 @@ function getAndExtractArchive(props: GetExtractArchiveProps) {
throw new Error(`File ${tarPath} has not been extracted successfully.`);
}
}

function validateDeadlineVersion(versionString: string) {
// Automatically populate the installer & recipe URI using the version, if it is provided.
try {
const version = Version.parse(versionString);
if(version.isLessThan(Version.MINIMUM_SUPPORTED_DEADLINE_VERSION)) {
console.error(`ERROR: Unsupported Deadline Version ${version.toString()}. Minimum supported version is ${Version.MINIMUM_SUPPORTED_DEADLINE_VERSION} \n`);
usage(1);
}
} catch(e) {
console.error(`ERROR: ${(e as Error).message} \n`);
usage(1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

/* eslint-disable no-console */

import { LambdaContext } from '../lib/aws-lambda';
import { CfnRequestEvent, SimpleCustomResource } from '../lib/custom-resource';
import {
VersionProvider,
IVersionProviderProperties,
IVersionedUris,
Platform,
} from './version-provider';


export class VersionProviderResource extends SimpleCustomResource {
readonly versionProvider: VersionProvider;

constructor(indexFilePath?: string) {
super();
this.versionProvider = new VersionProvider(indexFilePath);
}

/**
* @inheritdoc
*/
/* istanbul ignore next */ // @ts-ignore
public validateInput(data: object): boolean {
return this.versionProvider.implementsIVersionProviderProperties(data);
}

/**
* @inheritdoc
*/
// @ts-ignore -- we do not use the physicalId
public async doCreate(physicalId: string, resourceProperties: IVersionProviderProperties): Promise<Map<Platform, IVersionedUris>> {
return await this.versionProvider.getVersionUris(resourceProperties);
}

/**
* @inheritdoc
*/
/* istanbul ignore next */ // @ts-ignore
public async doDelete(physicalId: string, resourceProperties: IVersionProviderProperties): Promise<void> {
// Nothing to do -- we don't modify anything.
return;
}
}

/**
* The handler used to provide the installer links for the requested version
*/
/* istanbul ignore next */
export async function handler(event: CfnRequestEvent, context: LambdaContext): Promise<string> {
const versionProvider = new VersionProviderResource();
return await versionProvider.handler(event, context);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

export * from './handler';
export * from './version-provider';
Loading

0 comments on commit fcb926e

Please sign in to comment.