chore: update cloudly dependency stack

Align Cloudly with the current typedserver, smartconfig, smartstate, and Docker tooling releases so builds and Docker output stay compatible with the upgraded stack.
This commit is contained in:
2026-05-08 13:56:20 +00:00
parent 80226c8a1c
commit f40ef6b7c0
75 changed files with 4003 additions and 6406 deletions
+45 -17
View File
@@ -7,9 +7,9 @@ import { Image } from './classes.image.js';
export class ImageManager {
cloudlyRef: Cloudly;
public typedrouter = new plugins.typedrequest.TypedRouter();
public smartbucketInstance: plugins.smartbucket.SmartBucket;
public imageDir: plugins.smartbucket.Directory;
public dockerImageStore: plugins.docker.DockerImageStore;
public smartbucketInstance!: plugins.smartbucket.SmartBucket;
public imageDir!: plugins.smartbucket.Directory;
public dockerImageStore!: plugins.docker.DockerImageStore;
get db() {
return this.cloudlyRef.mongodbConnector.smartdataDb;
@@ -26,7 +26,7 @@ export class ImageManager {
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_CreateImage>(
'createImage',
async (reqArg, toolsArg) => {
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqArg);
await toolsArg!.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqArg);
const image = await this.CImage.create({
name: reqArg.name,
description: reqArg.description,
@@ -41,7 +41,7 @@ export class ImageManager {
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_GetImage>(
new plugins.typedrequest.TypedHandler('getImage', async (reqArg, toolsArg) => {
await toolsArg.passGuards([this.cloudlyRef.authManager.adminOrClusterIdentityGuard], reqArg);
await toolsArg!.passGuards([this.cloudlyRef.authManager.adminOrClusterIdentityGuard], reqArg);
const image = await this.CImage.getInstance({
id: reqArg.imageId,
});
@@ -55,7 +55,7 @@ export class ImageManager {
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_DeleteImage>(
'deleteImage',
async (reqArg, toolsArg) => {
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqArg);
await toolsArg!.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqArg);
const image = await this.CImage.getInstance({
id: reqArg.imageId,
});
@@ -69,7 +69,7 @@ export class ImageManager {
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_GetAllImages>(
'getAllImages',
async (requestArg, toolsArg) => {
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], requestArg);
await toolsArg!.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], requestArg);
const images = await this.CImage.getInstances({});
return {
images: await Promise.all(
@@ -96,9 +96,24 @@ export class ImageManager {
throw new plugins.typedrequest.TypedResponseError('Image not found');
}
const imageVersion = reqArg.versionString;
if (!imageVersion) {
throw new plugins.typedrequest.TypedResponseError('versionString is required');
}
console.log(
`got request to push image version ${imageVersion} for image ${refImage.data.name}`,
);
const storagePath = await refImage.getStoragePath(imageVersion);
refImage.data.versions = [
...refImage.data.versions.filter((version) => version.versionString !== imageVersion),
{
versionString: imageVersion,
source: 'upload',
storagePath,
size: 0,
createdAt: Date.now(),
},
];
await refImage.save();
const imagePushStream = reqArg.imageStream;
(async () => {
const smartWebDuplex = new plugins.smartstream.webstream.WebDuplexStream<
@@ -112,10 +127,12 @@ export class ImageManager {
});
imagePushStream.writeToWebstream(smartWebDuplex.writable);
await this.dockerImageStore.storeImage(
refImage.id,
storagePath,
plugins.smartstream.SmartDuplex.fromWebReadableStream(smartWebDuplex.readable),
);
})();
})().catch((error) => {
console.error(`failed to store image ${refImage.id}:${imageVersion}`, error);
});
return {
allowed: true,
};
@@ -133,13 +150,21 @@ export class ImageManager {
const imageVersion = image.data.versions.find(
(version) => version.versionString === reqArg.versionString,
);
const readable = this.imageDir.fastGetStream(
if (!imageVersion) {
throw new plugins.typedrequest.TypedResponseError('Image version not found');
}
const readable = await this.imageDir.fastGetStream(
{
path: await image.getStoragePath(reqArg.versionString),
path: imageVersion.storagePath || await image.getStoragePath(reqArg.versionString),
},
'webstream',
);
const imageVirtualStream = new plugins.typedrequest.VirtualStream();
(async () => {
await imageVirtualStream.readFromWebstream(readable);
})().catch((error) => {
console.error(`failed to stream image ${image.id}:${reqArg.versionString}`, error);
});
return {
imageStream: imageVirtualStream,
};
@@ -150,21 +175,24 @@ export class ImageManager {
public async start() {
// lets setup s3
const s3Descriptor: plugins.tsclass.storage.IS3Descriptor =
await this.cloudlyRef.config.appData.waitForAndGetKey('s3Descriptor');
const s3Descriptor =
await this.cloudlyRef.config.appData.waitForAndGetKey('s3Descriptor') as plugins.tsclass.storage.IS3Descriptor;
console.log(this.cloudlyRef.config.data.s3Descriptor);
this.smartbucketInstance = new plugins.smartbucket.SmartBucket(
this.cloudlyRef.config.data.s3Descriptor,
this.cloudlyRef.config.data.s3Descriptor!,
);
const bucket = await this.smartbucketInstance.getBucketByName(s3Descriptor.bucketName);
await bucket.fastPut({ path: 'images/00init', contents: 'init' });
const bucketName = s3Descriptor.bucketName!;
const bucket = await this.smartbucketInstance.bucketExists(bucketName)
? await this.smartbucketInstance.getBucketByName(bucketName)
: await this.smartbucketInstance.createBucket(bucketName);
await bucket.fastPut({ path: 'images/00init', contents: 'init', overwrite: true });
this.imageDir = await bucket.getDirectoryFromPath({
path: '/images',
});
// lets setup dockerstore
await plugins.smartfile.fs.ensureDir(paths.dockerImageStoreDir);
await plugins.fsPromises.mkdir(paths.dockerImageStoreDir, { recursive: true });
this.dockerImageStore = new plugins.docker.DockerImageStore({
localDirPath: paths.dockerImageStoreDir,
bucketDir: this.imageDir,