Skip to content

Commit

Permalink
feat: basic telemetry
Browse files Browse the repository at this point in the history
Logs an event whenever users with telemetry enabled do a build or try to
launch vfkit, with basic anonymous details. We need to see what data this
produces and it will clearly need to change as we evolve the extension,
but gives us a basic view for now.

Fixes #23.

Signed-off-by: Tim deBoer <[email protected]>
  • Loading branch information
deboer-tim committed Jan 15, 2024
1 parent ef49fb8 commit ec0042b
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const bootcImageBuilderContainerName = '-bootc-image-builder';
const bootcImageBuilderName = 'quay.io/centos-bootc/bootc-image-builder:latest-1704948606';
let diskImageBuildingName: string;

const telemetryLogger = extensionApi.env.createTelemetryLogger();

export async function activate(extensionContext: ExtensionContext): Promise<void> {
bootc = new BootC(extensionContext);
await bootc?.activate();
Expand All @@ -38,43 +40,58 @@ export async function activate(extensionContext: ExtensionContext): Promise<void
let imageLocation = container.labels['bootc.build.image.location'];

// Check that vfkit is installed and error if it isn't before executing
const telemetryData: Record<string, any> = {};
telemetryData.imageType = container.labels['bootc.build.type'];
try {
await extensionApi.process.exec('vfkit', ['--version']);
} catch (error) {
await extensionApi.window.showErrorMessage(`Unable to launch ${imageLocation} with vfkit: ${error}`);
telemetryData.error = 'no-version';
telemetryLogger.logUsage('launchVfkit', telemetryData);
return;
}

// Check to see if imageLocation exists and error if it doesn't before executing
if (!fs.existsSync(imageLocation)) {
await extensionApi.window.showErrorMessage(`Unable to launch ${imageLocation} with vfkit: ${imageLocation} does not exist`);
telemetryData.error = 'no-image';
telemetryLogger.logUsage('launchVfkit', telemetryData);
return;
}

// Check container.labels['bootc.build.type'] to see if it is ami or raw
// if it is not raw or ami, we cannot launch with vfkit
if (container.labels['bootc.build.type'] !== 'ami' && container.labels['bootc.build.type'] !== 'raw') {
await extensionApi.window.showErrorMessage(`Unable to launch ${imageLocation} with vfkit: ${container.labels['bootc.build.type']} is not supported`);
telemetryData.error = 'unsupported-type';
telemetryLogger.logUsage('launchVfkit', telemetryData);
return;
}

await launchVfkit(imageLocation);
await launchVfkit(imageLocation, telemetryData);
}),

extensionApi.commands.registerCommand('bootc.image.build', async image => {
const telemetryData: Record<string, any> = {};

const selectedType = await extensionApi.window.showQuickPick(['qcow2', 'ami', 'raw', 'iso'], {
placeHolder: 'Select image type',
});
if (!selectedType) {
telemetryData.canceled = true;
telemetryLogger.logUsage('buildDiskImage', telemetryData);
return;
}
telemetryData.imageType = selectedType;

const selectedFolder = await extensionApi.window.showInputBox({
prompt: 'Select the folder to generate disk' + selectedType + ' into',
value: os.homedir(),
ignoreFocusOut: true,
});
if (!selectedFolder) {
telemetryData.canceled = true;
telemetryLogger.logUsage('buildDiskImage', telemetryData);
return;
}
// Make this into a map that 'qcow2' -> 'disk.qcow2'
Expand All @@ -99,6 +116,9 @@ export async function activate(extensionContext: ExtensionContext): Promise<void
'No',
)) === 'No'
) {
telemetryData.overwrite = true;
telemetryData.canceled = true;
telemetryLogger.logUsage('buildDiskImage', telemetryData);
return;
}

Expand Down Expand Up @@ -156,20 +176,24 @@ export async function activate(extensionContext: ExtensionContext): Promise<void
successful = true;

fs.writeFileSync(logPath, logData, { flag: 'w' });
telemetryData.success = true;
} catch (error) {
console.error(error);
try {
fs.writeFileSync(logPath, logData, { flag: 'w' });
} catch (e) {
// ignore
}
telemetryData.error = error;
await extensionApi.window.showErrorMessage(
`Unable to build disk image: ${error}. Check logs at ${logPath}`,
);
}

// Mark the task as completed
progress.report({ increment: -1 });

telemetryLogger.logUsage('buildDiskImage', telemetryData);

// Only if success = true and type = ami
if ((successful && selectedType === 'ami') || selectedType === 'raw') {
Expand All @@ -185,7 +209,7 @@ export async function activate(extensionContext: ExtensionContext): Promise<void
);
}

async function launchVfkit(imagePath: string): Promise<void> {
async function launchVfkit(imagePath: string, telemetryData: Record<string, any>): Promise<void> {
// take image path replace last part (disk.qcow2 / disk.raw) with vfkit-serial.log
// this will be the log file path
const logFilePath = imagePath.replace(/[^/]+$/, '') + 'vfkit-serial.log';
Expand Down Expand Up @@ -216,8 +240,12 @@ async function launchVfkit(imagePath: string): Promise<void> {
console.log(args);
try {
await extensionApi.process.exec(command, args);
telemetryData.success = true;
telemetryLogger.logUsage('launchVfkit', telemetryData);
} catch (error) {
console.error(error);
telemetryData.error = error;
telemetryLogger.logUsage('launchVfkit', telemetryData);
await extensionApi.window.showErrorMessage(`Unable to launch ${imagePath} with vfkit: ${error}`);
}
}
Expand Down

0 comments on commit ec0042b

Please sign in to comment.