Skip to content

Commit

Permalink
chore(deps): bumping jsii to 5.1.9 and node to 18
Browse files Browse the repository at this point in the history
Updated jsii and fixed issues that came up from that.

jsii requires at least Node.js 16. 16 is EOL soon, so change minimum
required version to 18.
  • Loading branch information
edwards-aws committed Aug 17, 2023
1 parent 638e820 commit 4c9f438
Show file tree
Hide file tree
Showing 30 changed files with 228 additions and 81 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [18.x, 20.x]

steps:
- uses: actions/checkout@v3
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ and let us know if it's not up-to-date (even better, submit a PR with your corr
The RFDK is written in Typescript and converted, using [jsii](https://github.com/aws/jsii), into Python. Thus, the
minimal development environment must include:

- Node.js >= 14.19.3
- Node.js >= 18.0.0
- docker >= 18

We also recommend developing on a Linux system.
Expand All @@ -39,10 +39,10 @@ the [instructions](https://github.com/nvm-sh/nvm#installing-and-updating) to ins
then you can install a version of Node.js and set your shell to make it available when you login:

```bash
# For example, the latest version of Node.js 14.x
# For example, the latest version of Node.js 18.x

# Find out the version number for latest
LATEST_VERSION=$(nvm ls-remote | grep v14 | grep 'Latest' | awk '{print $1}')
LATEST_VERSION=$(nvm ls-remote | grep v18 | grep 'Latest' | awk '{print $1}')

# Install it
nvm install ${LATEST_VERSION}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ It offers high-level object-oriented abstractions to define render farm infrastr
using the power of Python and Typescript.

The RFDK is available in:
- Javascript, Typescript ([Node.js >= 14.19.3](https://nodejs.org/download/release/latest-v14.x/))
- Javascript, Typescript ([Node.js >= 18.0.0](https://nodejs.org/download/release/latest-v18.x/))
- We recommend using an [Active LTS Release](https://nodejs.org/en/about/releases/)
- Python ([Python >= 3.6](https://www.python.org/downloads/))

Expand Down
1 change: 1 addition & 0 deletions integ/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
cdk.output
cdk.out
6 changes: 3 additions & 3 deletions integ/components/deadline/common/scripts/bash/deploy-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function deploy_component_stacks () {
# (https://docs.aws.amazon.com/cdk/latest/guide/context.html#context_methods)
# in our case this is for stack.availabilityZones

npx cdk synth &> "${INTEG_TEMP_DIR}/${COMPONENT_NAME}/synth.log"
npx cdk synth --output "$(pwd)/cdk.out" --app "npx ts-node --cwd $(pwd) bin/${COMPONENT_NAME}.ts" &> "${INTEG_TEMP_DIR}/${COMPONENT_NAME}/synth.log"
SYNTH_EXIT_CODE=$?
echo $SYNTH_EXIT_CODE > "${INTEG_TEMP_DIR}/${COMPONENT_NAME}/synth-exit-code"
if [[ $SYNTH_EXIT_CODE -ne 0 ]]
Expand All @@ -42,7 +42,7 @@ function deploy_component_stacks () {

for stack in $(cdk_stack_deploy_order); do
echo "$(timestamp) [${COMPONENT_NAME}] -> [${stack}] stack deployment started"
npx cdk deploy --app cdk.out --require-approval=never -e "${stack}" &>> "${deploy_log_path}"
npx cdk deploy --concurrency 10 --app $(pwd)/cdk.out --require-approval=never -e "${stack}" &>> "${deploy_log_path}"
STACK_DEPLOY_EXIT_CODE=$?
if [[ $STACK_DEPLOY_EXIT_CODE -ne 0 ]]
then
Expand Down Expand Up @@ -93,7 +93,7 @@ function destroy_component_stacks () {
cp /dev/null "${destroy_log_path}"
for stack in $(cdk_stack_destroy_order); do
echo "$(timestamp) [${COMPONENT_NAME}] -> [${stack}] stack destroy started"
npx cdk destroy --app cdk.out -e -f "${stack}" &>> "${destroy_log_path}"
npx cdk destroy --app $(pwd)/cdk.out -e -f "${stack}" &>> "${destroy_log_path}"
STACK_DESTROY_EXIT_CODE=$?
if [[ $STACK_DESTROY_EXIT_CODE -ne 0 ]]
then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ describe.each(testCases)('Deadline Repository tests (%s)', (_, id) => {
ingestionTime: expect.anything(),
message: expect.stringMatching( /Cloud-init v. / ),
timestamp: expect.anything(),
eventId: expect.anything(),
},
);
});
Expand All @@ -272,6 +273,7 @@ describe.each(testCases)('Deadline Repository tests (%s)', (_, id) => {
ingestionTime: expect.anything(),
message: expect.not.stringMatching( /\w*(?<!declare -A )INSTALLER_DB_ARGS/ ),
timestamp: expect.anything(),
eventId: expect.anything(),
},
);
});
Expand Down Expand Up @@ -303,6 +305,7 @@ describe.each(testCases)('Deadline Repository tests (%s)', (_, id) => {
ingestionTime: expect.anything(),
message: expect.stringMatching( /Executing \/tmp\/repoinstalltemp\/deadlinecommand.exe/ ),
timestamp: expect.anything(),
eventId: expect.anything(),
},
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { BlockList } from 'net';
import { CloudFormation } from '@aws-sdk/client-cloudformation';
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
import {
CidrBlock,
NetworkUtils,
} from 'aws-cdk-lib/aws-ec2/lib/network-util';
import { ssmCommand } from '../../common/functions/awaitSsmCommand';

// Name of testing stack is derived from env variable to ensure uniqueness
Expand Down Expand Up @@ -281,14 +278,17 @@ describe('Deadline Secrets Management tests', () => {
// source IP and connection IP are within the expected subnet CIDR blocks.
expect(identityInfos.some(identityInfo => {
return expectedSubnetCidrPairs.some(expected => {
const connectionIpNum = NetworkUtils.ipToNum(identityInfo.connectionIpAddress);
const connectionSubnetCidr = new CidrBlock(expected.connectionSubnetCidrBlock);
const connectionSubnet = expected.connectionSubnetCidrBlock.split('/');

const sourceIpNum = NetworkUtils.ipToNum(identityInfo.sourceIpAddress);
const sourceIpSubnetCidr = new CidrBlock(expected.sourceSubnetCidrBlock);
const connectionSubnetRange = new BlockList();
connectionSubnetRange.addSubnet(connectionSubnet[0], parseInt(connectionSubnet[1]));

return sourceIpSubnetCidr.minAddress() <= sourceIpNum && sourceIpNum <= sourceIpSubnetCidr.maxAddress() &&
connectionSubnetCidr.minAddress() <= connectionIpNum && connectionIpNum <= connectionSubnetCidr.maxAddress();
const sourceSubnet = expected.sourceSubnetCidrBlock.split('/');

const sourceSubnetRange = new BlockList();
sourceSubnetRange.addSubnet(sourceSubnet[0], parseInt(sourceSubnet[1]));

return sourceSubnetRange.check(identityInfo.sourceIpAddress) && connectionSubnetRange.check(identityInfo.connectionIpAddress);
});
})).toBeTruthy();
});
Expand Down
4 changes: 2 additions & 2 deletions integ/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"build+test": "yarn run build",
"build+test+package": "yarn run build+test",
"watch": "tsc -w",
"test": "jest",
"test": "npx jest",
"cdk": "cdk",
"e2e": "./scripts/bash/rfdk-integ-e2e.sh",
"e2e-automated": "./scripts/bash/run-e2e-automated.sh",
Expand Down Expand Up @@ -85,6 +85,6 @@
"constructs": "^10.0.0"
},
"engines": {
"node": ">= 14.15.0"
"node": ">= 18.0.0"
}
}
2 changes: 1 addition & 1 deletion integ/scripts/bash/deploy-infrastructure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ echo "$(date "+%Y-%m-%dT%H:%M:%S") [infrastructure] deployment started"
set +e

# Hide the deploy log unless something goes wrong (save the scrollback buffer)
npx cdk deploy "*" --require-approval=never &> "${INTEG_TEMP_DIR}/infrastructure/deploy.txt"
npx cdk deploy "*" --concurrency 10 --require-approval=never --output "$(pwd)/cdk.out" --app "npx ts-node --cwd $(pwd) bin/_infrastructure.ts" &> "${INTEG_TEMP_DIR}/infrastructure/deploy.txt"
deploy_exit_code=$?

# If an exit code was returned from the deployment, output the deploy log
Expand Down
2 changes: 1 addition & 1 deletion integ/scripts/bash/teardown-infrastructure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cd "$INFRASTRUCTURE_APP"
mkdir -p "${INTEG_TEMP_DIR}/infrastructure"

# Hide the destroy log unless something goes wrong (save the scrollback buffer)
npx cdk destroy "*" -f &> "${INTEG_TEMP_DIR}/infrastructure/destroy.txt"
npx cdk destroy "*" --app "$(pwd)/cdk.out" -f &> "${INTEG_TEMP_DIR}/infrastructure/destroy.txt"
destroy_exit_code=$?

# If an exit code was returned from the destroy, output the destroy log
Expand Down
2 changes: 1 addition & 1 deletion lambda-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"watch": "tsc -w"
},
"engines": {
"node": ">= 14.15.0"
"node": ">= 18.0.0"
},
"stability": "stable",
"maturity": "stable",
Expand Down
8 changes: 8 additions & 0 deletions packages/aws-rfdk/docs/upgrade/upgrading-1.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Upgrading to RFDK v1.3.x or Newer

## Updating Node.js

Node 14 is End of Life and RFDK >= 1.3.x no longer supports it. Node.js 18.0.0 is the minimum version
that RFDK now supports.

You can follow our [installation guide](CONTRIBUTING.md#installing-nodejs) for Node.js to upgrade to the latest version.
11 changes: 2 additions & 9 deletions packages/aws-rfdk/lib/deadline/lib/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import {
/**
* Build arguments to supply to a Docker image build
*/
export interface BuildArgs {
readonly [name: string]: string;
}
export type BuildArgs = Record<string, string>;

/**
* Docker container image recipe
Expand Down Expand Up @@ -54,12 +52,7 @@ export interface Recipe {
/**
* A collection of Deadline Docker recipes
*/
export interface DeadlineDockerRecipes {
/**
* A mapping of name to recipe
*/
readonly [name: string]: Recipe;
}
export type DeadlineDockerRecipes = Record<string, Recipe>;

/**
* The manifest included with Deadline Docker image recipes
Expand Down
19 changes: 12 additions & 7 deletions packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

/* eslint-disable no-console */

import { types } from 'util';
// eslint-disable-next-line import/no-extraneous-dependencies
import {AutoScaling, EC2} from 'aws-sdk';
import {AutoScaling, EC2, AWSError} from 'aws-sdk';

/**
* Contents of the Message sent from Sns in response to a lifecycle event.
Expand Down Expand Up @@ -45,7 +46,7 @@ async function completeLifecycle(success: boolean, message: SnsLaunchInstanceMes
const response = await autoscaling.completeLifecycleAction(request).promise();
console.log('Got response: ' + JSON.stringify(response));
} catch (e) {
throw new Error(`Error sending completeLifecycleAction: ${e.code} -- ${e.message}`);
throw new Error(`Error sending completeLifecycleAction: ${(e as AWSError)?.code} -- ${(e as Error)?.message}`);
}
}

Expand All @@ -64,7 +65,7 @@ async function attachEniToInstance(instanceId: string, eniId: string): Promise<v
const response = await ec2.attachNetworkInterface(request).promise();
console.log('Got response: ' + JSON.stringify(response));
} catch (e) {
throw new Error(`Error attaching network interface to instance: ${e.code} -- ${e.message}`);
throw new Error(`Error attaching network interface to instance: ${(e as AWSError)?.code} -- ${(e as Error)?.message}`);
}
}

Expand All @@ -85,17 +86,21 @@ export async function handler(event: { [key: string]: any }): Promise<void> {
await attachEniToInstance(message.EC2InstanceId, eniId);
success = true;
} catch (e) {
console.error(e.toString());
console.error(e.stack);
console.error(String(e));
console.error((e as Error)?.stack);
} finally {
// Note: Instance stays in 'Pending: Wait' state unless this lambda signals a lifecycle transition, so we must **always** send one.
// https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CompleteLifecycleAction.html
await completeLifecycle(success, message);
}
}
} catch (e) {
console.error(e.toString());
console.error(e.stack);
if (types.isNativeError(e)) {
console.error(e.toString());
console.error(e.stack);
} else {
console.error(String(e));
}
}
}
}
46 changes: 46 additions & 0 deletions packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,49 @@ test('continues when complete lifecycle errors', async () => {
await expect(handler(event)).resolves.not.toThrow();
expect(console.error).toHaveBeenCalledTimes(4); // 4 = each of the two records printing two error messages
});

test('continues when complete lifecycle errors non-error thrown', async () => {
// GIVEN
const event = {
Records: [
{
Sns: {
Message: JSON.stringify({
LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING',
AutoScalingGroupName: 'ASG-Name-1',
LifecycleHookName: 'Hook-Name-1',
EC2InstanceId: 'i-0000000000',
LifecycleActionToken: 'Action-Token-1',
NotificationMetadata: JSON.stringify({
eniId: 'eni-000000000',
}),
}),
},
},
{
Sns: {
Message: JSON.stringify({
LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING',
AutoScalingGroupName: 'ASG-Name-1',
LifecycleHookName: 'Hook-Name-1',
EC2InstanceId: 'i-0000000000',
LifecycleActionToken: 'Action-Token-1',
NotificationMetadata: JSON.stringify({
eniId: 'eni-000000000',
}),
}),
},
},
],
};

attachSpy = jest.fn( (request) => successRequestMock(request) );
mock('EC2', 'attachNetworkInterface', attachSpy);

jest.spyOn(JSON, 'parse').mockImplementation(jest.fn( () => {throw 47;} ));

// THEN
// eslint-disable-next-line: no-floating-promises
await expect(handler(event)).resolves.not.toThrow();
expect(console.error).toHaveBeenCalledTimes(2); // 2 = each of the two records printing one error message.
});
2 changes: 1 addition & 1 deletion packages/aws-rfdk/lib/lambdas/nodejs/export-logs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ async function confirmTaskCompletion(taskId: string): Promise<void> {
} catch (e) {
// Retry 3 times before giving up
if (errorCount < 3) {
console.error(`${taskId}: Encountered failure #${errorCount} with message: ${e.message}`);
console.error(`${taskId}: Encountered failure #${errorCount} with message: ${(e as Error)?.message}`);
errorCount++;
} else {
throw e;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
/* eslint-disable no-console */


import { types } from 'util';
import { LambdaContext } from '../aws-lambda';
import { calculateSha256Hash } from './hash';
import { CfnResponseStatus, sendCfnResponse } from './reply';
Expand Down Expand Up @@ -51,7 +52,7 @@ export abstract class SimpleCustomResource {
* @param resourceProperties The ResourceProperties given to the handler.
* @returns The Data to send back to CloudFormation as attributes of this CfnCustomResource
*/
public abstract async doCreate(physicalId: string, resourceProperties: object): Promise<object|undefined>;
public abstract doCreate(physicalId: string, resourceProperties: object): Promise<object|undefined>;

/**
* Called to perform the 'Delete' action. There are three locations in the state-diagram
Expand All @@ -64,7 +65,7 @@ export abstract class SimpleCustomResource {
* @param physicalId A stable hash value derived from the value of ResourceProperties
* @param resourceProperties The ResourceProperties given to the handler.
*/
public abstract async doDelete(physicalId: string, resourceProperties: object): Promise<void>;
public abstract doDelete(physicalId: string, resourceProperties: object): Promise<void>;

/**
* Handler/engine for the CustomResource state machine. Users of this class should
Expand Down Expand Up @@ -118,7 +119,11 @@ export abstract class SimpleCustomResource {
// failure to notify results in a stuck stack that takes at least an hour to
// timeout.
status = CfnResponseStatus.FAILED;
failReason = `${e.message}\n${e.stack}`;
if (types.isNativeError(e)) {
failReason = `${e.message}\n${e.stack}`;
} else {
failReason = String(e);
}
} finally {
// Always send a response to CloudFormation, signal success or
// failure based on whether or not we had an exception.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ export class DeadlineClient {
try {
return await this.performRequest(options, data);
} catch(exception) {
const { statusCode, statusMessage } = exception;
const statusCode = (exception as any)?.statusCode;
const statusMessage = (exception as any)?.statusMessage;
if (statusCode !== undefined && statusMessage !== undefined) {
if (statusCode >= 500 && retriesLeft > 0) {
console.log(`Request failed with ${statusCode}: ${statusMessage}. Will retry after ${retryDelayMs} ms.`);
Expand Down
Loading

0 comments on commit 4c9f438

Please sign in to comment.