diff --git a/.changeset/tricky-schools-heal.md b/.changeset/tricky-schools-heal.md new file mode 100644 index 000000000000..43e76c8fe910 --- /dev/null +++ b/.changeset/tricky-schools-heal.md @@ -0,0 +1,7 @@ +--- +"wrangler": minor +--- + +Event messages are capitalized, images of wrong architectures properly show the error in `cloudchamber create` +When a new "health" enum is introduced, `wrangler cloudchamber list` won't crash anymore. +Update Cloudchamber schemas. diff --git a/packages/wrangler/src/__tests__/helpers/mock-cloudchamber.ts b/packages/wrangler/src/__tests__/helpers/mock-cloudchamber.ts index e0f5a0a5bb95..39043e856894 100644 --- a/packages/wrangler/src/__tests__/helpers/mock-cloudchamber.ts +++ b/packages/wrangler/src/__tests__/helpers/mock-cloudchamber.ts @@ -1,4 +1,8 @@ -import { DeploymentType, NodeGroup } from "../../cloudchamber/client"; +import { + DeploymentType, + NodeGroup, + PlacementStatusHealth, +} from "../../cloudchamber/client"; import type { DeploymentV2, PlacementWithEvents, @@ -42,7 +46,7 @@ export const MOCK_DEPLOYMENTS: DeploymentV2[] = [ }, current_placement: { deployment_version: 2, - status: { health: "running" }, + status: { health: PlacementStatusHealth.RUNNING }, deployment_id: "2", terminate: false, created_at: "123", @@ -91,7 +95,7 @@ export const MOCK_DEPLOYMENTS_COMPLEX: DeploymentV2[] = [ }, current_placement: { deployment_version: 2, - status: { health: "running" }, + status: { health: PlacementStatusHealth.RUNNING }, deployment_id: "2", terminate: false, created_at: "123", @@ -137,7 +141,7 @@ export const MOCK_DEPLOYMENTS_COMPLEX: DeploymentV2[] = [ }, current_placement: { deployment_version: 2, - status: { health: "running" }, + status: { health: PlacementStatusHealth.RUNNING }, deployment_id: "2", terminate: false, created_at: "123", @@ -156,7 +160,7 @@ export const MOCK_PLACEMENTS: PlacementWithEvents[] = [ deployment_version: 2, terminate: false, events: [], - status: { health: "stopped" }, + status: { health: PlacementStatusHealth.STOPPED }, }, { id: "3", @@ -165,7 +169,7 @@ export const MOCK_PLACEMENTS: PlacementWithEvents[] = [ deployment_version: 3, terminate: false, events: [], - status: { health: "failed" }, + status: { health: PlacementStatusHealth.FAILED }, }, { id: "1", @@ -174,6 +178,6 @@ export const MOCK_PLACEMENTS: PlacementWithEvents[] = [ deployment_version: 4, terminate: false, events: [], - status: { health: "running" }, + status: { health: PlacementStatusHealth.RUNNING }, }, ]; diff --git a/packages/wrangler/src/cloudchamber/cli/deployments.ts b/packages/wrangler/src/cloudchamber/cli/deployments.ts index a7fffb9ae0eb..36d17ecb1e31 100644 --- a/packages/wrangler/src/cloudchamber/cli/deployments.ts +++ b/packages/wrangler/src/cloudchamber/cli/deployments.ts @@ -7,9 +7,12 @@ import { DeploymentsService } from "../client"; import { wrap } from "../helpers/wrap"; import { idToLocationName } from "../locations"; import { statusToColored } from "./util"; -import type { Placement, State } from "../client"; +import type { + DeploymentPlacementState, + Placement, + PlacementStatusHealth, +} from "../client"; import type { DeploymentV2 } from "../client/models/DeploymentV2"; -import type { Status } from "../enums"; function ipv6(placement: Placement | undefined) { if (!placement) { @@ -52,12 +55,14 @@ function version(deployment: DeploymentV2) { function health(placement?: Placement) { if (!placement) { - return statusToColored("placing"); + return statusToColored(); } + if (!placement.status["health"]) { - return statusToColored("placing"); + return statusToColored(); } - return statusToColored(placement.status["health"] as Status); + + return statusToColored(placement.status["health"] as PlacementStatusHealth); } /** @@ -81,7 +86,7 @@ export async function loadDeployments( undefined, deploymentsParams?.location, deploymentsParams?.image, - deploymentsParams?.state as State, + deploymentsParams?.state as DeploymentPlacementState | undefined, deploymentsParams?.state ) ); diff --git a/packages/wrangler/src/cloudchamber/cli/index.ts b/packages/wrangler/src/cloudchamber/cli/index.ts index 0a1ea0aa96fa..2504f1cc7b72 100644 --- a/packages/wrangler/src/cloudchamber/cli/index.ts +++ b/packages/wrangler/src/cloudchamber/cli/index.ts @@ -16,14 +16,16 @@ import { } from "../client"; import { wrap } from "../helpers/wrap"; import { idToLocationName } from "../locations"; +import { capitalize } from "./util"; import type { CustomerImageRegistry, DeploymentV2, ListSSHPublicKeys, PlacementEvent, + PlacementStatusHealth, PlacementWithEvents, } from "../client"; -import type { EventName, Status } from "../enums"; +import type { EventName } from "../enums"; export function pollRegistriesUntilCondition( onRegistries: (registries: Array) => boolean @@ -184,11 +186,11 @@ async function waitForEvent( eventName.includes(e.name as EventName) ); if (!event) { - if ((p.status["health"] as Status) === "failed") { + if ((p.status["health"] as PlacementStatusHealth) === "failed") { return true; } - if ((p.status["health"] as Status) == "stopped") { + if ((p.status["health"] as PlacementStatusHealth) == "stopped") { return true; } @@ -212,7 +214,6 @@ async function waitForImagePull(deployment: DeploymentV2) { s.stop(); if (err) { crash(err.message); - return; } if ( @@ -225,13 +226,19 @@ async function waitForImagePull(deployment: DeploymentV2) { } if (eventPlacement.event.name == "ImagePullError") { - crash( - "Your container image couldn't be pulled, (404 not found). Did you specify the correct URL?", - `Run ${brandColor( - process.argv0 + " cloudchamber modify " + deployment.id - )} to change the deployment image` - ); - return; + // TODO: We should really report here something more specific when it's not found. + // For now, the cloudchamber API always returns a 404 in the message when the + // image is not found. + if (eventPlacement.event.message.includes("404")) { + crash( + "Your container image couldn't be pulled, (404 not found). Did you specify the correct URL?", + `Run ${brandColor( + process.argv0 + " cloudchamber modify " + deployment.id + )} to change the deployment image` + ); + } + + crash(capitalize(eventPlacement.event.message)); } updateStatus("Pulled your image"); @@ -264,7 +271,6 @@ async function waitForVMToStart(deployment: DeploymentV2) { s.stop(); if (err) { crash(err.message); - return; } if (!eventPlacement.event) { @@ -325,7 +331,6 @@ async function waitForPlacementInstance(deployment: DeploymentV2) { if (err) { crash(err.message); - return; } updateStatus( diff --git a/packages/wrangler/src/cloudchamber/cli/util.ts b/packages/wrangler/src/cloudchamber/cli/util.ts index baefb1b1fef8..d9a0ee4faef3 100644 --- a/packages/wrangler/src/cloudchamber/cli/util.ts +++ b/packages/wrangler/src/cloudchamber/cli/util.ts @@ -1,20 +1,32 @@ import { bgGreen, bgRed, bgYellow } from "@cloudflare/cli/colors"; -import type { Status } from "../enums"; +import { type PlacementStatusHealth } from "../client"; -export function statusToColored(status?: Status): string { +export function capitalize(str: S): Capitalize { + return ( + str.length > 0 ? str[0].toUpperCase() + str.substring(1) : str + ) as Capitalize; +} + +export function statusToColored(status?: PlacementStatusHealth): string { if (!status) { return bgYellow("PLACING"); } - const mappings: Record string> = { - placing: bgYellow, + const mappings: Record string> = { + pending: bgYellow, placed: bgYellow, running: bgGreen, stopped: bgYellow, stopping: bgYellow, failed: bgRed, + unhealthy: bgRed, + complete: bgGreen, }; + if (!(status in mappings)) { + return bgYellow(status); + } + return mappings[status](status.toUpperCase()); } diff --git a/packages/wrangler/src/cloudchamber/client/index.ts b/packages/wrangler/src/cloudchamber/client/index.ts index 1f78da7e846d..1502f040ff76 100644 --- a/packages/wrangler/src/cloudchamber/client/index.ts +++ b/packages/wrangler/src/cloudchamber/client/index.ts @@ -14,17 +14,26 @@ export type { AccountLocationLimits } from "./models/AccountLocationLimits"; export type { AccountLocationLimitsAsProperty } from "./models/AccountLocationLimitsAsProperty"; export type { AccountRegistryToken } from "./models/AccountRegistryToken"; export type { Application } from "./models/Application"; +export type { ApplicationAffinities } from "./models/ApplicationAffinities"; +export { ApplicationAffinityColocation } from "./models/ApplicationAffinityColocation"; +export type { ApplicationConstraints } from "./models/ApplicationConstraints"; export type { ApplicationID } from "./models/ApplicationID"; export type { ApplicationJob } from "./models/ApplicationJob"; +export type { ApplicationJobsConfig } from "./models/ApplicationJobsConfig"; export { ApplicationMutationError } from "./models/ApplicationMutationError"; export type { ApplicationName } from "./models/ApplicationName"; export type { ApplicationNotFoundError } from "./models/ApplicationNotFoundError"; +export type { ApplicationStatus } from "./models/ApplicationStatus"; export { AssignIPv4 } from "./models/AssignIPv4"; +export { AssignIPv6 } from "./models/AssignIPv6"; export type { BadRequestError } from "./models/BadRequestError"; export { BadRequestWithCodeError } from "./models/BadRequestWithCodeError"; +export type { City } from "./models/City"; export type { Command } from "./models/Command"; export type { CompleteAccountCustomer } from "./models/CompleteAccountCustomer"; export type { CompleteAccountLocationCustomer } from "./models/CompleteAccountLocationCustomer"; +export { ContainerNetworkMode } from "./models/ContainerNetworkMode"; +export type { CreateApplicationBadRequest } from "./models/CreateApplicationBadRequest"; export type { CreateApplicationJobBadRequest } from "./models/CreateApplicationJobBadRequest"; export type { CreateApplicationJobRequest } from "./models/CreateApplicationJobRequest"; export type { CreateApplicationRequest } from "./models/CreateApplicationRequest"; @@ -36,31 +45,49 @@ export type { CreateSSHPublicKeyRequestBody } from "./models/CreateSSHPublicKeyR export type { CustomerImageRegistry } from "./models/CustomerImageRegistry"; export type { DeleteDeploymentError } from "./models/DeleteDeploymentError"; export type { DeploymentAlreadyExists } from "./models/DeploymentAlreadyExists"; +export type { DeploymentCheck } from "./models/DeploymentCheck"; +export type { DeploymentCheckHTTP } from "./models/DeploymentCheckHTTP"; +export type { DeploymentCheckHTTPRequestBody } from "./models/DeploymentCheckHTTPRequestBody"; +export { DeploymentCheckKind } from "./models/DeploymentCheckKind"; +export type { DeploymentCheckRequestBody } from "./models/DeploymentCheckRequestBody"; +export { DeploymentCheckType } from "./models/DeploymentCheckType"; export type { DeploymentCreationError } from "./models/DeploymentCreationError"; export type { DeploymentID } from "./models/DeploymentID"; export type { DeploymentListError } from "./models/DeploymentListError"; export type { DeploymentLocation } from "./models/DeploymentLocation"; export type { DeploymentModificationError } from "./models/DeploymentModificationError"; export { DeploymentMutationError } from "./models/DeploymentMutationError"; -export type { DeploymentNotFoundError } from "./models/DeploymentNotFoundError"; +export { DeploymentNotFoundError } from "./models/DeploymentNotFoundError"; +export { DeploymentPlacementState } from "./models/DeploymentPlacementState"; export type { DeploymentQueuedDetails } from "./models/DeploymentQueuedDetails"; export { DeploymentQueuedReason } from "./models/DeploymentQueuedReason"; export type { DeploymentReplacementError } from "./models/DeploymentReplacementError"; export { DeploymentSchedulingState } from "./models/DeploymentSchedulingState"; +export type { DeploymentSecretMap } from "./models/DeploymentSecretMap"; export type { DeploymentState } from "./models/DeploymentState"; export { DeploymentType } from "./models/DeploymentType"; export type { DeploymentV2 } from "./models/DeploymentV2"; export type { DeploymentVersion } from "./models/DeploymentVersion"; +export type { Disk } from "./models/Disk"; +export type { DiskMB } from "./models/DiskMB"; +export type { DiskSizeWithUnit } from "./models/DiskSizeWithUnit"; export type { DNSConfiguration } from "./models/DNSConfiguration"; export type { Domain } from "./models/Domain"; +export type { Duration } from "./models/Duration"; export type { EmptyResponse } from "./models/EmptyResponse"; export type { Entrypoint } from "./models/Entrypoint"; export type { EnvironmentVariable } from "./models/EnvironmentVariable"; export type { EnvironmentVariableName } from "./models/EnvironmentVariableName"; export type { EnvironmentVariableValue } from "./models/EnvironmentVariableValue"; +export { EventName } from "./models/EventName"; +export { EventType } from "./models/EventType"; export type { ExecFormParam } from "./models/ExecFormParam"; +export type { GenericErrorDetails } from "./models/GenericErrorDetails"; +export type { GenericErrorResponseWithRequestID } from "./models/GenericErrorResponseWithRequestID"; +export type { GenericMessageResponse } from "./models/GenericMessageResponse"; export type { GetDeploymentError } from "./models/GetDeploymentError"; export type { GetPlacementError } from "./models/GetPlacementError"; +export { HTTPMethod } from "./models/HTTPMethod"; export type { Identity } from "./models/Identity"; export type { Image } from "./models/Image"; export { ImageRegistryAlreadyExistsError } from "./models/ImageRegistryAlreadyExistsError"; @@ -69,6 +96,12 @@ export { ImageRegistryIsPublic } from "./models/ImageRegistryIsPublic"; export { ImageRegistryNotAllowedError } from "./models/ImageRegistryNotAllowedError"; export { ImageRegistryNotFoundError } from "./models/ImageRegistryNotFoundError"; export { ImageRegistryPermissions } from "./models/ImageRegistryPermissions"; +export type { ImageRegistryProtocol } from "./models/ImageRegistryProtocol"; +export { ImageRegistryProtocolAlreadyExists } from "./models/ImageRegistryProtocolAlreadyExists"; +export { ImageRegistryProtocolIsReferencedError } from "./models/ImageRegistryProtocolIsReferencedError"; +export { ImageRegistryProtocolNotFound } from "./models/ImageRegistryProtocolNotFound"; +export type { ImageRegistryProtocols } from "./models/ImageRegistryProtocols"; +export type { ImageRegistryProtoDomain } from "./models/ImageRegistryProtoDomain"; export type { InternalError } from "./models/InternalError"; export type { IP } from "./models/IP"; export type { IPAllocation } from "./models/IPAllocation"; @@ -78,7 +111,13 @@ export type { IPAllocationsWithFilter } from "./models/IPAllocationsWithFilter"; export { IPType } from "./models/IPType"; export type { IPV4 } from "./models/IPV4"; export type { ISO8601Timestamp } from "./models/ISO8601Timestamp"; +export type { JobEvents } from "./models/JobEvents"; export type { JobID } from "./models/JobID"; +export type { JobNotFoundError } from "./models/JobNotFoundError"; +export type { JobSecretMap } from "./models/JobSecretMap"; +export type { JobStatus } from "./models/JobStatus"; +export { JobStatusHealth } from "./models/JobStatusHealth"; +export type { JobTimeoutSeconds } from "./models/JobTimeoutSeconds"; export type { Label } from "./models/Label"; export type { LabelName } from "./models/LabelName"; export type { LabelValue } from "./models/LabelValue"; @@ -87,43 +126,60 @@ export type { ListDeploymentsV2 } from "./models/ListDeploymentsV2"; export type { ListIPsIsAllocated } from "./models/ListIPsIsAllocated"; export type { ListPlacements } from "./models/ListPlacements"; export type { ListPlacementsError } from "./models/ListPlacementsError"; +export type { ListSecretsMetadata } from "./models/ListSecretsMetadata"; export type { ListSSHPublicKeys } from "./models/ListSSHPublicKeys"; export type { ListSSHPublicKeysError } from "./models/ListSSHPublicKeysError"; export type { Location } from "./models/Location"; export type { LocationID } from "./models/LocationID"; export type { MemorySizeWithUnit } from "./models/MemorySizeWithUnit"; +export type { ModifyApplicationJobBadRequest } from "./models/ModifyApplicationJobBadRequest"; +export type { ModifyApplicationJobRequest } from "./models/ModifyApplicationJobRequest"; export type { ModifyApplicationRequestBody } from "./models/ModifyApplicationRequestBody"; export type { ModifyDeploymentBadRequest } from "./models/ModifyDeploymentBadRequest"; export type { ModifyDeploymentV2RequestBody } from "./models/ModifyDeploymentV2RequestBody"; export type { ModifyMeRequestBody } from "./models/ModifyMeRequestBody"; +export type { ModifySecretRequestBody } from "./models/ModifySecretRequestBody"; export type { Network } from "./models/Network"; export { NetworkMode } from "./models/NetworkMode"; export type { NetworkParameters } from "./models/NetworkParameters"; export { NodeGroup } from "./models/NodeGroup"; -export type { NodeName } from "./models/NodeName"; export type { Placement } from "./models/Placement"; export type { PlacementEvent } from "./models/PlacementEvent"; export type { PlacementEvents } from "./models/PlacementEvents"; export type { PlacementID } from "./models/PlacementID"; export type { PlacementNotFoundError } from "./models/PlacementNotFoundError"; export type { PlacementStatus } from "./models/PlacementStatus"; +export { PlacementStatusHealth } from "./models/PlacementStatusHealth"; export type { PlacementWithEvents } from "./models/PlacementWithEvents"; +export type { PlainTextSecretValue } from "./models/PlainTextSecretValue"; export type { Port } from "./models/Port"; export type { Ref } from "./models/Ref"; +export type { Region } from "./models/Region"; export type { ReplaceDeploymentRequestBody } from "./models/ReplaceDeploymentRequestBody"; +export type { SchedulerDeploymentConfiguration } from "./models/SchedulerDeploymentConfiguration"; export { SchedulingPolicy } from "./models/SchedulingPolicy"; +export type { Secret } from "./models/Secret"; +export { SecretAccessType } from "./models/SecretAccessType"; +export type { SecretMap } from "./models/SecretMap"; +export type { SecretMetadata } from "./models/SecretMetadata"; +export type { SecretName } from "./models/SecretName"; +export { SecretNameAlreadyExists } from "./models/SecretNameAlreadyExists"; +export { SecretNotFound } from "./models/SecretNotFound"; export type { SSHPublicKey } from "./models/SSHPublicKey"; export type { SSHPublicKeyID } from "./models/SSHPublicKeyID"; export type { SSHPublicKeyItem } from "./models/SSHPublicKeyItem"; -export { State } from "./models/State"; +export { SSHPublicKeyNotFoundError } from "./models/SSHPublicKeyNotFoundError"; export type { UnAuthorizedError } from "./models/UnAuthorizedError"; export type { UnixTimestamp } from "./models/UnixTimestamp"; export type { UnknownAccount } from "./models/UnknownAccount"; +export type { UserDeploymentConfiguration } from "./models/UserDeploymentConfiguration"; export { AccountService } from "./services/AccountService"; export { ApplicationsService } from "./services/ApplicationsService"; export { DeploymentsService } from "./services/DeploymentsService"; export { ImageRegistriesService } from "./services/ImageRegistriesService"; export { IPsService } from "./services/IPsService"; +export { JobsService } from "./services/JobsService"; export { PlacementsService } from "./services/PlacementsService"; +export { SecretsService } from "./services/SecretsService"; export { SshPublicKeysService } from "./services/SshPublicKeysService"; diff --git a/packages/wrangler/src/cloudchamber/client/models/AccountLimit.ts b/packages/wrangler/src/cloudchamber/client/models/AccountLimit.ts index 7f192c9d8ed4..58474fa96295 100644 --- a/packages/wrangler/src/cloudchamber/client/models/AccountLimit.ts +++ b/packages/wrangler/src/cloudchamber/client/models/AccountLimit.ts @@ -3,6 +3,7 @@ /* eslint-disable */ import type { AccountID } from "./AccountID"; +import type { DiskSizeWithUnit } from "./DiskSizeWithUnit"; import type { MemorySizeWithUnit } from "./MemorySizeWithUnit"; import type { NetworkMode } from "./NetworkMode"; import type { NodeGroup } from "./NodeGroup"; @@ -14,6 +15,7 @@ export type AccountLimit = { account_id: AccountID; vcpu_per_deployment: number; memory_per_deployment: MemorySizeWithUnit; + disk_per_deployment: DiskSizeWithUnit; total_vcpu: number; total_memory: MemorySizeWithUnit; node_group: NodeGroup; diff --git a/packages/wrangler/src/cloudchamber/client/models/Application.ts b/packages/wrangler/src/cloudchamber/client/models/Application.ts index 367bd1d687d3..316214c0d45f 100644 --- a/packages/wrangler/src/cloudchamber/client/models/Application.ts +++ b/packages/wrangler/src/cloudchamber/client/models/Application.ts @@ -3,12 +3,14 @@ /* eslint-disable */ import type { AccountID } from "./AccountID"; +import type { ApplicationAffinities } from "./ApplicationAffinities"; +import type { ApplicationConstraints } from "./ApplicationConstraints"; import type { ApplicationID } from "./ApplicationID"; +import type { ApplicationJobsConfig } from "./ApplicationJobsConfig"; import type { ApplicationName } from "./ApplicationName"; import type { ISO8601Timestamp } from "./ISO8601Timestamp"; -import type { Label } from "./Label"; -import type { NetworkParameters } from "./NetworkParameters"; import type { SchedulingPolicy } from "./SchedulingPolicy"; +import type { UserDeploymentConfiguration } from "./UserDeploymentConfiguration"; /** * Describes multiple deployments with parameters that describe how they should be placed @@ -18,18 +20,13 @@ export type Application = { created_at: ISO8601Timestamp; account_id: AccountID; name: ApplicationName; - /** - * The image to be dynamically scheduled - */ - image: string; - network?: NetworkParameters; scheduling_policy: SchedulingPolicy; /** * Number of deployments to create */ instances: number; - /** - * Deployment labels - */ - labels?: Array