Add OS Package Repo Tool 2 (OPRT2) - #400
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
| } else { | ||
| // Reset the length to 0, but don't release the allocated space | ||
| soh.buffer = soh.buffer[:0] | ||
| cmd.Stdout = bytes.NewBuffer(soh.buffer) |
There was a problem hiding this comment.
Can we just make soh.buffer a bytes.Buffer itself? This form of NewBuffer is meant for when you need a buffer with some initial contents (which we don't have since we just cleared out any existing content).
There was a problem hiding this comment.
Is this meant to be committed?
| @@ -0,0 +1,13 @@ | |||
| FROM mcr.microsoft.com/vscode/devcontainers/go:1.25 | |||
|
|
|||
| RUN go install gotest.tools/gotestsum@latest && \ | |||
There was a problem hiding this comment.
Do we need to install @latest here? Looks like we pin the version of gotestsum elsewhere in this PR.
|
|
||
| logger, err := config.GetLogger(c.Logger) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to create logger") |
There was a problem hiding this comment.
| return fmt.Errorf("failed to create logger") | |
| return errors.New("failed to create logger") |
For a static error message prefer errors.New over Errorf.
| // Ensure that the cleanup hook is always run. This is important to avoid leaking Attune credentials. | ||
| if closer, ok := authenticator.(commandrunner.CleanupHook); ok { | ||
| defer func() { | ||
| cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute) |
There was a problem hiding this comment.
Are you intentionally wrapping context.Background() instead of using ctx here?
If so, context.WithoutCancel(ctx) is another option worth considering. It's a bit more explicit.
| ) | ||
|
|
||
| // EnvVarHook provides an easy way to set an environment variable on every | ||
| // command invokation. |
There was a problem hiding this comment.
| // command invokation. | |
| // command invocation. |
| // isOPRT2ConfigValid validates that the provided config file contents match the JSON schema | ||
| // for [OPRT2] config. Returns true if the config is valid, false otherwise. Records error | ||
| // information to stderr. | ||
| func isOPRT2ConfigValid(configFileAsJSON []byte) bool { |
There was a problem hiding this comment.
Generally library code should return some error type (with as much detail as you'd like) and leave it to the caller to decide whether to write the detail to stderr or do something else with it.
| // read and write functions will error, stopping the copy. | ||
| // This retains all properties of [io.Copy], including support for [io.WriterTo] and | ||
| // [io.ReaderFrom]. | ||
| func Copy(ctx context.Context, dst io.Writer, src io.Reader) (int64, error) { |
There was a problem hiding this comment.
This feels like an antipattern to me.
// If the context is cancelled, calls to
// read and write functions will error, stopping the copy.
How are you satisfying this? It looks like me like the context is only checked before the read or write operation begins, but as soon as it starts we stop respecting context cancelation and enter a blocking call.
| return errors.Join(cleanupErrs...) | ||
| } | ||
|
|
||
| // ListItemsWithPrefix returns a list of items in the storage backend that match the given prefix. |
There was a problem hiding this comment.
| // ListItemsWithPrefix returns a list of items in the storage backend that match the given prefix. | |
| // ListItems returns a list of items in the storage backend. |
| keys := slices.Collect(maps.Keys(uniqueMatchers)) | ||
| slices.Sort(keys) |
There was a problem hiding this comment.
| keys := slices.Collect(maps.Keys(uniqueMatchers)) | |
| slices.Sort(keys) | |
| keys := slices.Sorted(maps.Keys(uniqueMatchers)) |
There was a problem hiding this comment.
@fheinecke Two requests:
- +4K LoC is a lot to review. Please split this PR into several logical parts that are more manageable. Workflows, Makefiles, configs, tool itself can likely be split as well into several logical parts.
- I only glanced through the changeset so far but it all seems very complex: contextualcopy.io, io.go, contextlock.go, mutexmap.go, providers, some schema generator? Why is all of this needed, can the implementation be simplified before we spend time on the review? I'm pretty sure even Teleport codebase doesn't have this many wrappers over standard library functions and primitives, I'm certain we can do just fine without any of those for the tool that's just supposed to auth with Teleport and call an API to push packages.
I encourage you to start very simple and massively simplify the implementation, ensure the tool has bare minimum and essential stuff (Start simple and iterate). We can always add complexity when needed. Thanks.
Sure, I can do this.
As mentioned in the PR body the complexity of this is stemming from the following business requirements set prior to writing the first line of code for this project:
Yes, all of this could be simplified, but only if we either:
Is there something specific that you'd like me to change here?
Most if not all the contents of these files are here because:
I can link to these if you like. Basically all of them are here because the Go encourages/requires the use of a
|
|
@zmb3 I'll copy over and address your review comments on the split/follow up PRs |
Summary
This is a first pass at a new revision of the OS Package Repo Tool (OPRT). The primary purpose of this is to public OS packages via Attune, and is intended to replace practically all of our current tooling around OS package publishing.
Goals
As discussed internally, this tool will operate under the following assumptions:
Also discussed internally, this tool is designed to meet the following criteria:
tsh proxy app attune)The only component in this PR that is not built to meet these requirements is config file validation (see schema dir). However I believe that this is important to make it easier to detect problems with changes to our CI/CD pipelines. I also believe that this is less complex and easier to read than re-implementing full config validation and defaulting outside of the jsonschema library.
Remaining items
This is missing the following pieces that I will add in follow up PRs after this gets an initial review:
Usage
The tool is intended to be used as follows (GHA wrapper to come):
Config file:
Run it: