diff --git a/api/README.md b/api/README.md index c61219a4..8e8e9aea 100644 --- a/api/README.md +++ b/api/README.md @@ -2,18 +2,27 @@ This API is a Node.js server that will be running on a Linux VM. -It is composed of one endpoint: - -- `/sconify`: - - - Takes a public dockerhub image as input and a user auth token with push - access to the image's repo in order to push the sconified image, - - builds a sconified image out of it, - - publishes it to dockerhub with tag suffix, - - deploys an app contract on Bellecour. - -- `/` or any other endpoint: will return a simple text (mostly to check if the - server is running) +The API is composed of: + +- HTTP endpoints: + + - 🟢 `GET /`: will return a simple text (mostly to check if the server is + running) + - 🟢 `GET /health`: will return a JSON object with the health status of the + server and the version of the API. + - 🟠 `POST /sconify`: deprecated, use Websocket API request `SCONIFY_BUILD` + instead. + - 🟠 `POST /sconify/build`: deprecated, use Websocket API request + `SCONIFY_BUILD` instead. + +- Websocket API requests: + - 🟢 `SCONIFY_BUILD`: will take a dockerhub image and return a + `sconifiedImage` and `appContractAddress` in the response. + - Takes a public dockerhub image as input and a user auth token with push + access to the image's repo in order to push the sconified image + - builds a sconified image out of it + - publishes it to dockerhub with tag suffix + - 🟠 `SCONIFY`: deprecated, use `SCONIFY_BUILD` instead. ## Prerequisites @@ -41,3 +50,14 @@ npm run start ```sh npm run dev:pretty ``` + +## deprecations + +- `POST /sconify` is deprecated, websocket API request `SCONIFY_BUILD` should be + used instead. +- `POST /sconify/build` is deprecated, websocket API request `SCONIFY_BUILD` + should be used instead. +- websocket API request `SCONIFY` is deprecated, websocket API request + `SCONIFY_BUILD` should be used instead. +- template `Python` is deprecated, template `Python3.13` should be used instead. +- sconeVersion `v5` is deprecated, sconeVersion `v5.9` should be used instead. diff --git a/api/src/constants/constants.ts b/api/src/constants/constants.ts index 76ac8a81..3a365b71 100644 --- a/api/src/constants/constants.ts +++ b/api/src/constants/constants.ts @@ -33,14 +33,14 @@ export const TEMPLATE_CONFIG: Record< JavaScript: { // node binary name does not change from one version to another binary: '/usr/local/bin/node', - // for scone 5.7 this was necessary + // deprecated for scone 5.7 this was necessary sconeCuratedImage: 'registry.scontain.com:5050/sconecuratedimages/node:14.4.0-alpine3.11', }, 'Python3.13': { binary: '/usr/local/bin/python3.13', }, - // legacy template name Python used Python 3.8 + // deprecated legacy template name Python used Python 3.8 Python: { binary: '/usr/local/bin/python3.8', }, diff --git a/api/src/index.ts b/api/src/index.ts index c73143c1..c63d4b3e 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -10,7 +10,7 @@ import { requestIdMiddleware } from './utils/requestId.js'; import { errorHandlerMiddleware } from './utils/errors.js'; import { attachWebSocketServer } from './utils/websocket.js'; import { - sconifyBuildHttpHandler, + deprecated_sconifyBuildHttpHandler, sconifyBuildWsHandler, } from './sconify/sconifyBuild.handler.js'; @@ -34,7 +34,7 @@ app.use(loggerMiddleware); // deprecated endpoint, clients should use /sconify/build app.post('/sconify', deprecated_sconifyHttpHandler); -app.post('/sconify/build', sconifyBuildHttpHandler); +app.post('/sconify/build', deprecated_sconifyBuildHttpHandler); // Health endpoint app.get('/health', (req, res) => { diff --git a/api/src/sconify/deprecated_sconify.handler.ts b/api/src/sconify/deprecated_sconify.handler.ts index 1d5aa2af..f3a4b0e4 100644 --- a/api/src/sconify/deprecated_sconify.handler.ts +++ b/api/src/sconify/deprecated_sconify.handler.ts @@ -4,6 +4,7 @@ import { TEMPLATE_CONFIG, type TemplateName } from '../constants/constants.js'; import { ethereumAddressZodSchema } from '../utils/ethereumAddressZodSchema.js'; import { deprecated_sconify } from './deprecated_sconify.service.js'; import type { Request, Response } from 'express'; +import { logger } from '../utils/logger.js'; const bodySchema = z.object({ yourWalletPublicAddress: ethereumAddressZodSchema, @@ -25,7 +26,7 @@ const bodySchema = z.object({ .default('JavaScript'), }); -async function handleSconifyRequest(requestObj: object) { +async function deprecated_handleSconifyRequest(requestObj: object) { let yourWalletPublicAddress; let dockerhubImageToSconify; let dockerhubPushToken; @@ -54,8 +55,9 @@ async function handleSconifyRequest(requestObj: object) { } export async function deprecated_sconifyWsHandler(message: object) { + logger.warn('deprecated feature hit: ws request SCONIFY'); const { sconifiedImage, appContractAddress } = - await handleSconifyRequest(message); + await deprecated_handleSconifyRequest(message); return { sconifiedImage, appContractAddress }; } @@ -63,9 +65,9 @@ export async function deprecated_sconifyHttpHandler( req: Request, res: Response ) { - const { sconifiedImage, appContractAddress } = await handleSconifyRequest( - req.body || {} - ); + logger.warn('deprecated feature hit: POST /sconify'); + const { sconifiedImage, appContractAddress } = + await deprecated_handleSconifyRequest(req.body || {}); res.status(200).json({ success: true, sconifiedImage, diff --git a/api/src/sconify/sconifyBuild.handler.ts b/api/src/sconify/sconifyBuild.handler.ts index 2bdf0e1b..4e35e523 100644 --- a/api/src/sconify/sconifyBuild.handler.ts +++ b/api/src/sconify/sconifyBuild.handler.ts @@ -8,6 +8,7 @@ import { import { ethereumAddressZodSchema } from '../utils/ethereumAddressZodSchema.js'; import { sconify } from './sconifyBuild.service.js'; import type { Request, Response } from 'express'; +import { logger } from '../utils/logger.js'; const bodySchema = z.object({ yourWalletPublicAddress: ethereumAddressZodSchema, @@ -51,6 +52,13 @@ async function handleSconifyRequest(requestObj: object) { }), }); } + if (template === 'Python') { + logger.warn('Deprecated feature hit: template === "Python"'); + } + if (sconeVersion === 'v5') { + logger.warn('Deprecated feature hit: sconeVersion === "v5"'); + } + const { dockerImage, dockerImageDigest, fingerprint, entrypoint } = await sconify({ dockerImageToSconify: dockerhubImageToSconify, @@ -85,7 +93,11 @@ export async function sconifyBuildWsHandler(message: object) { }; } -export async function sconifyBuildHttpHandler(req: Request, res: Response) { +export async function deprecated_sconifyBuildHttpHandler( + req: Request, + res: Response +) { + logger.warn('Deprecated feature hit: POST /sconify/build'); const { dockerImage, dockerImageDigest, diff --git a/cli/src/config/config.ts b/cli/src/config/config.ts index 50660653..94c47015 100644 --- a/cli/src/config/config.ts +++ b/cli/src/config/config.ts @@ -3,7 +3,6 @@ import { useExperimentalNetworks } from '../utils/featureFlags.js'; export const SCONE_TAG = ['tee', 'scone']; export const DEFAULT_SCONE_VERSION = 'v5.9'; -export const SCONIFY_API_HTTP_URL = 'https://iapp-api.iex.ec'; export const SCONIFY_API_WS_URL = 'wss://iapp-api.iex.ec'; export const CONFIG_FILE = 'iapp.config.json'; diff --git a/cli/src/utils/featureFlags.ts b/cli/src/utils/featureFlags.ts index 87813047..8d4da2e7 100644 --- a/cli/src/utils/featureFlags.ts +++ b/cli/src/utils/featureFlags.ts @@ -1,6 +1,5 @@ import chalk from 'chalk'; -export const useWsApi = checkFlag('EXPERIMENTAL_WS_API'); export const useTdx = checkFlag('EXPERIMENTAL_TDX_APP'); export const useExperimentalNetworks = checkFlag('EXPERIMENTAL_NETWORKS'); diff --git a/cli/src/utils/sconify.ts b/cli/src/utils/sconify.ts index 464ff000..2a31f17b 100644 --- a/cli/src/utils/sconify.ts +++ b/cli/src/utils/sconify.ts @@ -1,8 +1,4 @@ -import { - DEFAULT_SCONE_VERSION, - SCONIFY_API_HTTP_URL, - SCONIFY_API_WS_URL, -} from '../config/config.js'; +import { DEFAULT_SCONE_VERSION, SCONIFY_API_WS_URL } from '../config/config.js'; import { getAuthToken } from './dockerhub.js'; import { sleep } from './sleep.js'; import { @@ -11,7 +7,6 @@ import { serializeData, } from './websocket.js'; import { debug } from './debug.js'; -import { useWsApi } from './featureFlags.js'; const INITIAL_RETRY_PERIOD = 20 * 1000; // 20s @@ -56,133 +51,86 @@ export async function sconify({ const pushToken = await getPushToken(); - let sconifyResult: { + const sconifyResult: { dockerImage?: string; dockerImageDigest?: string; entrypoint?: string; fingerprint?: string; sconeVersion?: string; - }; - - if (useWsApi) { - // experimental ws connection - sconifyResult = await new Promise((resolve, reject) => { - createReconnectingWs(SCONIFY_API_WS_URL, { - headers: { - 'x-wallet': walletAddress, - }, - connectCallback: (ws) => { - const handleError = (e: unknown) => { - ws.close(1000); // normal ws close - reject(e); - }; + } = await new Promise((resolve, reject) => { + createReconnectingWs(SCONIFY_API_WS_URL, { + headers: { + 'x-wallet': walletAddress, + }, + connectCallback: (ws) => { + const handleError = (e: unknown) => { + ws.close(1000); // normal ws close + reject(e); + }; - ws.on('message', (data) => { - let message; - // handle communication errors - try { - message = deserializeData(data); - debug(`ws message: ${JSON.stringify(message, undefined, 2)}`); - } catch (e) { - handleError(e); - } + ws.on('message', (data) => { + let message; + // handle communication errors + try { + message = deserializeData(data); + debug(`ws message: ${JSON.stringify(message, undefined, 2)}`); + } catch (e) { + handleError(e); + } - // handle server responses - if (message?.type === 'RESPONSE') { - if (message?.target === 'SCONIFY_BUILD') { - ws.close(1000); // normal ws close - if (message?.success === true && message.result) { - resolve(message.result); - } else { - reject(Error(message.error || 'Server unknown error')); - } + // handle server responses + if (message?.type === 'RESPONSE') { + if (message?.target === 'SCONIFY_BUILD') { + ws.close(1000); // normal ws close + if (message?.success === true && message.result) { + resolve(message.result); + } else { + reject(Error(message.error || 'Server unknown error')); } } + } - // handle server requests - if (message?.type === 'REQUEST') { - if (message?.target === 'RENEW_PUSH_TOKEN') { - getPushToken() - .then((renewedPushToken) => { - ws.send( - serializeData({ - type: 'RESPONSE', - target: 'RENEW_PUSH_TOKEN', - result: { - dockerhubPushToken: renewedPushToken, - }, - }) - ); - }) - .catch(handleError); - } + // handle server requests + if (message?.type === 'REQUEST') { + if (message?.target === 'RENEW_PUSH_TOKEN') { + getPushToken() + .then((renewedPushToken) => { + ws.send( + serializeData({ + type: 'RESPONSE', + target: 'RENEW_PUSH_TOKEN', + result: { + dockerhubPushToken: renewedPushToken, + }, + }) + ); + }) + .catch(handleError); } + } - // handle server info - if (message?.type === 'INFO') { - // TODO server feedback - } - }); - }, - initCallback: (ws) => { - ws.send( - serializeData({ - type: 'REQUEST', - target: 'SCONIFY_BUILD', // call sconify handler - template, - dockerhubImageToSconify: iAppNameToSconify, - dockerhubPushToken: pushToken, - yourWalletPublicAddress: walletAddress, - sconeVersion: DEFAULT_SCONE_VERSION, - }) - ); - }, - errorCallback: reject, - }); - }); - } else { - // standard http call - sconifyResult = await fetch(`${SCONIFY_API_HTTP_URL}/sconify/build`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'x-wallet': walletAddress, + // handle server info + if (message?.type === 'INFO') { + // TODO server feedback + } + }); }, - body: JSON.stringify({ - template, - dockerhubImageToSconify: iAppNameToSconify, - dockerhubPushToken: pushToken, // used for pushing sconified image on user repo - yourWalletPublicAddress: walletAddress, - sconeVersion: DEFAULT_SCONE_VERSION, - }), - }) - .catch(() => { - throw Error("Can't reach TEE transformation server!"); - }) - .then((res) => { - if (res.ok) { - return res.json().catch(() => { - // failed to parse body - throw Error('Unexpected server response'); - }); - } - if (res.status === 429) { - throw new TooManyRequestsError( - 'TEE transformation server is busy, retry later' - ); - } - // try getting error message from json body - return res - .json() - .catch(() => { - // failed to parse body - throw Error('Unknown server error'); + initCallback: (ws) => { + ws.send( + serializeData({ + type: 'REQUEST', + target: 'SCONIFY_BUILD', // call sconify handler + template, + dockerhubImageToSconify: iAppNameToSconify, + dockerhubPushToken: pushToken, + yourWalletPublicAddress: walletAddress, + sconeVersion: DEFAULT_SCONE_VERSION, }) - .then(({ error }) => { - throw Error(error || 'Unknown server error'); - }); - }); - } + ); + }, + errorCallback: reject, + }); + }); // Extract necessary information if (!sconifyResult.dockerImage) {