diff --git a/src/store/cockpitApi.ts b/src/store/cockpitApi.ts index 6691c54ebc..9f6f85e1d3 100644 --- a/src/store/cockpitApi.ts +++ b/src/store/cockpitApi.ts @@ -1,10 +1,15 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; +import TOML from '@ltd/j-toml'; + +import cockpit from 'cockpit'; +import { fsinfo } from 'cockpit/fsinfo'; import { GetArchitecturesApiResponse, GetArchitecturesApiArg, GetBlueprintsApiArg, GetBlueprintsApiResponse, + BlueprintItem, } from './imageBuilderApi'; const emptyCockpitApi = createApi({ @@ -28,22 +33,58 @@ export const cockpitApi = emptyCockpitApi.injectEndpoints({ GetBlueprintsApiResponse, GetBlueprintsApiArg >({ - queryFn: () => { - // TODO: Add cockpit file api support for reading in blueprints. - // For now we're just hardcoding a dummy response - // so we can render an empty table. - return new Promise((resolve) => { - resolve({ + queryFn: async () => { + try { + if (!cockpit) { + throw new Error('Cockpit API is not available'); + } + + const user = await cockpit.user(); + + // we will use the user's `.local` directory + // to save blueprints used for on-prem + // TODO: remove the hardcode + const path = `${user.home}/.local/share/cockpit/image-builder-frontend/blueprints`; + + // we probably don't need any more information other + // than the entries from the directory + const info = await fsinfo(path, ['entries'], { + superuser: 'try', + }); + + const entries = Object.entries(info?.entries || {}); + const blueprints: BlueprintItem[] = await Promise.all( + entries.map(async ([filename, _]) => { + const file = cockpit.file(`${path}/${filename}`); + + const contents = await file.read(); + const parsed = TOML.parse(contents); + file.close(); + + return { + name: parsed.name as string, + id: parsed.version as string, + version: parsed.version as number, + description: parsed.description as string, + last_modified_at: Date.now().toString(), + }; + }) + ); + + return { data: { - meta: { count: 0 }, + meta: { count: blueprints.length }, links: { + // TODO: figure out the pagination first: '', last: '', }, - data: [], + data: blueprints, }, - }); - }); + }; + } catch (error) { + return { error: error.message || 'Unknown error occurred' }; + } }, }), };