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

buildsys: add feature to vendor go modules #2053

Closed

Conversation

samuelkarp
Copy link
Contributor

Issue number:
#2052

Description of changes:
This pull request implements Option C in #2052: changes to buildsys that enable automatic Go module downloads ahead of the rpmbuild invocation.

Testing done:

cargo make -e PACKAGE=oci-add-hooks build-package
cargo make -e PACKAGE=hotdog build-package
cargo make -e BUILDSYS_VARIANT=aws-ecs-1

Launch an aws-ecs-1 AMI, verify that oci-add-hooks are built properly and have dependency licenses in /usr/share/licenses

Terms of contribution:

By submitting this pull request, I agree that this contribution is dual-licensed under the terms of both the Apache License, version 2.0, and the MIT license.

Copy link
Contributor

@etungsten etungsten left a comment

Choose a reason for hiding this comment

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

This is awesome! Thanks!!

@samuelkarp
Copy link
Contributor Author

samuelkarp force-pushed the buildsys-go-modules branch from 65bd339 to a7b439a

Added .gitignore files to the packages for the src/ directory that gets created during build.

packages/hotdog/hotdog.spec Show resolved Hide resolved
Comment on lines +15 to +18
[[package.metadata.build-package.go-mods]]
input = "hotdog-3f2ca92.tar.gz"
mod-dir = "hotdog-3f2ca9275fae8db87409c3a0999aa2c8a4bd44d1"
output-dir = "src"
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd tend to prefer coming up with some standard contract and automating that in a way that's easy for spec files to consume, so there's less risk of each spec doing things in slightly different ways, which tends to obscure packaging mistakes.

Specifically, if instead of an output dir we created a tarball, then we could reference that archive in the spec file in the usual way - listing it as a Source, and using the %setup or %autosetup macro. The latter would be valuable for any patches we'd carry. There's also a modest performance benefit from not having lots of small files to copy into the build context.

Then we could specify the behavior into the external-files declaration like:

[[package.metadata.build-package.external-files]]
url = "https://github.com/bottlerocket-os/hotdog/archive/3f2ca9275fae8db87409c3a0999aa2c8a4bd44d1/hotdog-3f2ca92.tar.gz"
path = "override-upstream.tar.gz"
sha512 = "ebf8f2f8f2c7b12443eae5eccdf0d37724637ac972874b9a88eb8d21d88cbe661b0b53680015ebb8c06e17bde708acf90f39fac82002a4c72266ecdac87c3fb5"
bundle-modules = [ "go" ]
bundle-path = "override-upstream-bundled.tar.gz"

(Not entirely sure about what to name the output file but there's probably an automatic convention like x.tar.* -> x-bundled.tar.* that we could use.)

What do you think?

%cross_go_configure %{goimport}
# We use `GO111MODULE=off` to force golang to look for the dependencies in the GOPATH
GO111MODULE=off go build -v -x -buildmode=pie -ldflags="${GOLDFLAGS}" -o oci-add-hooks
%set_cross_go_flags
Copy link
Contributor

Choose a reason for hiding this comment

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

Awesome! It'll be really nice to get rid of cross_go_setup and cross_go_configure at some point.

Comment on lines +164 to +166
if let Some(mods) = manifest.go_mods() {
GoMod::vendor(&root_dir, &manifest_dir, &mods).context(error::GoModSnafu)?;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to emit cargo:rerun-if-changed directives for the output files, or tarball if we switch to that.

Comment on lines +15 to +16
#[snafu(display("input must be a file and end with .tar.gz"))]
InputFileBad,
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: we don't seem to check for the "ends with .tar.gz" part (and might not want to, since other compression formats might be used)

Comment on lines +76 to +79
match docker_go(root_dir, &args) {
Ok(_) => continue,
Err(e) => return Err(e),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This can be written more concisely as:

Suggested change
match docker_go(root_dir, &args) {
Ok(_) => continue,
Err(e) => return Err(e),
}
let _ = docker_go(root_dir, &args)?;

(Might be able to get rid of the let _ = part also.)

root_dir: &PathBuf,
package_dir: &PathBuf,
gomods: &[manifest::GoModule],
) -> Result<Self> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like you can just return nothing in the happy case:

Suggested change
) -> Result<Self> {
) -> Result<()> {

Comment on lines +97 to +101
dg_args
.module_path
.to_str()
.context(error::InputFileSnafu)
.unwrap(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm why do we still need to unwrap() here?

Generally that would mean that we would add another .context(error::WhateverSnafu) to the chain.

Comment on lines +124 to +130
return if output.status.success() {
Ok(output)
} else {
Err(error::Error::DockerExecution {
args: "".to_string(),
})
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return if output.status.success() {
Ok(output)
} else {
Err(error::Error::DockerExecution {
args: "".to_string(),
})
};
ensure!(output.status.success(), error::DockerExecution { args });
Ok(output)

Comment on lines +147 to +151
return if output.status.success() {
Some(stdout.to_string())
} else {
None
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this work?

Suggested change
return if output.status.success() {
Some(stdout.to_string())
} else {
None
};
output.status.success().then(|| stdout.to_string())

@samuelkarp
Copy link
Contributor Author

@bcressey Thanks for the detailed review here! I no longer work for Amazon and am not currently in a position to dedicate my own personal time or resources to moving this forward. I'd be happy for you or for someone else on the team to pick up my contribution and finish it. Please feel free to close this once a replacement PR is open.

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

Successfully merging this pull request may close these issues.

6 participants