@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
156 lines (137 loc) • 4.77 kB
text/typescript
import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
import chalk from 'chalk';
import * as yaml from 'js-yaml';
import { getPluginPath, getPluginInfo } from './plugin.js';
import { getOwnerAndRepo } from './github.js';
interface ArtifactHubConfig {
version: string;
name: string;
displayName: string;
createdAt?: string;
logoURL?: string;
description: string;
annotations: {
'headlamp/plugin/archive-url': string;
'headlamp/plugin/archive-checksum': string;
'headlamp/plugin/version-compat'?: string;
'headlamp/plugin/distro-compat'?: string;
};
}
/**
* Calculate SHA256 checksum of a file
*/
function calculateChecksum(filePath: string): string {
const fileBuffer = fs.readFileSync(filePath);
const hashSum = crypto.createHash('sha256');
hashSum.update(fileBuffer);
return hashSum.digest('hex');
}
/**
* Check if plugin has an artifacthub-pkg.yml file
*/
export function hasArtifactHubFile(pluginName: string): boolean {
const pluginPath = getPluginPath(pluginName);
const artifactHubPath = path.join(pluginPath, 'artifacthub-pkg.yml');
return fs.existsSync(artifactHubPath);
}
/**
* Get the path to the artifacthub-pkg.yml file for a plugin
*/
export function getArtifactHubPath(pluginName: string): string {
const pluginPath = getPluginPath(pluginName);
return path.join(pluginPath, 'artifacthub-pkg.yml');
}
/**
* Read and parse the artifacthub-pkg.yml file
*/
export function readArtifactHubConfig(pluginName: string): ArtifactHubConfig | null {
if (!hasArtifactHubFile(pluginName)) {
return null;
}
const artifactHubPath = getArtifactHubPath(pluginName);
try {
const content = fs.readFileSync(artifactHubPath, 'utf-8');
return yaml.load(content) as ArtifactHubConfig;
} catch (error) {
console.error(chalk.red(`Error reading artifacthub-pkg.yml for ${pluginName}:`));
console.error(error);
return null;
}
}
/**
* Update the artifacthub-pkg.yml file with new version and tarball information
*/
export function updateArtifactHubConfig(
pluginName: string,
version: string,
tarballPath: string
): void {
const artifactHubPath = getArtifactHubPath(pluginName);
const pluginInfo = getPluginInfo(getPluginPath(pluginName));
const { owner, repo } = getOwnerAndRepo();
// Calculate checksum of the tarball
const checksum = calculateChecksum(tarballPath);
const tarballName = path.basename(tarballPath);
// Generate the GitHub release URL
const archiveUrl = `https://github.com/${owner}/${repo}/releases/download/${pluginName}-${version}/${tarballName}`;
let config: ArtifactHubConfig;
if (hasArtifactHubFile(pluginName)) {
// Update existing config
config = readArtifactHubConfig(pluginName)!;
config.version = version;
config.annotations['headlamp/plugin/archive-url'] = archiveUrl;
config.annotations['headlamp/plugin/archive-checksum'] = `SHA256:${checksum}`;
} else {
// Create new config
config = {
version,
name: `headlamp_${pluginName.replace(/-/g, '_')}`,
displayName: pluginInfo.name,
description: `Headlamp plugin: ${pluginInfo.name}`,
annotations: {
'headlamp/plugin/archive-url': archiveUrl,
'headlamp/plugin/archive-checksum': `SHA256:${checksum}`,
'headlamp/plugin/version-compat': '>=0.22',
'headlamp/plugin/distro-compat': 'in-cluster,web,docker-desktop,desktop'
}
};
}
// Write the updated config
const yamlContent = yaml.dump(config, {
indent: 2,
quotingType: '"',
forceQuotes: false
});
fs.writeFileSync(artifactHubPath, yamlContent);
}
/**
* Create a template artifacthub-pkg.yml file for a plugin
*/
export function createArtifactHubTemplate(pluginName: string): void {
const artifactHubPath = getArtifactHubPath(pluginName);
const pluginInfo = getPluginInfo(getPluginPath(pluginName));
if (fs.existsSync(artifactHubPath)) {
throw new Error(`artifacthub-pkg.yml already exists for ${pluginName}`);
}
const template: Partial<ArtifactHubConfig> = {
version: pluginInfo.version,
name: `headlamp_${pluginName.replace(/-/g, '_')}`,
displayName: pluginInfo.name,
createdAt: new Date().toISOString(),
description: `Headlamp plugin: ${pluginInfo.name}`,
annotations: {
'headlamp/plugin/archive-url': 'TBD - will be updated during release',
'headlamp/plugin/archive-checksum': 'TBD - will be updated during release',
'headlamp/plugin/version-compat': '>=0.22',
'headlamp/plugin/distro-compat': 'in-cluster,web,docker-desktop,desktop'
}
};
const yamlContent = yaml.dump(template, {
indent: 2,
quotingType: '"',
forceQuotes: false
});
fs.writeFileSync(artifactHubPath, yamlContent);
}