Skip to content

Commit

Permalink
feat: add support for Google Cloud Engine image type (#1204)
Browse files Browse the repository at this point in the history
Updates the image builder to a recent image, which includes support for the
Google Cloud Engine (gce) image type.

Adds standard support for this image type to all the standard places in
API/backend/frontend/tests. Using a single PR given how minimal and obvious
the changes are in each part.

Fixes #1175.

Signed-off-by: Tim deBoer <[email protected]>
  • Loading branch information
deboer-tim authored Jan 21, 2025
1 parent 3b767c4 commit ae8d43e
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 18 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Go from a [bootc](https://containers.github.io/bootc/) compatible derived contai
* `anaconda-iso`: Unattended installation method (USB sticks / install-on-boot)
* `vmdk`: Usable in vSphere
* `vhd`: Virtual Hard Disk
* `gce`: Google Cloud Engine

The list above is what is supported by the underlying `bootc-image-builder` technology. The list can [be found here](https://github.com/osbuild/bootc-image-builder?tab=readme-ov-file#-image-types).

Expand Down
22 changes: 13 additions & 9 deletions docs/vm_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ There are **many** solutions to deploy a virtual machine image and this document

## General Solutions

* `qcow`: QEMU is the primary software that utilizes both the QCOW and QCOW2 formats. These formats allow you to create, manage, and run virtual machines with features like better performance and snapshot capabilities. [QEMU](https://www.qemu.org/).
* `raw`: The raw image format is widely supported across many virtualization tools and cloud server providers. Software like KVM, VMware, and cloud platforms including AWS and Azure can utilize raw images. Libvirt, often used with KVM, also supports raw images extensively. [Libvirt](https://libvirt.org/).
* `anaconda-iso`: BalenaEtcher is recommended for writing unattended ISO installer files to storage devices to create bootable media. It's user-friendly and cross-platform. [Download balenaEtcher](https://www.balena.io/etcher/).
* `vmdk`: VMware Workstation and VMware ESXi are two prominent platforms that support the VMDK format. They provide comprehensive tools for running and managing virtual machines. [VMware Workstation](https://www.vmware.com/products/workstation-pro.html), [VMware ESXi](https://www.vmware.com/products/esxi-and-esx.html).
* `ami`: Amazon EC2 uses the AMI format to launch new virtual servers. You can manage AMIs using Amazon's own tools like AWS Management Console. [Amazon EC2](https://aws.amazon.com/ec2/).
* `vhd`: Usable on multiple applications such as Microsoft Hyper-V and Azure.
- `qcow`: QEMU is the primary software that utilizes both the QCOW and QCOW2 formats. These formats allow you to create, manage, and run virtual machines with features like better performance and snapshot capabilities. [QEMU](https://www.qemu.org/).
- `raw`: The raw image format is widely supported across many virtualization tools and cloud server providers. Software like KVM, VMware, and cloud platforms including AWS and Azure can utilize raw images. Libvirt, often used with KVM, also supports raw images extensively. [Libvirt](https://libvirt.org/).
- `anaconda-iso`: BalenaEtcher is recommended for writing unattended ISO installer files to storage devices to create bootable media. It's user-friendly and cross-platform. [Download balenaEtcher](https://www.balena.io/etcher/).
- `vmdk`: VMware Workstation and VMware ESXi are two prominent platforms that support the VMDK format. They provide comprehensive tools for running and managing virtual machines. [VMware Workstation](https://www.vmware.com/products/workstation-pro.html), [VMware ESXi](https://www.vmware.com/products/esxi-and-esx.html).
- `ami`: Amazon EC2 uses the AMI format to launch new virtual servers. You can manage AMIs using Amazon's own tools like AWS Management Console. [Amazon EC2](https://aws.amazon.com/ec2/).
- `vhd`: Usable on multiple applications such as Microsoft Hyper-V and Azure.
- `gce`: Image format used on Google Cloud Engine.

## Recommended Development & Testing

Expand All @@ -35,6 +36,7 @@ brew install qemu

1. Build a RAW image
2. Run the following command:

```sh
# Change to your VM image location
export DISK_IMAGE=/Users/myusername/bootc/image/disk.raw
Expand All @@ -54,6 +56,7 @@ qemu-system-aarch64 \
-drive file=/opt/homebrew/share/qemu/edk2-aarch64-code.fd,format=raw,if=pflash,readonly=on \
-drive file=$DISK_IMAGE,if=virtio,cache=writethrough,format=raw
```

3. `curl` your local port to check VM access `curl localhost:8080`
4. To exit the terminal, type: `Ctrl+a` then `x`

Expand All @@ -74,6 +77,7 @@ brew install vfkit

1. Build a RAW image
2. Run the following command:

```sh
# Change to your VM image location
export DISK_IMAGE=/Users/myusername/bootc/image/disk.raw
Expand All @@ -91,12 +95,10 @@ vfkit --cpus 2 --memory 2048 \
--gui
```


### x86_64 / AMD64 (qemu)

[qemu](https://www.qemu.org/) which emulates the architecture.


**Installation:**

```
Expand All @@ -109,6 +111,7 @@ brew install qemu

1. Build a RAW image
2. Run the following command:

```sh
# Change to your VM image location
export DISK_IMAGE=/Users/myusername/bootc/image/disk.raw
Expand All @@ -123,5 +126,6 @@ qemu-system-x86_64 \
-device virtio-net,netdev=usernet \
-snapshot $DISK_IMAGE
```

3. `curl` your local port to check VM access `curl localhost:8080`
4. To exit the terminal, type: `Ctrl+a` then `x`
4. To exit the terminal, type: `Ctrl+a` then `x`
4 changes: 3 additions & 1 deletion packages/backend/src/build-disk-image.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -45,6 +45,8 @@ export async function buildExists(folder: string, types: BuildType[]) {
imageName = 'bootiso/disk.iso';
} else if (type === 'vhd') {
imageName = 'vpc/disk.vhd';
} else if (type === 'gce') {
imageName = 'gce/image.tar.gz';
}

const imagePath = resolve(folder, imageName);
Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,5 +19,5 @@
// Image related
export const bootcImageBuilder = 'bootc-image-builder';
export const bootcImageBuilderCentos =
'quay.io/centos-bootc/bootc-image-builder:sha256-b4eb0793837e627b5cd08bbb641ddf7f22b013d5d2f4d7d593ca6261f2126550';
'quay.io/centos-bootc/bootc-image-builder:sha256-e53a3916cfc416f00a54a93757d7a48beb1af7fce3a3a329d07a0eea2e2b0737';
export const bootcImageBuilderRHEL = 'registry.redhat.io/rhel9/bootc-image-builder:9.4';
9 changes: 8 additions & 1 deletion packages/frontend/src/Build.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -184,6 +184,13 @@ test('Check that VMDK option is there', async () => {
expect(vmdk).toBeDefined();
});

test('Check that GCE option is there', async () => {
render(Build);

const gce = screen.getByLabelText('gce-checkbox');
expect(gce).toBeDefined();
});

test('Check that preselecting an image works', async () => {
vi.mocked(bootcClient.listHistoryInfo).mockResolvedValue(mockHistoryInfo);
vi.mocked(bootcClient.listBootcImages).mockResolvedValue(mockBootcImages);
Expand Down
6 changes: 6 additions & 0 deletions packages/frontend/src/Build.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,12 @@ $: if (availableArchitectures) {
on:click={e => updateBuildType('vhd', e.detail)}>
Virtual Hard Disk (*.vhd)
</Checkbox>
<Checkbox
checked={buildType.includes('gce')}
title="gce-checkbox"
on:click={e => updateBuildType('gce', e.detail)}>
Google Cloud Engine (*.gce)
</Checkbox>
</div>
</div>
<div>
Expand Down
4 changes: 2 additions & 2 deletions packages/shared/src/models/bootc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,7 +16,7 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

export type BuildType = 'qcow2' | 'ami' | 'raw' | 'vmdk' | 'anaconda-iso' | 'vhd';
export type BuildType = 'qcow2' | 'ami' | 'raw' | 'vmdk' | 'anaconda-iso' | 'vhd' | 'gce';

// Follows https://github.com/osbuild/bootc-image-builder?tab=readme-ov-file#-build-config convention
// users = array
Expand Down
4 changes: 2 additions & 2 deletions tests/playwright/src/bootc-extension.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -132,7 +132,7 @@ test.describe('BootC Extension', () => {
imageBuildFailed = false;
});

const types = ['QCOW2', 'AMI', 'RAW', 'VMDK', 'ISO', 'VHD'];
const types = ['QCOW2', 'AMI', 'RAW', 'VMDK', 'ISO', 'VHD', 'GCE'];

for (const type of types) {
test.describe.serial('Building images ', () => {
Expand Down
10 changes: 9 additions & 1 deletion tests/playwright/src/model/bootc-page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
* Copyright (C) 2024-2025 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -34,6 +34,7 @@ export class BootcPage {
readonly vmdkCheckbox: Locator;
readonly amiCheckbox: Locator;
readonly vhdCheckbox: Locator;
readonly gceCheckbox: Locator;
readonly amd64Button: Locator;
readonly arm64Button: Locator;
readonly buildButton: Locator;
Expand All @@ -58,6 +59,7 @@ export class BootcPage {
this.vmdkCheckbox = webview.getByLabel('vmdk-checkbox');
this.amiCheckbox = webview.getByLabel('ami-checkbox');
this.vhdCheckbox = webview.getByLabel('vhd-checkbox');
this.gceCheckbox = webview.getByLabel('gce-checkbox');
this.amd64Button = webview.getByLabel('amd64-button');
this.arm64Button = webview.getByLabel('arm64-button');
this.bootcListPage = webview.getByRole('region', { name: 'Bootable Containers', exact: true });
Expand Down Expand Up @@ -123,6 +125,10 @@ export class BootcPage {
await this.vhdCheckbox.check();
await playExpect(this.vhdCheckbox).toBeChecked();
break;
case 'gce':
await this.gceCheckbox.check();
await playExpect(this.gceCheckbox).toBeChecked();
break;
default:
throw new Error(`Unknown type: ${type}`);
}
Expand Down Expand Up @@ -179,6 +185,8 @@ export class BootcPage {
await playExpect(this.amiCheckbox).not.toBeChecked();
await this.vhdCheckbox.uncheck();
await playExpect(this.vhdCheckbox).not.toBeChecked();
await this.gceCheckbox.uncheck();
await playExpect(this.gceCheckbox).not.toBeChecked();
}

async getCurrentStatusOfLatestEntry(): Promise<string> {
Expand Down

0 comments on commit ae8d43e

Please sign in to comment.