Use cache key to segment lock folders
parent
60a142b8de
commit
efc2e075b0
|
|
@ -648,68 +648,69 @@ const fs = __importStar(__nccwpck_require__(57147));
|
||||||
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
|
const cloud_runner_logger_1 = __importDefault(__nccwpck_require__(22855));
|
||||||
const cloud_runner_options_1 = __importDefault(__nccwpck_require__(96552));
|
const cloud_runner_options_1 = __importDefault(__nccwpck_require__(96552));
|
||||||
class SharedWorkspaceLocking {
|
class SharedWorkspaceLocking {
|
||||||
static GetAllWorkspaces() {
|
static GetAllWorkspaces(buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
return (yield SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}`)).map((x) => x.replace(`/`, ``));
|
return (yield SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/`)).map((x) => x.replace(`/`, ``));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static GetAllLocks(workspace) {
|
static GetAllLocks(workspace, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
throw new Error("Workspace doesn't exist, can't call get all locks");
|
throw new Error("Workspace doesn't exist, can't call get all locks");
|
||||||
}
|
}
|
||||||
return (yield SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${workspace}/`)).map((x) => x.replace(`/`, ``));
|
return (yield SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/`)).map((x) => x.replace(`/`, ``));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static GetOrCreateLockedWorkspace(workspaceIfCreated, runId) {
|
static GetOrCreateLockedWorkspace(workspaceIfCreated, runId, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!cloud_runner_options_1.default.retainWorkspaces) {
|
if (!cloud_runner_options_1.default.retainWorkspaces) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cloud_runner_logger_1.default.log(`run agent ${runId} is trying to access a workspace`);
|
cloud_runner_logger_1.default.log(`run agent ${runId} is trying to access a workspace`);
|
||||||
const workspaces = yield SharedWorkspaceLocking.GetFreeWorkspaces();
|
const workspaces = yield SharedWorkspaceLocking.GetFreeWorkspaces(buildParametersContext);
|
||||||
for (const element of workspaces) {
|
for (const element of workspaces) {
|
||||||
if (yield SharedWorkspaceLocking.LockWorkspace(element, runId)) {
|
if (yield SharedWorkspaceLocking.LockWorkspace(element, runId, buildParametersContext)) {
|
||||||
cloud_runner_logger_1.default.log(`run agent ${runId} locked workspace: ${element}`);
|
cloud_runner_logger_1.default.log(`run agent ${runId} locked workspace: ${element}`);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const workspace = yield SharedWorkspaceLocking.CreateWorkspace(workspaceIfCreated, runId);
|
const workspace = yield SharedWorkspaceLocking.CreateWorkspace(workspaceIfCreated, buildParametersContext, runId);
|
||||||
cloud_runner_logger_1.default.log(`run agent ${runId} didn't find a free workspace so created: ${workspace}`);
|
cloud_runner_logger_1.default.log(`run agent ${runId} didn't find a free workspace so created: ${workspace}`);
|
||||||
return workspace;
|
return workspace;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static DoesWorkspaceExist(workspace) {
|
static DoesWorkspaceExist(workspace, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
return (yield SharedWorkspaceLocking.GetAllWorkspaces()).includes(workspace);
|
return (yield SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext)).includes(workspace);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static HasWorkspaceLock(workspace, runId) {
|
static HasWorkspaceLock(workspace, runId, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (yield SharedWorkspaceLocking.GetAllLocks(workspace)).filter((x) => x.includes(runId)).length > 0;
|
return ((yield SharedWorkspaceLocking.GetAllLocks(workspace, buildParametersContext)).filter((x) => x.includes(runId))
|
||||||
|
.length > 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static GetFreeWorkspaces() {
|
static GetFreeWorkspaces(buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const result = [];
|
const result = [];
|
||||||
const workspaces = yield SharedWorkspaceLocking.GetAllWorkspaces();
|
const workspaces = yield SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext);
|
||||||
for (const element of workspaces) {
|
for (const element of workspaces) {
|
||||||
if (!(yield SharedWorkspaceLocking.IsWorkspaceLocked(element))) {
|
if (!(yield SharedWorkspaceLocking.IsWorkspaceLocked(element, buildParametersContext))) {
|
||||||
result.push(element);
|
result.push(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static IsWorkspaceLocked(workspace) {
|
static IsWorkspaceLocked(workspace, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const files = yield SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${workspace}/`);
|
const files = yield SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/`);
|
||||||
const workspaceFileDoesNotExists = files.filter((x) => {
|
const workspaceFileDoesNotExists = files.filter((x) => {
|
||||||
return x.includes(`_workspace`);
|
return x.includes(`_workspace`);
|
||||||
}).length === 0;
|
}).length === 0;
|
||||||
|
|
@ -719,43 +720,43 @@ class SharedWorkspaceLocking {
|
||||||
return workspaceFileDoesNotExists || lockFilesExist;
|
return workspaceFileDoesNotExists || lockFilesExist;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static CreateWorkspace(workspace, lockId = ``) {
|
static CreateWorkspace(workspace, buildParametersContext, lockId = ``) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (lockId !== ``) {
|
if (lockId !== ``) {
|
||||||
yield SharedWorkspaceLocking.LockWorkspace(workspace, lockId);
|
yield SharedWorkspaceLocking.LockWorkspace(workspace, lockId, buildParametersContext);
|
||||||
}
|
}
|
||||||
const file = `${Date.now()}_workspace`;
|
const file = `${Date.now()}_workspace`;
|
||||||
fs.writeFileSync(file, '');
|
fs.writeFileSync(file, '');
|
||||||
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`, false, true);
|
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`, false, true);
|
||||||
fs.rmSync(file);
|
fs.rmSync(file);
|
||||||
return workspace;
|
return workspace;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static LockWorkspace(workspace, runId) {
|
static LockWorkspace(workspace, runId, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const file = `${Date.now()}_${runId}_lock`;
|
const file = `${Date.now()}_${runId}_lock`;
|
||||||
fs.writeFileSync(file, '');
|
fs.writeFileSync(file, '');
|
||||||
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`, false, true);
|
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`, false, true);
|
||||||
fs.rmSync(file);
|
fs.rmSync(file);
|
||||||
return SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId);
|
return SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId, buildParametersContext);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static ReleaseWorkspace(workspace, runId) {
|
static ReleaseWorkspace(workspace, runId, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
if (!(yield SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const file = (yield SharedWorkspaceLocking.GetAllLocks(workspace)).filter((x) => x.includes(`_${runId}_lock`));
|
const file = (yield SharedWorkspaceLocking.GetAllLocks(workspace, buildParametersContext)).filter((x) => x.includes(`_${runId}_lock`));
|
||||||
cloud_runner_logger_1.default.log(`${JSON.stringify(yield SharedWorkspaceLocking.GetAllLocks(workspace))}`);
|
cloud_runner_logger_1.default.log(`${JSON.stringify(yield SharedWorkspaceLocking.GetAllLocks(workspace, buildParametersContext))}`);
|
||||||
cloud_runner_logger_1.default.log(`Deleting file ${file}`);
|
cloud_runner_logger_1.default.log(`Deleting file ${file}`);
|
||||||
cloud_runner_logger_1.default.log(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`);
|
cloud_runner_logger_1.default.log(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`);
|
||||||
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`, false, true);
|
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`, false, true);
|
||||||
return !SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId);
|
return !SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId, buildParametersContext);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static CleanupWorkspace(workspace) {
|
static CleanupWorkspace(workspace, buildParametersContext) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${workspace} --recursive`, false, true);
|
yield cloud_runner_system_1.CloudRunnerSystem.Run(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace} --recursive`, false, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static ReadLines(command) {
|
static ReadLines(command) {
|
||||||
|
|
@ -5067,7 +5068,7 @@ class BuildAutomationWorkflow {
|
||||||
try {
|
try {
|
||||||
cloud_runner_logger_1.default.log(`Cloud Runner is running standard build automation`);
|
cloud_runner_logger_1.default.log(`Cloud Runner is running standard build automation`);
|
||||||
if (cloud_runner_options_1.default.retainWorkspaces) {
|
if (cloud_runner_options_1.default.retainWorkspaces) {
|
||||||
const workspace = (yield shared_workspace_locking_1.default.GetOrCreateLockedWorkspace(`test-workspace-${cloud_runner_1.default.buildParameters.buildGuid}`, cloud_runner_1.default.buildParameters.buildGuid)) || cloud_runner_1.default.buildParameters.buildGuid;
|
const workspace = (yield shared_workspace_locking_1.default.GetOrCreateLockedWorkspace(`test-workspace-${cloud_runner_1.default.buildParameters.buildGuid}`, cloud_runner_1.default.buildParameters.buildGuid, cloud_runner_1.default.buildParameters)) || cloud_runner_1.default.buildParameters.buildGuid;
|
||||||
process.env.LOCKED_WORKSPACE = workspace;
|
process.env.LOCKED_WORKSPACE = workspace;
|
||||||
cloud_runner_logger_1.default.logLine(`Using workspace ${workspace}`);
|
cloud_runner_logger_1.default.logLine(`Using workspace ${workspace}`);
|
||||||
cloudRunnerStepState.environment = [
|
cloudRunnerStepState.environment = [
|
||||||
|
|
@ -5102,7 +5103,7 @@ class BuildAutomationWorkflow {
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
cloud_runner_logger_1.default.logWithTime('Configurable post build step(s) time');
|
cloud_runner_logger_1.default.logWithTime('Configurable post build step(s) time');
|
||||||
if (cloud_runner_options_1.default.retainWorkspaces) {
|
if (cloud_runner_options_1.default.retainWorkspaces) {
|
||||||
yield shared_workspace_locking_1.default.ReleaseWorkspace(`test-workspace-${cloud_runner_1.default.buildParameters.buildGuid}`, cloud_runner_1.default.buildParameters.buildGuid);
|
yield shared_workspace_locking_1.default.ReleaseWorkspace(`test-workspace-${cloud_runner_1.default.buildParameters.buildGuid}`, cloud_runner_1.default.buildParameters.buildGuid, cloud_runner_1.default.buildParameters);
|
||||||
}
|
}
|
||||||
cloud_runner_logger_1.default.log(`Cloud Runner finished running standard build automation`);
|
cloud_runner_logger_1.default.log(`Cloud Runner finished running standard build automation`);
|
||||||
return output;
|
return output;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2,60 +2,76 @@ import { CloudRunnerSystem } from '../cloud-runner/services/cloud-runner-system'
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger';
|
import CloudRunnerLogger from '../cloud-runner/services/cloud-runner-logger';
|
||||||
import CloudRunnerOptions from '../cloud-runner/cloud-runner-options';
|
import CloudRunnerOptions from '../cloud-runner/cloud-runner-options';
|
||||||
|
import BuildParameters from '../build-parameters';
|
||||||
export class SharedWorkspaceLocking {
|
export class SharedWorkspaceLocking {
|
||||||
private static readonly workspaceRoot = `s3://game-ci-test-storage/locks/`;
|
private static readonly workspaceRoot = `s3://game-ci-test-storage/locks/`;
|
||||||
public static async GetAllWorkspaces(): Promise<string[]> {
|
public static async GetAllWorkspaces(buildParametersContext: BuildParameters): Promise<string[]> {
|
||||||
return (await SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}`)).map((x) =>
|
return (
|
||||||
x.replace(`/`, ``),
|
await SharedWorkspaceLocking.ReadLines(
|
||||||
);
|
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/`,
|
||||||
|
)
|
||||||
|
).map((x) => x.replace(`/`, ``));
|
||||||
}
|
}
|
||||||
public static async GetAllLocks(workspace: string): Promise<string[]> {
|
public static async GetAllLocks(workspace: string, buildParametersContext: BuildParameters): Promise<string[]> {
|
||||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
throw new Error("Workspace doesn't exist, can't call get all locks");
|
throw new Error("Workspace doesn't exist, can't call get all locks");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
await SharedWorkspaceLocking.ReadLines(`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${workspace}/`)
|
await SharedWorkspaceLocking.ReadLines(
|
||||||
|
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/`,
|
||||||
|
)
|
||||||
).map((x) => x.replace(`/`, ``));
|
).map((x) => x.replace(`/`, ``));
|
||||||
}
|
}
|
||||||
public static async GetOrCreateLockedWorkspace(workspaceIfCreated: string, runId: string) {
|
public static async GetOrCreateLockedWorkspace(
|
||||||
|
workspaceIfCreated: string,
|
||||||
|
runId: string,
|
||||||
|
buildParametersContext: BuildParameters,
|
||||||
|
) {
|
||||||
if (!CloudRunnerOptions.retainWorkspaces) {
|
if (!CloudRunnerOptions.retainWorkspaces) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloudRunnerLogger.log(`run agent ${runId} is trying to access a workspace`);
|
CloudRunnerLogger.log(`run agent ${runId} is trying to access a workspace`);
|
||||||
|
|
||||||
const workspaces = await SharedWorkspaceLocking.GetFreeWorkspaces();
|
const workspaces = await SharedWorkspaceLocking.GetFreeWorkspaces(buildParametersContext);
|
||||||
for (const element of workspaces) {
|
for (const element of workspaces) {
|
||||||
if (await SharedWorkspaceLocking.LockWorkspace(element, runId)) {
|
if (await SharedWorkspaceLocking.LockWorkspace(element, runId, buildParametersContext)) {
|
||||||
CloudRunnerLogger.log(`run agent ${runId} locked workspace: ${element}`);
|
CloudRunnerLogger.log(`run agent ${runId} locked workspace: ${element}`);
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const workspace = await SharedWorkspaceLocking.CreateWorkspace(workspaceIfCreated, runId);
|
const workspace = await SharedWorkspaceLocking.CreateWorkspace(workspaceIfCreated, buildParametersContext, runId);
|
||||||
CloudRunnerLogger.log(`run agent ${runId} didn't find a free workspace so created: ${workspace}`);
|
CloudRunnerLogger.log(`run agent ${runId} didn't find a free workspace so created: ${workspace}`);
|
||||||
|
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async DoesWorkspaceExist(workspace: string) {
|
public static async DoesWorkspaceExist(workspace: string, buildParametersContext: BuildParameters) {
|
||||||
return (await SharedWorkspaceLocking.GetAllWorkspaces()).includes(workspace);
|
return (await SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext)).includes(workspace);
|
||||||
}
|
}
|
||||||
public static async HasWorkspaceLock(workspace: string, runId: string): Promise<boolean> {
|
public static async HasWorkspaceLock(
|
||||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
workspace: string,
|
||||||
|
runId: string,
|
||||||
|
buildParametersContext: BuildParameters,
|
||||||
|
): Promise<boolean> {
|
||||||
|
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (await SharedWorkspaceLocking.GetAllLocks(workspace)).filter((x) => x.includes(runId)).length > 0;
|
return (
|
||||||
|
(await SharedWorkspaceLocking.GetAllLocks(workspace, buildParametersContext)).filter((x) => x.includes(runId))
|
||||||
|
.length > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async GetFreeWorkspaces(): Promise<string[]> {
|
public static async GetFreeWorkspaces(buildParametersContext: BuildParameters): Promise<string[]> {
|
||||||
const result: string[] = [];
|
const result: string[] = [];
|
||||||
const workspaces = await SharedWorkspaceLocking.GetAllWorkspaces();
|
const workspaces = await SharedWorkspaceLocking.GetAllWorkspaces(buildParametersContext);
|
||||||
for (const element of workspaces) {
|
for (const element of workspaces) {
|
||||||
if (!(await SharedWorkspaceLocking.IsWorkspaceLocked(element))) {
|
if (!(await SharedWorkspaceLocking.IsWorkspaceLocked(element, buildParametersContext))) {
|
||||||
result.push(element);
|
result.push(element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,12 +79,12 @@ export class SharedWorkspaceLocking {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async IsWorkspaceLocked(workspace: string): Promise<boolean> {
|
public static async IsWorkspaceLocked(workspace: string, buildParametersContext: BuildParameters): Promise<boolean> {
|
||||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const files = await SharedWorkspaceLocking.ReadLines(
|
const files = await SharedWorkspaceLocking.ReadLines(
|
||||||
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${workspace}/`,
|
`aws s3 ls ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const workspaceFileDoesNotExists =
|
const workspaceFileDoesNotExists =
|
||||||
|
|
@ -84,15 +100,15 @@ export class SharedWorkspaceLocking {
|
||||||
return workspaceFileDoesNotExists || lockFilesExist;
|
return workspaceFileDoesNotExists || lockFilesExist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async CreateWorkspace(workspace: string, lockId: string = ``) {
|
public static async CreateWorkspace(workspace: string, buildParametersContext: BuildParameters, lockId: string = ``) {
|
||||||
if (lockId !== ``) {
|
if (lockId !== ``) {
|
||||||
await SharedWorkspaceLocking.LockWorkspace(workspace, lockId);
|
await SharedWorkspaceLocking.LockWorkspace(workspace, lockId, buildParametersContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
const file = `${Date.now()}_workspace`;
|
const file = `${Date.now()}_workspace`;
|
||||||
fs.writeFileSync(file, '');
|
fs.writeFileSync(file, '');
|
||||||
await CloudRunnerSystem.Run(
|
await CloudRunnerSystem.Run(
|
||||||
`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`,
|
`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
@ -101,35 +117,53 @@ export class SharedWorkspaceLocking {
|
||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async LockWorkspace(workspace: string, runId: string): Promise<boolean> {
|
public static async LockWorkspace(
|
||||||
|
workspace: string,
|
||||||
|
runId: string,
|
||||||
|
buildParametersContext: BuildParameters,
|
||||||
|
): Promise<boolean> {
|
||||||
const file = `${Date.now()}_${runId}_lock`;
|
const file = `${Date.now()}_${runId}_lock`;
|
||||||
fs.writeFileSync(file, '');
|
fs.writeFileSync(file, '');
|
||||||
await CloudRunnerSystem.Run(
|
await CloudRunnerSystem.Run(
|
||||||
`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`,
|
`aws s3 cp ./${file} ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
fs.rmSync(file);
|
fs.rmSync(file);
|
||||||
|
|
||||||
return SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId);
|
return SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId, buildParametersContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async ReleaseWorkspace(workspace: string, runId: string): Promise<boolean> {
|
public static async ReleaseWorkspace(
|
||||||
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace))) {
|
workspace: string,
|
||||||
|
runId: string,
|
||||||
|
buildParametersContext: BuildParameters,
|
||||||
|
): Promise<boolean> {
|
||||||
|
if (!(await SharedWorkspaceLocking.DoesWorkspaceExist(workspace, buildParametersContext))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const file = (await SharedWorkspaceLocking.GetAllLocks(workspace)).filter((x) => x.includes(`_${runId}_lock`));
|
const file = (await SharedWorkspaceLocking.GetAllLocks(workspace, buildParametersContext)).filter((x) =>
|
||||||
CloudRunnerLogger.log(`${JSON.stringify(await SharedWorkspaceLocking.GetAllLocks(workspace))}`);
|
x.includes(`_${runId}_lock`),
|
||||||
|
);
|
||||||
|
CloudRunnerLogger.log(
|
||||||
|
`${JSON.stringify(await SharedWorkspaceLocking.GetAllLocks(workspace, buildParametersContext))}`,
|
||||||
|
);
|
||||||
CloudRunnerLogger.log(`Deleting file ${file}`);
|
CloudRunnerLogger.log(`Deleting file ${file}`);
|
||||||
CloudRunnerLogger.log(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`);
|
CloudRunnerLogger.log(
|
||||||
await CloudRunnerSystem.Run(`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${workspace}/${file}`, false, true);
|
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`,
|
||||||
|
);
|
||||||
|
await CloudRunnerSystem.Run(
|
||||||
|
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace}/${file}`,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
return !SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId);
|
return !SharedWorkspaceLocking.HasWorkspaceLock(workspace, runId, buildParametersContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async CleanupWorkspace(workspace: string) {
|
public static async CleanupWorkspace(workspace: string, buildParametersContext: BuildParameters) {
|
||||||
await CloudRunnerSystem.Run(
|
await CloudRunnerSystem.Run(
|
||||||
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${workspace} --recursive`,
|
`aws s3 rm ${SharedWorkspaceLocking.workspaceRoot}${buildParametersContext.cacheKey}/${workspace} --recursive`,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,48 +11,66 @@ describe('Cloud Runner Locking', () => {
|
||||||
if (CloudRunnerOptions.cloudRunnerTests) {
|
if (CloudRunnerOptions.cloudRunnerTests) {
|
||||||
it(`Simple Locking Flow`, async () => {
|
it(`Simple Locking Flow`, async () => {
|
||||||
Cli.options.retainWorkspaces = true;
|
Cli.options.retainWorkspaces = true;
|
||||||
|
const buildParameters: any = {
|
||||||
|
cacheKey: `test-workspace-${uuidv4()}`,
|
||||||
|
};
|
||||||
|
|
||||||
const newWorkspaceName = `test-workspace-${uuidv4()}`;
|
const newWorkspaceName = `test-workspace-${uuidv4()}`;
|
||||||
const runId = uuidv4();
|
const runId = uuidv4();
|
||||||
await SharedWorkspaceLocking.CreateWorkspace(newWorkspaceName);
|
await SharedWorkspaceLocking.CreateWorkspace(newWorkspaceName, buildParameters);
|
||||||
const isExpectedUnlockedBeforeLocking =
|
const isExpectedUnlockedBeforeLocking =
|
||||||
(await SharedWorkspaceLocking.IsWorkspaceLocked(newWorkspaceName)) === false;
|
(await SharedWorkspaceLocking.IsWorkspaceLocked(newWorkspaceName, buildParameters)) === false;
|
||||||
expect(isExpectedUnlockedBeforeLocking).toBeTruthy();
|
expect(isExpectedUnlockedBeforeLocking).toBeTruthy();
|
||||||
await SharedWorkspaceLocking.LockWorkspace(newWorkspaceName, runId);
|
await SharedWorkspaceLocking.LockWorkspace(newWorkspaceName, runId, buildParameters);
|
||||||
const isExpectedLockedAfterLocking = (await SharedWorkspaceLocking.IsWorkspaceLocked(newWorkspaceName)) === true;
|
const isExpectedLockedAfterLocking =
|
||||||
|
(await SharedWorkspaceLocking.IsWorkspaceLocked(newWorkspaceName, buildParameters)) === true;
|
||||||
expect(isExpectedLockedAfterLocking).toBeTruthy();
|
expect(isExpectedLockedAfterLocking).toBeTruthy();
|
||||||
const locksBeforeRelease = await SharedWorkspaceLocking.GetAllLocks(newWorkspaceName);
|
const locksBeforeRelease = await SharedWorkspaceLocking.GetAllLocks(newWorkspaceName, buildParameters);
|
||||||
CloudRunnerLogger.log(JSON.stringify(locksBeforeRelease, undefined, 4));
|
CloudRunnerLogger.log(JSON.stringify(locksBeforeRelease, undefined, 4));
|
||||||
expect(locksBeforeRelease.length > 1).toBeTruthy();
|
expect(locksBeforeRelease.length > 1).toBeTruthy();
|
||||||
await SharedWorkspaceLocking.ReleaseWorkspace(newWorkspaceName, runId);
|
await SharedWorkspaceLocking.ReleaseWorkspace(newWorkspaceName, runId, buildParameters);
|
||||||
const locks = await SharedWorkspaceLocking.GetAllLocks(newWorkspaceName);
|
const locks = await SharedWorkspaceLocking.GetAllLocks(newWorkspaceName, buildParameters);
|
||||||
expect(locks.length === 1).toBeTruthy();
|
expect(locks.length === 1).toBeTruthy();
|
||||||
const isExpectedLockedAfterReleasing =
|
const isExpectedLockedAfterReleasing =
|
||||||
(await SharedWorkspaceLocking.IsWorkspaceLocked(newWorkspaceName)) === false;
|
(await SharedWorkspaceLocking.IsWorkspaceLocked(newWorkspaceName, buildParameters)) === false;
|
||||||
expect(isExpectedLockedAfterReleasing).toBeTruthy();
|
expect(isExpectedLockedAfterReleasing).toBeTruthy();
|
||||||
}, 150000);
|
}, 150000);
|
||||||
it('All Locking Actions', async () => {
|
it('All Locking Actions', async () => {
|
||||||
Cli.options.retainWorkspaces = true;
|
Cli.options.retainWorkspaces = true;
|
||||||
CloudRunnerLogger.log(`GetAllWorkspaces ${JSON.stringify(await SharedWorkspaceLocking.GetAllWorkspaces())}`);
|
const buildParameters: any = {
|
||||||
CloudRunnerLogger.log(`GetFreeWorkspaces ${JSON.stringify(await SharedWorkspaceLocking.GetFreeWorkspaces())}`);
|
cacheKey: `test-workspace-${uuidv4()}`,
|
||||||
|
};
|
||||||
|
CloudRunnerLogger.log(
|
||||||
|
`GetAllWorkspaces ${JSON.stringify(await SharedWorkspaceLocking.GetAllWorkspaces(buildParameters))}`,
|
||||||
|
);
|
||||||
|
CloudRunnerLogger.log(
|
||||||
|
`GetFreeWorkspaces ${JSON.stringify(await SharedWorkspaceLocking.GetFreeWorkspaces(buildParameters))}`,
|
||||||
|
);
|
||||||
CloudRunnerLogger.log(
|
CloudRunnerLogger.log(
|
||||||
`IsWorkspaceLocked ${JSON.stringify(
|
`IsWorkspaceLocked ${JSON.stringify(
|
||||||
await SharedWorkspaceLocking.IsWorkspaceLocked(`test-workspace-${uuidv4()}`),
|
await SharedWorkspaceLocking.IsWorkspaceLocked(`test-workspace-${uuidv4()}`, buildParameters),
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
CloudRunnerLogger.log(`GetFreeWorkspaces ${JSON.stringify(await SharedWorkspaceLocking.GetFreeWorkspaces())}`);
|
CloudRunnerLogger.log(
|
||||||
|
`GetFreeWorkspaces ${JSON.stringify(await SharedWorkspaceLocking.GetFreeWorkspaces(buildParameters))}`,
|
||||||
|
);
|
||||||
CloudRunnerLogger.log(
|
CloudRunnerLogger.log(
|
||||||
`LockWorkspace ${JSON.stringify(
|
`LockWorkspace ${JSON.stringify(
|
||||||
await SharedWorkspaceLocking.LockWorkspace(`test-workspace-${uuidv4()}`, uuidv4()),
|
await SharedWorkspaceLocking.LockWorkspace(`test-workspace-${uuidv4()}`, uuidv4(), buildParameters),
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
CloudRunnerLogger.log(
|
CloudRunnerLogger.log(
|
||||||
`CreateLockableWorkspace ${JSON.stringify(
|
`CreateLockableWorkspace ${JSON.stringify(
|
||||||
await SharedWorkspaceLocking.CreateWorkspace(`test-workspace-${uuidv4()}`),
|
await SharedWorkspaceLocking.CreateWorkspace(`test-workspace-${uuidv4()}`, buildParameters),
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
CloudRunnerLogger.log(
|
CloudRunnerLogger.log(
|
||||||
`GetLockedWorkspace ${JSON.stringify(
|
`GetLockedWorkspace ${JSON.stringify(
|
||||||
await SharedWorkspaceLocking.GetOrCreateLockedWorkspace(`test-workspace-${uuidv4()}`, uuidv4()),
|
await SharedWorkspaceLocking.GetOrCreateLockedWorkspace(
|
||||||
|
`test-workspace-${uuidv4()}`,
|
||||||
|
uuidv4(),
|
||||||
|
buildParameters,
|
||||||
|
),
|
||||||
)}`,
|
)}`,
|
||||||
);
|
);
|
||||||
}, 3000000);
|
}, 3000000);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
|
||||||
(await SharedWorkspaceLocking.GetOrCreateLockedWorkspace(
|
(await SharedWorkspaceLocking.GetOrCreateLockedWorkspace(
|
||||||
`test-workspace-${CloudRunner.buildParameters.buildGuid}`,
|
`test-workspace-${CloudRunner.buildParameters.buildGuid}`,
|
||||||
CloudRunner.buildParameters.buildGuid,
|
CloudRunner.buildParameters.buildGuid,
|
||||||
|
CloudRunner.buildParameters,
|
||||||
)) || CloudRunner.buildParameters.buildGuid;
|
)) || CloudRunner.buildParameters.buildGuid;
|
||||||
|
|
||||||
process.env.LOCKED_WORKSPACE = workspace;
|
process.env.LOCKED_WORKSPACE = workspace;
|
||||||
|
|
@ -84,6 +85,7 @@ export class BuildAutomationWorkflow implements WorkflowInterface {
|
||||||
await SharedWorkspaceLocking.ReleaseWorkspace(
|
await SharedWorkspaceLocking.ReleaseWorkspace(
|
||||||
`test-workspace-${CloudRunner.buildParameters.buildGuid}`,
|
`test-workspace-${CloudRunner.buildParameters.buildGuid}`,
|
||||||
CloudRunner.buildParameters.buildGuid,
|
CloudRunner.buildParameters.buildGuid,
|
||||||
|
CloudRunner.buildParameters,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue