Skip to content
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

upcoming: [M3-8014] - Update APIv4 and Validation packages based on Image Service spec #10541

Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/api-v4": Upcoming Features
---

Update images endpoints to reflect the image service API spec ([#10541](https://github.com/linode/manager/pull/10541))
19 changes: 19 additions & 0 deletions packages/api-v4/src/images/images.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
createImageSchema,
updateImageRegionsSchema,
updateImageSchema,
uploadImageSchema,
} from '@linode/validation/lib/images.schema';
Expand Down Expand Up @@ -107,3 +108,21 @@ export const uploadImage = (data: ImageUploadPayload) => {
setData(data, uploadImageSchema)
);
};

/**
* Selects the regions to which this image will be replicated.
*
* @param imageId { string } ID of the Image to look up.
* @param regions { string[] } ID of regions to replicate to. Must contain at least one valid region.
*/
export const updateImageRegions = (imageId: string, regions: string[]) => {
const data = {
regions,
};

return Request<Image>(
setURL(`${API_ROOT}/images/${encodeURIComponent(imageId)}/regions`),
setMethod('POST'),
setData(data, updateImageRegionsSchema)
);
};
93 changes: 91 additions & 2 deletions packages/api-v4/src/images/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,113 @@ export type ImageStatus =
| 'deleted'
| 'pending_upload';

type ImageCapabilities = 'cloud-init';
type ImageCapabilities = 'cloud-init' | 'distributed-images';

type ImageType = 'manual' | 'automatic';

type ImageRegionStatus =
| 'creating'
| 'pending'
| 'available'
| 'pending deletion'
| 'pending replication'
Comment on lines +15 to +16
Copy link
Member

@bnussman-akamai bnussman-akamai Jun 3, 2024

Choose a reason for hiding this comment

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

Maybe we should ask for verification on this... It would be very unusual to have a status with spaces instead of underscores so I'm surprised this is what was reflected in the spec

Copy link
Contributor

Choose a reason for hiding this comment

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

++

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Confirmed by Priyank Patel on API team

| 'replicating'
| 'timedout';

export interface ImageRegion {
region: string;
status: ImageRegionStatus;
}

export interface Image {
/**
* An optional timestamp of this image's planned end-of-life.
*/
eol: string | null;

/**
* The unique ID of the this image.
*/
id: string;

/**
* A short description of this image.
*/
label: string;

/**
* A detailed description of this image.
*/
description: string | null;

/**
* The timestamp of when this image was created.
*/
created: string;

/**
* The timestamp of when this image was last updated.
*/
updated: string;
type: string;

/**
* Indicates the method of this image's creation.
*/
type: ImageType;

/**
* Whether this image is marked for public distribution.
*/
is_public: boolean;

/**
* The minimum size in MB needed to deploy this image.
*/
size: number;

/**
* The total storage consumed by this image across its regions.
*/
total_size: number;
hkhalil-akamai marked this conversation as resolved.
Show resolved Hide resolved

/**
* The name of the user who created this image or 'linode' for public images.
*/
created_by: null | string;

/**
* The distribution author.
*/
vendor: string | null;

/**
* Whether this is a public image that is deprecated.
*/
deprecated: boolean;

/**
* A timestamp of when this image will expire if it was automatically captured.
*/
expiry: null | string;

/**
* The current status of this image.
*/
status: ImageStatus;

/**
* A list of the capabilities of this image.
*/
capabilities: ImageCapabilities[];

/**
* A list of the regions in which this image is available.
*/
regions: ImageRegion[];

/**
* A list of tags added to this image.
*/
tags: string[];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Changed
---

Add `regions` and `total_size` fields to `imageFactory` ([#10541](https://github.com/linode/manager/pull/10541))
2 changes: 2 additions & 0 deletions packages/manager/src/factories/images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ export const imageFactory = Factory.Sync.makeFactory<Image>({
id: Factory.each((id) => `private/${id}`),
is_public: false,
label: Factory.each((i) => `image-${i}`),
regions: [],
size: 1500,
status: 'available',
tags: [],
total_size: 1500,
type: 'manual',
updated: new Date().toISOString(),
vendor: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/validation": Added
---

`updateImageRegionsSchema` ([#10541](https://github.com/linode/manager/pull/10541))
8 changes: 7 additions & 1 deletion packages/validation/src/images.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const baseImageSchema = object({
label: labelSchema.notRequired(),
description: string().notRequired().min(1).max(65000),
cloud_init: boolean().notRequired(),
tags: array(string()).notRequired(),
tags: array(string().min(3).max(50)).max(500).notRequired(),
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we have a validation schema we can share across linodes, volumes, etc for tags

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are the requirements for tags always the same across the API?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not 100% sure, but I would assume they are. Might require some investigation

});

export const createImageSchema = baseImageSchema.shape({
Expand All @@ -33,3 +33,9 @@ export const updateImageSchema = object({
.max(65000, 'Length must be 65000 characters or less.'),
tags: array(string()).notRequired(),
});

export const updateImageRegionsSchema = object({
regions: array(string())
.required('Regions are required.')
.min(1, 'Must specify at least one region.'),
});
Loading