Skip to content

Commit 3f478af

Browse files
nikitassharmaCarmenPopoviciuemily-shen
authored
CC-5418: Set instance_type in wrangler (#9633)
* CC-5418: Set instance_type in wrangler Allow users to specify an instance type in wrangler. Instance type will configure vCPU, memory, and disk. * move instance_type to top level * switch from minor change to patch * fix linting and formatting errors * Update packages/wrangler/src/cloudchamber/common.ts * Update packages/wrangler/src/cloudchamber/common.ts * Update packages/wrangler/src/cloudchamber/common.ts * Update packages/wrangler/src/cloudchamber/common.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/create.ts * Update packages/wrangler/src/cloudchamber/modify.ts * Update packages/wrangler/src/cloudchamber/modify.ts * Update packages/wrangler/src/cloudchamber/common.ts * Update packages/wrangler/src/__tests__/cloudchamber/create.test.ts * Update packages/wrangler/src/__tests__/cloudchamber/create.test.ts * Update packages/wrangler/src/config/validation.ts Co-authored-by: emily-shen <[email protected]> * Update packages/wrangler/src/config/validation.ts Co-authored-by: emily-shen <[email protected]> * Update packages/wrangler/src/cloudchamber/create.ts Co-authored-by: emily-shen <[email protected]> * Update packages/wrangler/src/config/environment.ts Co-authored-by: emily-shen <[email protected]> * Update packages/wrangler/src/config/validation.ts Co-authored-by: emily-shen <[email protected]> * Update packages/wrangler/src/config/validation.ts Co-authored-by: emily-shen <[email protected]> * Update packages/wrangler/src/cloudchamber/modify.ts Co-authored-by: emily-shen <[email protected]> * stricter requirements for command line args * validateOptionalProperty * fix tests * create command line args update --------- Co-authored-by: Carmen Popoviciu <[email protected]> Co-authored-by: emily-shen <[email protected]>
1 parent 24b2c66 commit 3f478af

File tree

10 files changed

+542
-63
lines changed

10 files changed

+542
-63
lines changed

.changeset/sad-drinks-relate.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
Add support for setting an instance type for containers in wrangler. This allows users to configure memory, disk, and vCPU by setting instance type when interacting with containers.

packages/wrangler/src/__tests__/cloudchamber/apply.test.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,4 +1603,140 @@ describe("cloudchamber apply", () => {
16031603
expect(std.stderr).toMatchInlineSnapshot(`""`);
16041604
/* eslint-enable */
16051605
});
1606+
1607+
test("can apply a simple application (instance type)", async () => {
1608+
setIsTTY(false);
1609+
writeWranglerConfig({
1610+
name: "my-container",
1611+
containers: [
1612+
{
1613+
name: "my-container-app",
1614+
instances: 3,
1615+
class_name: "DurableObjectClass",
1616+
instance_type: "dev",
1617+
configuration: {
1618+
image: "./Dockerfile",
1619+
},
1620+
constraints: {
1621+
tier: 2,
1622+
},
1623+
},
1624+
],
1625+
});
1626+
mockGetApplications([]);
1627+
mockCreateApplication({ id: "abc" } as Application);
1628+
await runWrangler("cloudchamber apply --json");
1629+
/* eslint-disable */
1630+
expect(std.stdout).toMatchInlineSnapshot(`
1631+
"╭ Deploy a container application deploy changes to your application
1632+
1633+
│ Container application changes
1634+
1635+
├ NEW my-container-app
1636+
1637+
│ [[containers]]
1638+
│ name = \\"my-container-app\\"
1639+
│ instances = 3
1640+
│ scheduling_policy = \\"default\\"
1641+
1642+
│ [containers.configuration]
1643+
│ image = \\"./Dockerfile\\"
1644+
│ instance_type = \\"dev\\"
1645+
1646+
│ [containers.constraints]
1647+
│ tier = 2
1648+
1649+
1650+
│  SUCCESS  Created application my-container-app (Application ID: abc)
1651+
1652+
╰ Applied changes
1653+
1654+
"
1655+
`);
1656+
expect(std.stderr).toMatchInlineSnapshot(`""`);
1657+
/* eslint-enable */
1658+
});
1659+
1660+
test("can apply a simple existing application (instance type)", async () => {
1661+
setIsTTY(false);
1662+
writeWranglerConfig({
1663+
name: "my-container",
1664+
containers: [
1665+
{
1666+
name: "my-container-app",
1667+
instances: 4,
1668+
class_name: "DurableObjectClass",
1669+
instance_type: "standard",
1670+
configuration: {
1671+
image: "./Dockerfile",
1672+
},
1673+
constraints: {
1674+
tier: 2,
1675+
},
1676+
},
1677+
],
1678+
});
1679+
mockGetApplications([
1680+
{
1681+
id: "abc",
1682+
name: "my-container-app",
1683+
instances: 3,
1684+
created_at: new Date().toString(),
1685+
version: 1,
1686+
account_id: "1",
1687+
scheduling_policy: SchedulingPolicy.REGIONAL,
1688+
configuration: {
1689+
image: "./Dockerfile",
1690+
disk: {
1691+
size: "2GB",
1692+
size_mb: 2000,
1693+
},
1694+
vcpu: 0.0625,
1695+
memory: "256MB",
1696+
memory_mib: 256,
1697+
},
1698+
constraints: {
1699+
tier: 3,
1700+
},
1701+
},
1702+
]);
1703+
const applicationReqBodyPromise = mockModifyApplication();
1704+
await runWrangler("cloudchamber apply --json");
1705+
/* eslint-disable */
1706+
expect(std.stdout).toMatchInlineSnapshot(`
1707+
"╭ Deploy a container application deploy changes to your application
1708+
1709+
│ Container application changes
1710+
1711+
├ EDIT my-container-app
1712+
1713+
│ [[containers]]
1714+
│ - instances = 3
1715+
│ + instances = 4
1716+
│ name = \\"my-container-app\\"
1717+
1718+
│ [containers.configuration]
1719+
│ image = \\"./Dockerfile\\"
1720+
│ - instance_type = \\"dev\\"
1721+
│ + instance_type = \\"standard\\"
1722+
1723+
│ [containers.constraints]
1724+
│ ...
1725+
│ - tier = 3
1726+
│ + tier = 2
1727+
1728+
├ Loading
1729+
1730+
1731+
│  SUCCESS  Modified application my-container-app
1732+
1733+
╰ Applied changes
1734+
1735+
"
1736+
`);
1737+
expect(std.stderr).toMatchInlineSnapshot(`""`);
1738+
const app = await applicationReqBodyPromise;
1739+
expect(app.configuration?.instance_type).toEqual("standard");
1740+
/* eslint-enable */
1741+
});
16061742
});

packages/wrangler/src/__tests__/cloudchamber/create.test.ts

Lines changed: 126 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,17 @@ describe("cloudchamber create", () => {
112112
-v, --version Show version number [boolean]
113113
114114
OPTIONS
115-
--json Return output as clean JSON [boolean] [default: false]
116-
--image Image to use for your deployment [string]
117-
--location Location on Cloudflare's network where your deployment will run [string]
118-
--var Container environment variables [array]
119-
--label Deployment labels [array]
120-
--all-ssh-keys To add all SSH keys configured on your account to be added to this deployment, set this option to true [boolean]
121-
--ssh-key-id ID of the SSH key to add to the deployment [array]
122-
--vcpu Number of vCPUs to allocate to this deployment. [number]
123-
--memory Amount of memory (GiB, MiB...) to allocate to this deployment. Ex: 4GiB. [string]
124-
--ipv4 Include an IPv4 in the deployment [boolean]"
115+
--json Return output as clean JSON [boolean] [default: false]
116+
--image Image to use for your deployment [string]
117+
--location Location on Cloudflare's network where your deployment will run [string]
118+
--var Container environment variables [array]
119+
--label Deployment labels [array]
120+
--all-ssh-keys To add all SSH keys configured on your account to be added to this deployment, set this option to true [boolean]
121+
--ssh-key-id ID of the SSH key to add to the deployment [array]
122+
--instance-type Instance type to allocate to this deployment [choices: \\"dev\\", \\"basic\\", \\"standard\\"]
123+
--vcpu Number of vCPUs to allocate to this deployment. [number]
124+
--memory Amount of memory (GiB, MiB...) to allocate to this deployment. Ex: 4GiB. [string]
125+
--ipv4 Include an IPv4 in the deployment [boolean]"
125126
`);
126127
});
127128

@@ -170,6 +171,53 @@ describe("cloudchamber create", () => {
170171
);
171172
});
172173

174+
it("should fail with a nice message when instance type is invalid", async () => {
175+
setIsTTY(false);
176+
fs.writeFileSync(
177+
"./wrangler.toml",
178+
TOML.stringify({
179+
name: "my-container",
180+
cloudchamber: {
181+
image: "hello:world",
182+
location: "sfo06",
183+
instance_type: "invalid",
184+
},
185+
}),
186+
187+
"utf-8"
188+
);
189+
await expect(
190+
runWrangler("cloudchamber create ")
191+
).rejects.toThrowErrorMatchingInlineSnapshot(
192+
` [Error: Processing wrangler.toml configuration:
193+
- "instance_type" should be one of 'dev', 'basic', or 'standard', but got invalid]`
194+
);
195+
});
196+
197+
it("should fail with a nice message when instance type is set with vcpu", async () => {
198+
setIsTTY(false);
199+
fs.writeFileSync(
200+
"./wrangler.toml",
201+
TOML.stringify({
202+
name: "my-container",
203+
cloudchamber: {
204+
image: "hello:world",
205+
location: "sfo06",
206+
vcpu: 2,
207+
instance_type: "dev",
208+
},
209+
}),
210+
211+
"utf-8"
212+
);
213+
await expect(
214+
runWrangler("cloudchamber create ")
215+
).rejects.toThrowErrorMatchingInlineSnapshot(
216+
` [Error: Processing wrangler.toml configuration:
217+
- "cloudchamber" configuration should not set either "memory" or "vcpu" with "instance_type"]`
218+
);
219+
});
220+
173221
it("should fail with a nice message when parameters are missing (json)", async () => {
174222
setIsTTY(false);
175223
setWranglerConfig({});
@@ -180,6 +228,18 @@ describe("cloudchamber create", () => {
180228
expect(std.err).toMatchInlineSnapshot(`""`);
181229
});
182230

231+
it("should fail with a nice message when instance type is set with memory (json)", async () => {
232+
setIsTTY(false);
233+
setWranglerConfig({});
234+
await runWrangler(
235+
"cloudchamber create --image hello:world --location sfo06 --instance-type dev --memory 400GB --json"
236+
);
237+
expect(std.out).toMatchInlineSnapshot(
238+
`"{\\"error\\":\\"Field /\\"instance_type/\\" is mutually exclusive with /\\"memory/\\" and /\\"vcpu/\\". These fields cannot be set together.\\"}"`
239+
);
240+
expect(std.err).toMatchInlineSnapshot(`""`);
241+
});
242+
183243
it("should create deployment (detects no interactivity)", async () => {
184244
setIsTTY(false);
185245
setWranglerConfig({});
@@ -194,8 +254,31 @@ describe("cloudchamber create", () => {
194254
expect(std.out).toMatchInlineSnapshot(MOCK_DEPLOYMENTS_COMPLEX_RESPONSE);
195255
});
196256

257+
it("should create deployment with instance type (detects no interactivity)", async () => {
258+
setIsTTY(false);
259+
setWranglerConfig({});
260+
mockGetKey();
261+
msw.use(
262+
http.post(
263+
"*/deployments/v2",
264+
async ({ request }) => {
265+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
266+
const r = (await request.json()) as Record<string, any>;
267+
expect(r.instance_type).toEqual("dev");
268+
return HttpResponse.json({});
269+
},
270+
{ once: true }
271+
)
272+
);
273+
expect(std.err).toMatchInlineSnapshot(`""`);
274+
await runWrangler(
275+
"cloudchamber create --image hello:world --location sfo06 --var HELLO:WORLD --var YOU:CONQUERED --instance-type dev --ipv4 true"
276+
);
277+
expect(std.out).toMatchInlineSnapshot(`"{}"`);
278+
});
279+
197280
it("properly reads wrangler config", async () => {
198-
// This is very similar to the previous test except config
281+
// This is very similar to the previous tests except config
199282
// is set in wrangler and not overridden by the CLI
200283
setIsTTY(false);
201284
setWranglerConfig({
@@ -216,6 +299,38 @@ describe("cloudchamber create", () => {
216299
expect(std.err).toMatchInlineSnapshot(`""`);
217300
});
218301

302+
it("properly reads wrangler config for instance type", async () => {
303+
// This is very similar to the previous tests except config
304+
// is set in wrangler and not overridden by the CLI
305+
setIsTTY(false);
306+
setWranglerConfig({
307+
image: "hello:world",
308+
ipv4: true,
309+
instance_type: "dev",
310+
location: "sfo06",
311+
});
312+
// if values are not read by wrangler, this mock won't work
313+
// since the wrangler command wont get the right parameters
314+
mockGetKey();
315+
msw.use(
316+
http.post(
317+
"*/deployments/v2",
318+
async ({ request }) => {
319+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
320+
const r = (await request.json()) as Record<string, any>;
321+
expect(r.instance_type).toEqual("dev");
322+
return HttpResponse.json({});
323+
},
324+
{ once: true }
325+
)
326+
);
327+
await runWrangler(
328+
"cloudchamber create --var HELLO:WORLD --var YOU:CONQUERED"
329+
);
330+
expect(std.out).toMatchInlineSnapshot(`"{}"`);
331+
expect(std.err).toMatchInlineSnapshot(`""`);
332+
});
333+
219334
it("should create deployment indicating ssh keys (detects no interactivity)", async () => {
220335
setIsTTY(false);
221336
setWranglerConfig({

packages/wrangler/src/__tests__/cloudchamber/modify.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ describe("cloudchamber modify", () => {
8686
--ssh-public-key-id Public SSH key IDs to include in this container. You can add one to your account with \`wrangler cloudchamber ssh create [array]
8787
--image The new image that the deployment will have from now on [string]
8888
--location The new location that the deployment will have from now on [string]
89+
--instance-type The new instance type that the deployment will have from now on [choices: \\"dev\\", \\"basic\\", \\"standard\\"]
8990
--vcpu The new vcpu that the deployment will have from now on [number]
9091
--memory The new memory that the deployment will have from now on [string]"
9192
`);

0 commit comments

Comments
 (0)