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 preliminary Go 1.21 support #427

Merged
merged 20 commits into from
Jan 31, 2024
Merged

Conversation

eskultety
Copy link
Member

@eskultety eskultety commented Dec 14, 2023

This PR just deals with the necessary bits to get projects building with 1.21. Proper 1.21 support including support for the toolchain will be proposed in the future.

Maintainers will complete the following section

  • Commit messages are descriptive enough
  • Code coverage from testing does not decrease and new code is covered
  • Docs updated (if applicable)
  • Docs links in the code are still valid (if docs were updated)

Note: if the contribution is external (not from an organization member), the CI
pipeline will not run automatically. After verifying that the CI is safe to run:

@brunoapimentel
Copy link
Contributor

brunoapimentel commented Dec 26, 2023

We need to update the go version in the docs: https://github.com/containerbuildsystem/cachi2/blob/main/README.md?plain=1#L311.

Besides this, LGTM 🚀

@eskultety
Copy link
Member Author

Converting to draft as due to #419 (comment) this should be proposed as POC first.

@eskultety eskultety marked this pull request as draft January 8, 2024 14:37
@eskultety eskultety changed the title Add preliminary Go 1.21 support POC Add preliminary Go 1.21 support Jan 8, 2024
@eskultety eskultety force-pushed the go-121 branch 2 times, most recently from 39758a3 to 7ea7d38 Compare January 18, 2024 09:28
@eskultety eskultety changed the title POC Add preliminary Go 1.21 support Add preliminary Go 1.21 support Jan 18, 2024
@eskultety eskultety marked this pull request as ready for review January 18, 2024 09:29
@eskultety
Copy link
Member Author

Dropping the draft flag, since we can assume the latest revision to act as v1.

Note that unit/integration tests implementation was skipped for v1 (apart from the necessary changes to keep the existing suite passing) to get review on the overall design.

Copy link
Contributor

@chmeliik chmeliik left a comment

Choose a reason for hiding this comment

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

Approach LGTM 👍

Didn't go into the details

cachi2/core/utils.py Show resolved Hide resolved
cachi2/core/package_managers/gomod.py Show resolved Hide resolved
@brunoapimentel
Copy link
Contributor

So, I'm having a small issue running this locally when I target a Go 1.18 repo:

2024-01-19 11:24:45,216 INFO go.mod recommends/requires Go version: 1.18
2024-01-19 11:24:45,216 INFO Downloading the gomod dependencies
2024-01-19 11:24:49,141 ERROR The command "go install golang.org/dl/go1.20@latest" failed
2024-01-19 11:24:49,141 ERROR STDERR:
go: downloading golang.org/dl v0.0.0-20240109181448-9c0c6b2b4a66
build cache is required, but could not be located: GOCACHE is not defined and neither $XDG_CACHE_HOME nor $HOME are defined

I could work around this by passing my local $HOME to the run_cmd process, so I'm guessing this is needed in local envs?

@eskultety
Copy link
Member Author

So, I'm having a small issue running this locally when I target a Go 1.18 repo:

2024-01-19 11:24:45,216 INFO go.mod recommends/requires Go version: 1.18
2024-01-19 11:24:45,216 INFO Downloading the gomod dependencies
2024-01-19 11:24:49,141 ERROR The command "go install golang.org/dl/go1.20@latest" failed
2024-01-19 11:24:49,141 ERROR STDERR:
go: downloading golang.org/dl v0.0.0-20240109181448-9c0c6b2b4a66
build cache is required, but could not be located: GOCACHE is not defined and neither $XDG_CACHE_HOME nor $HOME are defined

I could work around this by passing my local $HOME to the run_cmd process, so I'm guessing this is needed in local envs?

Doh! I knew about this, but forgot to address it amongst other things that had to be done here. So Go's SDK download and install requires git (which, duh, everyone should have), potentially gcc (but this should be Go's direct dependency). Lastly, Go builds some artifacts (as can be seen in the Containerfile commit which deletes them), so yeah, I'll point Go to some GOCACHE

@brunoapimentel
Copy link
Contributor

One more small detail: apparently, very old versions of go.mod files lack the go {version} line: https://github.com/release-engineering/retrodep/blob/master/go.mod

I think we can easily leave this as unsupported... but maybe it's just as easy to assume this should be handled by go 1.20.

@eskultety
Copy link
Member Author

One more small detail: apparently, very old versions of go.mod files lack the go {version} line: https://github.com/release-engineering/retrodep/blob/master/go.mod

I think we can easily leave this as unsupported... but maybe it's just as easy to assume this should be handled by go 1.20.

LOL, that must be veeery old. Well, my original unposted version of the code handling this situation looked roughly like this:

try:
  run go list -f {{.GoVersion}} -m
except Exception:
 # if go failed to parse go.mod, falback to regex
re.match(...)

But then I figured versions of Go that wouldn't pass parsing with the regex have already been long EOL'd.
I can add the code back if you want, but the error reporting was funky in that case, because we'd have reported "Failed to download dependencies" by the time we get to the fallback code in the except clause, so more work would be needed.

but maybe it's just as easy to assume this should be handled by go 1.20.

Yeah, good point, I can set the parsed version using the regex to a fixed value of the bundled Go if the regex doesn't find a match (so that we get past the version comparisons) and let the bundled Go installation (since it claims to be backwards compatible) handle it, that's a trivial fix.

@eskultety eskultety force-pushed the go-121 branch 2 times, most recently from a8d2214 to 9ce522a Compare January 22, 2024 15:01
@eskultety
Copy link
Member Author

since v1:

  • Go._retry has now a better description along with more generic error messages since we're running more than just dependency downloading commands
  • _get_gomod_version now returns a fixed 1.20 string if a go.mod doesn't specify the go directive (Note however, that this way any newer Go toolchain will modify go.mod with its own version in such case; not a problem of cachi2)
  • explicitly set GOCACHE with go install and <gover>/bin/go download to prevent build cache is required, but could not be located: GOCACHE is not defined and neither $XDG_CACHE_HOME nor $HOME are defined error

@brunoapimentel
Copy link
Contributor

Maybe it'd be good to add some unit tests to the new Go class to improve coverage: https://coveralls.io/builds/65216054/source?filename=cachi2%2Fcore%2Fpackage_managers%2Fgomod.py.

I think we also should bump some of our integration test-repos to Go 1.21 (or add new branches/scenarios). But we can do this in a follow up story.

@eskultety
Copy link
Member Author

Maybe it'd be good to add some unit tests to the new Go class to improve coverage: https://coveralls.io/builds/65216054/source?filename=cachi2%2Fcore%2Fpackage_managers%2Fgomod.py.

I think we also should bump some of our integration test-repos to Go 1.21 (or add new branches/scenarios). But we can do this in a follow up story.

Sure, I will add them provided I have a green light on this approach, see #427 (comment)

@eskultety
Copy link
Member Author

since v2:

  • rearranged some of the commits slightly
  • added unit tests for the Go instance methods
  • cosmetic code changes due to the unit tests

To make the whole Go CLI wrapper interface more convenient, make
instances of the class callables, so that one can just write
something like:
    go(["foo", "bar"], env={}, capture_output=False)

So in the end it's supposed to make the usage more intuitive by:
    - passing any CLI arguments to a callable named "go"
    - passing subprocess arguments directly with the base signature

Signed-off-by: Erik Skultety <[email protected]>
This helper's purpose is to locate an alternative toolchain
installation if requested. It scans 2 locations:
    1) system /usr/local/go/go<ver>
        - this one will be pre-installed in the container image to
          save time during runtime
    2) $XDG_CACHE_HOME/cachi2/go
        - this one is targeted at local cachi2 use cases, i.e. without
          using the container image

Signed-off-by: Erik Skultety <[email protected]>
The release property is essentially just a gateway to extracting the
version number. It uses and parses 'go version' to get the information.

Signed-off-by: Erik Skultety <[email protected]>
This property is going to be used for comparisons with the
recommended/required toolchain versions coming from go.mod file, so it
returns packaging.version.Version instead of plain string.

Signed-off-by: Erik Skultety <[email protected]>
This helper is crucial in that it determines our behaviour based on the
Go version specified in the package's go.mod file. Unfortunately for us
we cannot utilize Go's native functionality of parsing the go.mod file
for us as older versions of Go will have issues with go.mod files based
on newer version of the language. Therefore, let's extract the
    'go <ver>' line manually.

Signed-off-by: Erik Skultety <[email protected]>
This patch wires everything up by routing all 'go' calls through the
wrapper class.

Signed-off-by: Erik Skultety <[email protected]>
We used to log the version of Go used for pre-fetching of the deps. We
can still do that, but not outside of a Go instance since we may need
alternate version of SDK to be installed, so that information would
then be misleading. Since we already log this (and much more) as part
of the Go class, we don't need the dropped hunk anymore.

Signed-off-by: Erik Skultety <[email protected]>
The logic of these helpers has been extracted into the Go class and so
these have become unused and can be dropped.

Signed-off-by: Erik Skultety <[email protected]>
One of Go 1.21's main features is specifying the suggested version of
toolchain to be used for compiling modules as a means of forwards
compatibility.
However, this patch only adds preliminary support for Go 1.21 in that it
essentially explicitly denies usage of toolchains (which is fine,
because those versions are only suggestive, Go always prefers building
with the bundled toolchain anyway) by the means of explicitly setting
the GOTOOLCHAIN env variable to 'local' which instructs Go to always
use the bundled toolchain (provided it's new enough to conform to the
minimum required version of Go indicated by the 'go' line).
This patch makes sure we set GOTOOLCHAIN=local during both pre-fetch as
well as for user container builds.

Future patches will add proper support for 1.21 dealing with
alternative toolchain versions that will need to be prefetched.

STONEBLD-2046

Signed-off-by: Erik Skultety <[email protected]>
Copy link
Contributor

@taylormadore taylormadore left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@eskultety
Copy link
Member Author

Since v3:

  • minor cosmetic changes

The main motivation behind this change is the Go 1.21 version which
isn't available on Fedora 38 but is on Fedora 39.

Resolves: containerbuildsystem#387

Signed-off-by: Erik Skultety <[email protected]>
Since we bumped the container image to Fedora 39 shipping with 1.21, we
need to update our Go mock data with 1.21.

Signed-off-by: Erik Skultety <[email protected]>
@eskultety
Copy link
Member Author

since v4:

  • silence Hadolint

@eskultety
Copy link
Member Author

@taylormadore @ben-alkov please give this one more quick look and if it looks good I'll proceed with the merge.

Copy link
Contributor

@taylormadore taylormadore left a comment

Choose a reason for hiding this comment

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

Still LGTM 👍

@eskultety eskultety added this pull request to the merge queue Jan 31, 2024
Merged via the queue into containerbuildsystem:main with commit 3a916a0 Jan 31, 2024
15 checks passed
@eskultety eskultety deleted the go-121 branch July 17, 2024 11:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants