Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add source_image to disk_attachment #196

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

adsr
Copy link

@adsr adsr commented Oct 30, 2023

Add ability to specify a source_image in a disk_attachment.

Relevant excerpt from GCP godocs:

	// SourceImage: The source image to create this disk. When creating a
	// new instance, one of initializeParams.sourceImage or
	// initializeParams.sourceSnapshot or disks.source is required except
	// for local SSD.
@adsr adsr requested a review from a team as a code owner October 30, 2023 21:52
@hashicorp-cla
Copy link

hashicorp-cla commented Oct 30, 2023

CLA assistant check
All committers have signed the CLA.

Copy link
Contributor

@lbajolet-hashicorp lbajolet-hashicorp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @adsr,

Thanks for the feature! The code looks good to me, I left a couple of questions, but overall this looks good to me.

Just to be sure, have you tested the feature? We should probably add some acceptance test for this, I can take care of it since we'll run them on our accounts, could I ask you to share some template I can take inspiration from in order to write this?

Out of curiosity, this looks like this is essentially for pre-populating extra drives with images, may I ask you what you're using this feature for?

I'll come back later to approve it and possibly write the acceptance test.

@@ -196,7 +204,7 @@ func (bd *BlockDevice) prepareDiskCreate() []error {
errs = append(errs, fmt.Errorf("Scratch volumes cannot have a name specified."))
}

if bd.VolumeSize == 0 {
if bd.VolumeSize == 0 && bd.SourceImage == "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder, any chance we can validate the volume's size is large enough to accomodate the image?

Copy link
Author

@adsr adsr Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't traced how or where this happens but VolumeSize appears to be ignored when specifiying a SourceImage.

EDIT: It only appeared that way because it was making a 3rd disk (see #196 (comment)). The API actually throws an error if the disk is too small:

==> googlecompute.chef: failed to create disk: googleapi: Error 400: Invalid value for field 'resource.sizeGb': '1'. Requested disk size cannot be smaller than the image size (20 GB), invalid

It seems fine to me to rely on the API. Would you prefer to raise an error ahead of time? I imagine we'd fetch metadata of the source image to figure out its size in order to compare.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relying on the API is sound indeed. We should probably warn in the docs so that users are aware they have to set the size and that they need to ensure the disk is larger than the base image.

Is the error clearly presented to the user? Or is the excerpt you shared from appears in the verbose logs only?
If it's the latter, we should probably figure out a way to return it clearly, otherwise it looks good to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if I'm wrong then, but if we specify a source image, we have to specify the disk size as well, correct? If so this check is not valid anymore

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we specify a source image, we have to specify the disk size as well, correct?

It's still optional I believe. Disk size defaults to the image size if you don't specify it (i.e., 0) which I think is desirable the majority of the time. Here are Google's docs for DiskSizeGb:

Specifies the size of the disk in base-2 GB. The size must be at least 10 GB. If you specify a sourceImage, which is required for boot disks, the default size is the size of the sourceImage. If you do not specify a sourceImage, the default disk size is 500 GB.

Is the error clearly presented to the user?

I think this was without debug logs. I will double check and get back to you to confirm.

builder/googlecompute/block_device.go Show resolved Hide resolved
Copy link
Author

@adsr adsr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thanks for the review.

Just to be sure, have you tested the feature?
Out of curiosity, this looks like this is essentially for pre-populating extra drives with images, may I ask you what you're using this feature for?

Yes, we've tested the feature. We intend to use this in conjunction with #190 to modify a bootable OS image without actually booting it. Booting an image and modifying it in place causes side effects which we need to avoid. So we mount the image as an extra disk (this PR), mount and modify it at runtime, and tell Packer to re-image the extra disk (#190).

could I ask you to share some template I can take inspiration from in order to write this?

I'll get back to you on that.

@@ -196,7 +204,7 @@ func (bd *BlockDevice) prepareDiskCreate() []error {
errs = append(errs, fmt.Errorf("Scratch volumes cannot have a name specified."))
}

if bd.VolumeSize == 0 {
if bd.VolumeSize == 0 && bd.SourceImage == "" {
Copy link
Author

@adsr adsr Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't traced how or where this happens but VolumeSize appears to be ignored when specifiying a SourceImage.

EDIT: It only appeared that way because it was making a 3rd disk (see #196 (comment)). The API actually throws an error if the disk is too small:

==> googlecompute.chef: failed to create disk: googleapi: Error 400: Invalid value for field 'resource.sizeGb': '1'. Requested disk size cannot be smaller than the image size (20 GB), invalid

It seems fine to me to rely on the API. Would you prefer to raise an error ahead of time? I imagine we'd fetch metadata of the source image to figure out its size in order to compare.

builder/googlecompute/block_device.go Show resolved Hide resolved
@adsr
Copy link
Author

adsr commented Nov 8, 2023

Here's a barebones template that illustrates what we're going for.

source "googlecompute" "image_extra_disk" {
  project_id = var.gcp_project_id
  zone = var.gcp_zone

  source_image_family = var.source_image_family

  image_name = var.image_name
  
  disk_attachment {                     
    disk_name = "extra-disk"                                
    device_name = "extra_disk"
    source_image = var.extra_disk_source_image_family
    volume_type = "pd-standard"
  }                   
                 
  image_source_disk = "extra-disk"
}
@adsr adsr marked this pull request as draft November 8, 2023 20:54
@adsr
Copy link
Author

adsr commented Nov 8, 2023

I've noticed it's actually creating 3 disks, the boot disk, an extra disk, and then a 3rd disk with the image. Need to fix this up. Converted to draft for now.

EDIT: Force-pushed to 689fc55. Now creating just 2 just disks as expected.

@adsr adsr force-pushed the disk_source_image branch 2 times, most recently from f1ea966 to 689fc55 Compare November 9, 2023 20:18
@adsr adsr marked this pull request as ready for review November 9, 2023 20:22
@adsr
Copy link
Author

adsr commented Nov 14, 2023

Copy link
Contributor

@lbajolet-hashicorp lbajolet-hashicorp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @adsr,

Thanks for the rerolls, I left a couple nits, but overall this looks good to me!
I pushed a refactor for the common code recently which conflicts with your PR, let me know if you need a hand to rebase that, but other than that, we're good for a merge soon.

DeviceName: "packer-test",
InitializeParams: &compute.AttachedDiskInitializeParams{
DiskName: "packer-test-disk",
SourceImage: "projects/p/global/images/family/f",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised we need to define the SourceImage for both the BlockDevice and the AttachedDisk objects, is this required?

SourceImage: bd.SourceImage,
}
} else {
disk.Source = bd.SourceVolume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the SourceVolume and the SourceImage are mutually exclusive, I believe this can remain part of the definition for the AttachedDisk?

@nywilken
Copy link
Member

Hi @adsr thanks for your help in pushing this enhancement forward. It looks like there were just a few suggestions left to address with a rebase to resolve conflicts.

Are you still interested in pushing this PR forward?

@uriyyo
Copy link

uriyyo commented Jun 6, 2024

Hi @adsr @lbajolet-hashicorp,

We would like to use this feature in our project. Is there smth we can help with? In case we are stuck with this PR, we can open an alternative PR with this feature.

Please, let me know if there is smth we can help with ���

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants