diff --git a/packages/grid_client/src/modules/base.ts b/packages/grid_client/src/modules/base.ts index c8192ec2cf..1fbd0c1b2a 100644 --- a/packages/grid_client/src/modules/base.ts +++ b/packages/grid_client/src/modules/base.ts @@ -47,12 +47,16 @@ class BaseModule { this.tfClient = config.tfclient; } + getNewDeploymentPath(...paths: string[]): string { + return PATH.join(this.config.storePath, this.moduleName, this.projectName, ...paths); + } + getDeploymentPath(name: string): string { return PATH.join(this.config.storePath, this.projectName, this.moduleName, name); } async getDeploymentContracts(name: string) { - const path = PATH.join(this.getDeploymentPath(name), "contracts.json"); + const path = this.getNewDeploymentPath(name, "contracts.json"); const contracts = await this.backendStorage.load(path); if (!contracts) { return []; @@ -61,7 +65,7 @@ class BaseModule { } async save(name: string, contracts: Record) { - const contractsPath = PATH.join(this.getDeploymentPath(name), "contracts.json"); + const contractsPath = PATH.join(this.getNewDeploymentPath(name), "contracts.json"); const wireguardPath = PATH.join(this.getDeploymentPath(name), `${name}.conf`); const oldContracts = await this.getDeploymentContracts(name); let StoreContracts = oldContracts; @@ -100,8 +104,118 @@ class BaseModule { } } + async _migrateListKeys(): Promise { + const oldPath = this.getDeploymentPath(""); + + const oldKeys = await this.backendStorage.list(oldPath); + if (oldKeys.length === 0) { + return; + } + + const values = await Promise.all( + oldKeys.map(k => + this.backendStorage.load(PATH.join(oldPath, k, "contracts.json")).catch(error => { + console.log(`Error while fetching contarct data PATH[${PATH.join(oldPath, k, "contracts.json")}]`, error); + return null; + }), + ), + ); + + const contracts = await Promise.all( + values.flat(1).map(value => { + if (value) return this.tfClient.contracts.get({ id: value.contract_id }); + return Promise.resolve(null); + }), + ); + + const updateContractsExts: Promise[] = []; + for (const contract of contracts) { + if (!contract) { + continue; + } + + const { nodeContract } = contract.contractType || {}; + if (!nodeContract) { + continue; + } + + const { deploymentData, deploymentHash: hash } = nodeContract; + const oldData = JSON.parse(deploymentData || "{}") as unknown as { + type: string; + name: string; + projectName: string; + }; + const { name, projectName } = oldData; + + let instanceName = name; + + if (this.moduleName === "gateways") { + const [, instance] = name.split(this.config.twinId.toString()); + if (instance) { + instanceName = instance; + } + } + + if (projectName?.endsWith(`/${instanceName}`)) { + continue; + } + + oldData.projectName = `${projectName}/${instanceName}`; + + updateContractsExts.push( + this.tfClient.contracts.updateNode({ + id: contract.contractId, + data: JSON.stringify(oldData), + hash, + }), + ); + } + + const _updateContractsExts = await Promise.all(updateContractsExts.flat(1)); + const __updateContractsExts = _updateContractsExts.flat(1).filter(Boolean); + await this.tfClient.applyAllExtrinsics(__updateContractsExts); + + let ext1: any[] = []; + let ext2: any[] = []; + + for (let i = 0; i < oldKeys.length; i++) { + const oldKey = oldKeys[i]; + + let newKey = oldKey; + if (this.moduleName === "gateways") { + const [, key] = oldKey.split(this.config.twinId.toString()); + if (key) { + newKey = key; + } + } + + const value = values[i]; + const from = PATH.join(oldPath, oldKey, "contracts.json"); + const to = this.getNewDeploymentPath( + ...(this.projectName.includes(newKey) ? [oldKey] : [newKey, oldKey]), + "contracts.json", + ); + + if (value) { + ext1.push(this.backendStorage.dump(to, value)); + ext2.push(this.backendStorage.remove(from)); + } + } + + ext1 = await Promise.all(ext1.flat(1)); + ext2 = await Promise.all(ext2.flat(1)); + + if (this.backendStorage.type === BackendStorageType.tfkvstore) { + ext1 = ext1.flat(1).filter(x => !!x); + ext2 = ext2.flat(1).filter(x => !!x); + + await this.tfClient.applyAllExtrinsics(ext1.concat(ext2)); + } + } + async _list(): Promise { - return await this.backendStorage.list(this.getDeploymentPath("")); + await this._migrateListKeys(); + return this.backendStorage.list(this.getNewDeploymentPath("")); } async exists(name: string): Promise { diff --git a/packages/grid_client/src/storage/backend.ts b/packages/grid_client/src/storage/backend.ts index ab9abd09af..67a1b99c17 100644 --- a/packages/grid_client/src/storage/backend.ts +++ b/packages/grid_client/src/storage/backend.ts @@ -24,7 +24,7 @@ enum BackendStorageType { } class BackendStorage { - storage; + storage: BackendStorageInterface; constructor( public type: BackendStorageType = BackendStorageType.auto, substrateURL = "", @@ -76,8 +76,8 @@ class BackendStorage { return JSON.parse(data.toString()); } - async list(key: string) { - return await this.storage.list(key); + list(key: string): Promise { + return this.storage.list(key); } async remove(key: string) { diff --git a/packages/playground/src/components/domain_name.vue b/packages/playground/src/components/domain_name.vue index 5d2cd2c12e..6c7a28b5c5 100644 --- a/packages/playground/src/components/domain_name.vue +++ b/packages/playground/src/components/domain_name.vue @@ -1,6 +1,6 @@