Skip to content

Cloud Run Functions data model #8767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/deploy/functions/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@
serviceAccount?: string | null;
}

export type FunctionsPlatform = "gcfv1" | "gcfv2";
export const AllFunctionsPlatforms: FunctionsPlatform[] = ["gcfv1", "gcfv2", "run"];

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 303 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.
export const AllFunctionsPlatforms: FunctionsPlatform[] = ["gcfv1", "gcfv2"];

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 304 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot redeclare block-scoped variable 'AllFunctionsPlatforms'.

export type Triggered =
| HttpsTriggered
Expand Down Expand Up @@ -353,7 +353,7 @@
ServiceConfiguration &
Triggered & {
entryPoint: string;
platform: FunctionsPlatform;

Check failure on line 356 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 356 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 356 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 356 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 356 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 356 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot find name 'FunctionsPlatform'.
runtime: Runtime;

// Output only
Expand Down Expand Up @@ -702,8 +702,8 @@
* alphabetically
*/
export function compareFunctions(
left: TargetIds & { platform: FunctionsPlatform },

Check failure on line 705 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 705 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 705 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 705 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 705 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 705 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot find name 'FunctionsPlatform'.
right: TargetIds & { platform: FunctionsPlatform },

Check failure on line 706 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 706 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 706 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 706 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Cannot find name 'FunctionsPlatform'.

Check failure on line 706 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Cannot find name 'FunctionsPlatform'.

Check failure on line 706 in src/deploy/functions/backend.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Cannot find name 'FunctionsPlatform'.
): number {
if (left.platform !== right.platform) {
return right.platform < left.platform ? -1 : 1;
Expand Down
3 changes: 2 additions & 1 deletion src/deploy/functions/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@
export type MemoryOption = 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768;
const allMemoryOptions: MemoryOption[] = [128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768];

export type FunctionsPlatform = backend.FunctionsPlatform;
// Run is an automatic migration from gcfv2 and is not used on the wire.
export type FunctionsPlatform = Exclude<backend.FunctionsPlatform, "run">;

Check failure on line 212 in src/deploy/functions/build.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

'"/Users/runner/work/firebase-tools/firebase-tools/src/deploy/functions/backend"' has no exported member named 'FunctionsPlatform'. Did you mean 'AllFunctionsPlatforms'?

Check failure on line 212 in src/deploy/functions/build.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

'"/Users/runner/work/firebase-tools/firebase-tools/src/deploy/functions/backend"' has no exported member named 'FunctionsPlatform'. Did you mean 'AllFunctionsPlatforms'?

Check failure on line 212 in src/deploy/functions/build.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

'"/Users/runner/work/firebase-tools/firebase-tools/src/deploy/functions/backend"' has no exported member named 'FunctionsPlatform'. Did you mean 'AllFunctionsPlatforms'?

Check failure on line 212 in src/deploy/functions/build.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

'"/home/runner/work/firebase-tools/firebase-tools/src/deploy/functions/backend"' has no exported member named 'FunctionsPlatform'. Did you mean 'AllFunctionsPlatforms'?

Check failure on line 212 in src/deploy/functions/build.ts

View workflow job for this annotation

GitHub Actions / unit (20)

'"/home/runner/work/firebase-tools/firebase-tools/src/deploy/functions/backend"' has no exported member named 'FunctionsPlatform'. Did you mean 'AllFunctionsPlatforms'?

Check failure on line 212 in src/deploy/functions/build.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

'"/home/runner/work/firebase-tools/firebase-tools/src/deploy/functions/backend"' has no exported member named 'FunctionsPlatform'. Did you mean 'AllFunctionsPlatforms'?
export const AllFunctionsPlatforms: FunctionsPlatform[] = ["gcfv1", "gcfv2"];
export type VpcEgressSetting = backend.VpcEgressSettings;
export const AllVpcEgressSettings: VpcEgressSetting[] = ["PRIVATE_RANGES_ONLY", "ALL_TRAFFIC"];
Expand Down
2 changes: 1 addition & 1 deletion src/deploy/functions/ensure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export async function defaultServiceAccount(e: backend.Endpoint): Promise<string
const metadata = await metadataCall;
if (e.platform === "gcfv1") {
return `${metadata.projectId}@appspot.gserviceaccount.com`;
} else if (e.platform === "gcfv2") {
} else if (e.platform === "gcfv2" || e.platform === "run") {
return await getDefaultServiceAccount(metadata.projectNumber);
}
assertExhaustive(e.platform);
Expand Down
7 changes: 6 additions & 1 deletion src/deploy/functions/functionsDeployHelper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as backend from "./backend";
import { DEFAULT_CODEBASE, ValidatedConfig } from "../../functions/projectConfig";
import { assertExhaustive } from "../../functional";

export interface EndpointFilter {
// If codebase is undefined, match all functions in all codebase that matches the idChunks.
Expand Down Expand Up @@ -130,8 +131,12 @@
export function getHumanFriendlyPlatformName(platform: backend.Endpoint["platform"]): string {
if (platform === "gcfv1") {
return "1st Gen";
} else if (platform === "gcfv2") {
return "2nd Gen";
} else if (platform === "run") {
return "Cloud Run";
}
return "2nd Gen";
assertExhaustive(platform);

Check failure on line 139 in src/deploy/functions/functionsDeployHelper.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 139 in src/deploy/functions/functionsDeployHelper.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 139 in src/deploy/functions/functionsDeployHelper.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 139 in src/deploy/functions/functionsDeployHelper.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 139 in src/deploy/functions/functionsDeployHelper.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 139 in src/deploy/functions/functionsDeployHelper.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/deploy/functions/prepare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,11 @@ export async function prepare(
let resource: string;
if (endpoint.platform === "gcfv1") {
resource = `projects/${endpoint.project}/locations/${endpoint.region}/functions/${endpoint.id}`;
} else if (endpoint.platform === "gcfv2") {
} else if (endpoint.platform === "gcfv2" || endpoint.platform === "run") {
// N.B. If GCF starts allowing v1's allowable characters in IDs they're
// going to need to have a transform to create a service ID (which has a
// more restrictive character set). We'll need to reimplement that here.
// BUG BUG BUG. This has happened and we need to fix it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This comment indicates a known issue where the function ID to service ID conversion is not happening. It's marked as a BUG BUG BUG, suggesting it's critical and needs to be addressed.

Suggested change
// BUG BUG BUG. This has happened and we need to fix it.
// TODO: Implement function ID to service ID conversion

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO the severity of this comment is accurate. This is a WIP and a BUG should be resolved before releasing to the public whereas a TODO can be ignored for years.

resource = `projects/${endpoint.project}/locations/${endpoint.region}/services/${endpoint.id}`;
} else {
assertExhaustive(endpoint.platform);
Expand Down
27 changes: 22 additions & 5 deletions src/deploy/functions/pricing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ export function canCalculateMinInstanceCost(endpoint: backend.Endpoint): boolean
const SECONDS_PER_MONTH = 30 * 24 * 60 * 60;

/** The cost of a series of endpoints at 100% idle in a 30d month. */
// BUG BUG BUG!
// This method incorrectly gives a disjoint free tier for GCF v1 and GCF v2 which
// was broken and never fixed when GCF decided to vendor Run usage as the GCF SKU.
// It should be a single free tier that applies to both. This will soon be wrong
// in a _different_ way when GCF v2 un-vendors the SKU and instead v2 and Run should
// share a free tier.
export function monthlyMinInstanceCost(endpoints: backend.Endpoint[]): number {
// Assertion: canCalculateMinInstanceCost
type Usage = {
Expand All @@ -169,6 +175,7 @@ export function monthlyMinInstanceCost(endpoints: backend.Endpoint[]): number {
const usage: Record<backend.FunctionsPlatform, Record<tier, Usage>> = {
gcfv1: { 1: { ram: 0, cpu: 0 }, 2: { ram: 0, cpu: 0 } },
gcfv2: { 1: { ram: 0, cpu: 0 }, 2: { ram: 0, cpu: 0 } },
run: { 1: { ram: 0, cpu: 0 }, 2: { ram: 0, cpu: 0 } },
};

for (const endpoint of endpoints) {
Expand All @@ -188,10 +195,10 @@ export function monthlyMinInstanceCost(endpoints: backend.Endpoint[]): number {
} else {
// V2 is currently fixed at 1vCPU.
const tier = V2_REGION_TO_TIER[endpoint.region];
usage["gcfv2"][tier].ram =
usage["gcfv2"][tier].ram + ramGb * SECONDS_PER_MONTH * endpoint.minInstances;
usage["gcfv2"][tier].cpu =
usage["gcfv2"][tier].cpu +
usage[endpoint.platform][tier].ram =
usage[endpoint.platform][tier].ram + ramGb * SECONDS_PER_MONTH * endpoint.minInstances;
usage[endpoint.platform][tier].cpu =
usage[endpoint.platform][tier].cpu +
(endpoint.cpu as number) * SECONDS_PER_MONTH * endpoint.minInstances;
}
}
Expand All @@ -218,5 +225,15 @@ export function monthlyMinInstanceCost(endpoints: backend.Endpoint[]): number {
v2CpuBill -= V2_FREE_TIER.vCpu * V2_RATES.vCpu[1];
v2CpuBill = Math.max(v2CpuBill, 0);

return v1MemoryBill + v1CpuBill + v2MemoryBill + v2CpuBill;
let runMemoryBill =
usage["run"][1].ram * V2_RATES.memoryGb[1] + usage["run"][2].ram * V2_RATES.memoryGb[2];
runMemoryBill -= V2_FREE_TIER.memoryGb * V2_RATES.memoryGb[1];
runMemoryBill = Math.max(runMemoryBill, 0);

let runCpuBill =
usage["run"][1].cpu * V2_RATES.idleVCpu[1] + usage["run"][2].cpu * V2_RATES.idleVCpu[2];
runCpuBill -= V2_FREE_TIER.vCpu * V2_RATES.vCpu[1];
runCpuBill = Math.max(runCpuBill, 0);

return v1MemoryBill + v1CpuBill + v2MemoryBill + v2CpuBill + runMemoryBill + runCpuBill;
}
25 changes: 22 additions & 3 deletions src/deploy/functions/release/fabricator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ export class Fabricator {
await this.createV1Function(endpoint, scraperV1);
} else if (endpoint.platform === "gcfv2") {
await this.createV2Function(endpoint, scraperV2);
} else if (endpoint.platform === "run") {
throw new FirebaseError("Creating new Cloud Run functions is not supported yet.", {
exit: 1,
});
} else {
assertExhaustive(endpoint.platform);
}
Expand All @@ -206,6 +210,8 @@ export class Fabricator {
await this.updateV1Function(update.endpoint, scraperV1);
} else if (update.endpoint.platform === "gcfv2") {
await this.updateV2Function(update.endpoint, scraperV2);
} else if (update.endpoint.platform === "run") {
throw new FirebaseError("Updating Cloud Run functions is not supported yet.", { exit: 1 });
} else {
assertExhaustive(update.endpoint.platform);
}
Expand All @@ -216,10 +222,13 @@ export class Fabricator {
async deleteEndpoint(endpoint: backend.Endpoint): Promise<void> {
await this.deleteTrigger(endpoint);
if (endpoint.platform === "gcfv1") {
await this.deleteV1Function(endpoint);
} else {
await this.deleteV2Function(endpoint);
return this.deleteV1Function(endpoint);
} else if (endpoint.platform === "gcfv2") {
return this.deleteV2Function(endpoint);
} else if (endpoint.platform === "run") {
throw new FirebaseError("Deleting Cloud Run functions is not supported yet.", { exit: 1 });
}
assertExhaustive(endpoint.platform);
}

async createV1Function(endpoint: backend.Endpoint, scraper: SourceTokenScraper): Promise<void> {
Expand Down Expand Up @@ -623,6 +632,11 @@ export class Fabricator {
// Set/Delete trigger is responsible for wiring up a function with any trigger not owned
// by the GCF API. This includes schedules, task queues, and blocking function triggers.
async setTrigger(endpoint: backend.Endpoint): Promise<void> {
if (endpoint.platform === "run") {
throw new FirebaseError("Setting triggers for Cloud Run functions is not supported yet.", {
exit: 1,
});
}
if (backend.isScheduleTriggered(endpoint)) {
if (endpoint.platform === "gcfv1") {
await this.upsertScheduleV1(endpoint);
Expand All @@ -640,6 +654,11 @@ export class Fabricator {
}

async deleteTrigger(endpoint: backend.Endpoint): Promise<void> {
if (endpoint.platform === "run") {
throw new FirebaseError("Deleting triggers for Cloud Run functions is not supported yet.", {
exit: 1,
});
}
if (backend.isScheduleTriggered(endpoint)) {
if (endpoint.platform === "gcfv1") {
await this.deleteScheduleV1(endpoint);
Expand Down
5 changes: 5 additions & 0 deletions src/experiments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export const ALL_EXPERIMENTS = experiments({
"of how that image was created.",
public: true,
},
runfunctions: {
shortDescription:
"Functions created using the V2 API target Cloud Run Functions (not production ready)",
public: false,
},

// Emulator experiments
emulatoruisnapshot: {
Expand Down
4 changes: 4 additions & 0 deletions src/functions/secrets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,12 @@
operationResourceName: op.name,
});
return gcfV2.endpointFromFunction(cfn);
} else if (endpoint.platform === "run") {
// This may be tricky because the image has been deleted. How does this work
// with GCF?
throw new FirebaseError("Updating Cloud Run functions is not yet implemented.");
Comment on lines +363 to +365

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This error message is not very informative. Consider adding more context to the error message to help users understand why updating Cloud Run functions is not yet implemented.

Suggested change
// This may be tricky because the image has been deleted. How does this work
// with GCF?
throw new FirebaseError("Updating Cloud Run functions is not yet implemented.");
throw new FirebaseError("Updating secrets for Cloud Run functions is not yet implemented. Please use GCFv2.");

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad suggestion

} else {
assertExhaustive(endpoint.platform);

Check failure on line 367 in src/functions/secrets.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (22)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 367 in src/functions/secrets.ts

View workflow job for this annotation

GitHub Actions / vscode_unit (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 367 in src/functions/secrets.ts

View workflow job for this annotation

GitHub Actions / vscode_integration (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 367 in src/functions/secrets.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (22)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 367 in src/functions/secrets.ts

View workflow job for this annotation

GitHub Actions / unit (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.

Check failure on line 367 in src/functions/secrets.ts

View workflow job for this annotation

GitHub Actions / check-json-schema (20)

Argument of type 'FunctionsPlatform' is not assignable to parameter of type 'never'.
}
}

Expand Down
24 changes: 0 additions & 24 deletions src/gcp/cloudfunctionsv2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,30 +62,6 @@ describe("cloudfunctionsv2", () => {
updateTime: new Date(),
};

describe("megabytes", () => {
enum Bytes {
KB = 1e3,
MB = 1e6,
GB = 1e9,
KiB = 1 << 10,
MiB = 1 << 20,
GiB = 1 << 30,
}
it("Should handle decimal SI units", () => {
expect(cloudfunctionsv2.mebibytes("1000k")).to.equal((1000 * Bytes.KB) / Bytes.MiB);
expect(cloudfunctionsv2.mebibytes("1.5M")).to.equal((1.5 * Bytes.MB) / Bytes.MiB);
expect(cloudfunctionsv2.mebibytes("1G")).to.equal(Bytes.GB / Bytes.MiB);
});
it("Should handle binary SI units", () => {
expect(cloudfunctionsv2.mebibytes("1Mi")).to.equal(Bytes.MiB / Bytes.MiB);
expect(cloudfunctionsv2.mebibytes("1Gi")).to.equal(Bytes.GiB / Bytes.MiB);
});
it("Should handle no unit", () => {
expect(cloudfunctionsv2.mebibytes("100000")).to.equal(100000 / Bytes.MiB);
expect(cloudfunctionsv2.mebibytes("1e9")).to.equal(1e9 / Bytes.MiB);
expect(cloudfunctionsv2.mebibytes("1.5E6")).to.equal((1.5 * 1e6) / Bytes.MiB);
});
});
describe("functionFromEndpoint", () => {
it("should guard against version mixing", () => {
expect(() => {
Expand Down
38 changes: 1 addition & 37 deletions src/gcp/cloudfunctionsv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
HASH_LABEL,
} from "../functions/constants";
import { RequireKeys } from "../metaprogramming";
import { mebibytes } from "./k8s";

export const API_VERSION = "v2";

Expand Down Expand Up @@ -206,43 +207,6 @@ interface GenerateUploadUrlResponse {
storageSource: StorageSource;
}

// AvailableMemory suffixes and their byte count.
type MemoryUnit = "" | "k" | "M" | "G" | "T" | "Ki" | "Mi" | "Gi" | "Ti";
const BYTES_PER_UNIT: Record<MemoryUnit, number> = {
"": 1,
k: 1e3,
M: 1e6,
G: 1e9,
T: 1e12,
Ki: 1 << 10,
Mi: 1 << 20,
Gi: 1 << 30,
Ti: 1 << 40,
};

/**
* Returns the float-precision number of Mega(not Mebi)bytes in a
* Kubernetes-style quantity
* Must serve the same results as
* https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/api/resource/quantity.go
*/
export function mebibytes(memory: string): number {
const re = /^([0-9]+(\.[0-9]*)?)(Ki|Mi|Gi|Ti|k|M|G|T|([eE]([0-9]+)))?$/;
const matches = re.exec(memory);
if (!matches) {
throw new Error(`Invalid memory quantity "${memory}""`);
}
const quantity = Number.parseFloat(matches[1]);
let bytes: number;
if (matches[5]) {
bytes = quantity * Math.pow(10, Number.parseFloat(matches[5]));
} else {
const suffix = matches[3] || "";
bytes = quantity * BYTES_PER_UNIT[suffix as MemoryUnit];
}
return bytes / (1 << 20);
}

/**
* Logs an error from a failed function deployment.
* @param func The function that was unsuccessfully deployed.
Expand Down
2 changes: 1 addition & 1 deletion src/gcp/cloudscheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export async function jobFromEndpoint(
scheduled: "true",
},
};
} else if (endpoint.platform === "gcfv2") {
} else if (endpoint.platform === "gcfv2" || endpoint.platform === "run") {
job.timeZone = endpoint.scheduleTrigger.timeZone || DEFAULT_TIME_ZONE_V2;
job.httpTarget = {
uri: endpoint.uri!,
Expand Down
30 changes: 30 additions & 0 deletions src/gcp/k8s.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { expect } from "chai";
import * as k8s from "./k8s";

describe("megabytes", () => {
enum Bytes {
KB = 1e3,
MB = 1e6,
GB = 1e9,
KiB = 1 << 10,
MiB = 1 << 20,
GiB = 1 << 30,
}

it("Should handle decimal SI units", () => {
expect(k8s.mebibytes("1000k")).to.equal((1000 * Bytes.KB) / Bytes.MiB);
expect(k8s.mebibytes("1.5M")).to.equal((1.5 * Bytes.MB) / Bytes.MiB);
expect(k8s.mebibytes("1G")).to.equal(Bytes.GB / Bytes.MiB);
});

it("Should handle binary SI units", () => {
expect(k8s.mebibytes("1Mi")).to.equal(Bytes.MiB / Bytes.MiB);
expect(k8s.mebibytes("1Gi")).to.equal(Bytes.GiB / Bytes.MiB);
});

it("Should handle no unit", () => {
expect(k8s.mebibytes("100000")).to.equal(100000 / Bytes.MiB);
expect(k8s.mebibytes("1e9")).to.equal(1e9 / Bytes.MiB);
expect(k8s.mebibytes("1.5E6")).to.equal((1.5 * 1e6) / Bytes.MiB);
});
});
69 changes: 69 additions & 0 deletions src/gcp/k8s.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// AvailableMemory suffixes and their byte count.
type MemoryUnit = "" | "k" | "M" | "G" | "T" | "Ki" | "Mi" | "Gi" | "Ti";
const BYTES_PER_UNIT: Record<MemoryUnit, number> = {
"": 1,
k: 1e3,
M: 1e6,
G: 1e9,
T: 1e12,
Ki: 1 << 10,
Mi: 1 << 20,
Gi: 1 << 30,
Ti: 1 << 40,
};
/**
* Returns the float-precision number of Mebi(not Mega)bytes in a
* Kubernetes-style quantity
* Must serve the same results as
* https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/api/resource/quantity.go
*/

export function mebibytes(memory: string): number {
const re = /^([0-9]+(\.[0-9]*)?)(Ki|Mi|Gi|Ti|k|M|G|T|([eE]([0-9]+)))?$/;
const matches = re.exec(memory);
if (!matches) {
throw new Error(`Invalid memory quantity "${memory}""`);
}
const quantity = Number.parseFloat(matches[1]);
let bytes: number;
if (matches[5]) {
bytes = quantity * Math.pow(10, Number.parseFloat(matches[5]));
} else {
const suffix = matches[3] || "";
bytes = quantity * BYTES_PER_UNIT[suffix as MemoryUnit];
}
return bytes / (1 << 20);
}

export interface PlaintextEnvVar {
name: string;
value: string;
}

export interface SecretEnvVar {
name: string;
valueSource: {
secretKeyRef: {
secret: string; // Secret name
version?: string; // Optional version, defaults to latest
};
};
}

export type EnvVar = PlaintextEnvVar | SecretEnvVar;

export type ResourceType = "cpu" | "memory" | "nvidia.com/gpu";

export interface Container {
name?: string;
image: string;
command?: string[];
args?: string[];
env: EnvVar[];
workingDir?: string;
resources: {
limits: Record<ResourceType, string>;
};
cpuIdle?: boolean;
startupCpuBoost?: boolean;
}
Loading
Loading