Skip to content

Remove unused parameters.#50201

Open
ctalledo wants to merge 1 commit intomoby:masterfrom
ctalledo:remove-unused-params
Open

Remove unused parameters.#50201
ctalledo wants to merge 1 commit intomoby:masterfrom
ctalledo:remove-unused-params

Conversation

@ctalledo
Copy link
Copy Markdown
Collaborator

- What I did

Refactoring to remove unused parameters in Moby code base.

- How I did it

- How to verify it

- A picture of a cute animal (not mandatory but encouraged)

@ctalledo ctalledo requested a review from tonistiigi as a code owner June 13, 2025 21:40
@ctalledo ctalledo marked this pull request as draft June 13, 2025 21:40
@ctalledo ctalledo force-pushed the remove-unused-params branch from 17fe7ae to a07bf60 Compare June 13, 2025 22:59
@ctalledo ctalledo marked this pull request as ready for review June 14, 2025 00:23
@ctalledo ctalledo changed the title Remove unusued parameters. Remove unused parameters. Jun 14, 2025
Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

We may have to be careful removing some of these; at least not without knowing why they were there in the first place.

Some of these functions (especially in the containerd implementation) were created as placeholder matching the signature for non-containerd. And it's possible some of these arguments were not yet implemented (but ultimately should).

Comment on lines 432 to +431
// FromRemote converts a remote snapshot reference to a local one
func (w *Worker) FromRemote(ctx context.Context, remote *solver.Remote) (cache.ImmutableRef, error) {
rootfs, err := getLayers(ctx, remote.Descriptors)
rootfs, err := getLayers(remote.Descriptors)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While updating; I see that rootfs is shadowing the rootfs import; perhaps change to rootFS

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh! Actually, that won't work either, because there's already a variable rootFS. Hm.. that's confusing for sure! Looks like we may want to look at variables used, because it's really easy to pick the wrong one then?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks. I opted for aliasing the rootfs import to rootfspkg, to avoid confusion with the rootfs variables in the code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment on lines 560 to +558
}

func getLayers(ctx context.Context, descs []ocispec.Descriptor) ([]rootfs.Layer, error) {
func getLayers(descs []ocispec.Descriptor) ([]rootfs.Layer, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Had a quick peek; looks like this was added in 22f7cae, and never used. Assuming the current implementation won't change, I don't think there's much need for a context, so probably fine indeed to remove.

Comment thread daemon/checkpoint.go

// getCheckpointDir verifies checkpoint directory for create,remove, list options and checks if checkpoint already exists
func getCheckpointDir(checkDir, checkpointID, ctrName, ctrID, ctrCheckpointDir string, create bool) (string, error) {
func getCheckpointDir(checkDir, checkpointID, ctrName, ctrCheckpointDir string, create bool) (string, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like this was used in the past, but its use was removed in e51aec9, so looks fine to remove;

Comment thread daemon/containerd/image_delete.go Outdated
// filter for which conflict types the caller cares about,
// and will only check for these conflict types.
func (i *ImageService) checkImageDeleteConflict(ctx context.Context, imgID image.ID, all []c8dimages.Image, mask conflictType) error {
func (i *ImageService) checkImageDeleteConflict(imgID image.ID, all []c8dimages.Image, mask conflictType) error {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like the context here was added in cad9713, which at the time also called i.client.ImageService().List(ctx, "target.digest=="+imgID.String())

That code was removed in 87c87bc, however it added a TODO;

// TODO: Count unexpired references...

Not 100% what's needed to satisfy that TODO, but perhaps we should check if that may involve a context to be passed; in that case it may be better to keep the context, otherwise we end up removing contexts that later have to be reintroduced again.

Copy link
Copy Markdown
Collaborator Author

@ctalledo ctalledo Jun 17, 2025

Choose a reason for hiding this comment

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

Thanks; my view is: I don't think we should keep unused variables (ctx in this case) unless there's a compelling reason to do so (e.g., such as it's part of an existing API or interface, or having the variable be unused is clearly a bug). Otherwise it's confusing when folks read the code, plus it leads to unused variables that never get removed.

In this particular case, the checkImageDeleteConflict function is just an internal function (not an API or interface), and therefore I think it's best to remove the unused variable. If and when the "TODO" you mentioned is done and if a context is needed, then it will be plumbed accordingly (and that should be trivial to do).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Context variables will be used if the function is annotated with logging (e.g. log.G(ctx).Warn(...)) or OpenTelemetry tracing events. Contexts are for propagating contextual metadata about the function call, not just cancelation and deadlines.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Why not add the context variable if and when the function needs it though? Otherwise we have a unused variable that may remain there forever.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Otherwise we have a unused variable that may remain there forever.

So what?

Changing a function signature requires touching all the call sites. That's a tedious refactor that can't be automated: whether the parameter value should be ctx, context.Background(), context.TODO() or context.WithoutCancel(ctx) depends on what's calling the function. Having the context parameter already roughed-in to the function signature allows authors to set the parameter value appropriately when writing the code that calls the function instead of leaving it to the poor soul who has to change the function signature and fix up all callers.

Preemptively adding context parameters to functions is a pragmatic decision which favours maintainability and sustainable development over aesthetics.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You're both right on this one!

In general, I agree with @ctalledo try to prevent implementing things ahead of time (risk of YAGNI!), unless you're really sure it's gonna be used (in which case probably a tracking ticket and/or TODO are warranted). And perhaps some of these cases where a context.Context was added were pre-maturely.

That said; context.Context is a bit of an outlier; we are still in process of modernizing our code-base to make more parts context-aware and/or adding telemetry (and context logging). For some of those it's worth the trade-off of having some signatures already include a context; having the context in the signature is a good reminder for those working on the code to consider adding context-handling.

There's various places where preparations have been made to wire up the context, and removing the unused context, even from a non-exported function can sometimes cause a ripple effect; remove it from the un-exported function, and next someone comes on functions that call the un-exported function, and may now be compelled to remove the context from that as well (potentially undoing the preparations).

Is it perfect? No it's not!
Are there cases where context were added too premature? Possibly!

In this case; I noticed the TODO I linked to above, and I'm tempted to say "It depends" - I don't know (yet) what's involved in addressing that TODO, and it's possible that addressing it involves calling a function that expects a context, and for that I definitely agree with @corhere - it's a minor burden to keep it in place, and probably more disruptive if we have to re-wire the contexts if it turns out we need it.

Copy link
Copy Markdown
Collaborator Author

@ctalledo ctalledo Jun 17, 2025

Choose a reason for hiding this comment

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

OK I left it in place in this function, though I don't see a need to keep it in the getLayers() function above.

@corhere: it's not an aesthetic concern, having unused parameters is confusing to the reader.

Comment thread daemon/containerd/image_push.go Outdated
}

func (i *ImageService) pushRef(ctx context.Context, targetRef reference.Named, platform *ocispec.Platform, metaHeaders map[string][]string, authConfig *registry.AuthConfig, out progress.Output) (retErr error) {
func (i *ImageService) pushRef(ctx context.Context, targetRef reference.Named, platform *ocispec.Platform, authConfig *registry.AuthConfig, out progress.Output) (retErr error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I suspect that the metaHeaders here are something that's not implemented yet for the containerd image store. Looking at the equivalent code for non-containerd, it looks like this is wired up;

imagePushConfig := &distribution.ImagePushConfig{
Config: distribution.Config{
MetaHeaders: metaHeaders,
AuthConfig: authConfig,
ProgressOutput: progress.ChanOutput(progressChan),
RegistryService: i.registryService,
ImageEventLogger: i.LogImageEvent,
MetadataStore: i.distributionMetadataStore,
ImageStore: distribution.NewImageConfigStoreFromStore(i.imageStore),
ReferenceStore: i.referenceStore,
},
ConfigMediaType: schema2.MediaTypeImageConfig,
LayerStores: distribution.NewLayerProvidersFromStore(i.layerStore),
UploadManager: i.uploadManager,
}

So this actually looks like a bug, or at least "something's missing" and we may not have a tracking ticket for it (but we should?);

func (ir *imageRouter) postImagesPush(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
metaHeaders := map[string][]string{}
for k, v := range r.Header {
if strings.HasPrefix(k, "X-Meta-") {
metaHeaders[k] = v
}
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

In this case the fact that metaHeaders is unused does seem like a clear bug, given that it's used in the docker image store implementation of the PushImage interface. So I've added it back.

Having said that, should we file a ticket to investigate further and actually use the metaHeaders in the implementation of PushImage for the containerd image store?

Comment on lines -48 to +44
func (i *ImageService) createLayer(descriptor *ocispec.Descriptor, layerName string, rwLayerOpts *layer.CreateRWLayerOpts, initFunc layer.MountInit) (container.RWLayer, error) {
func (i *ImageService) createLayer(descriptor *ocispec.Descriptor, layerName string, initFunc layer.MountInit) (container.RWLayer, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like a bug, or something left to implement

Copy link
Copy Markdown
Collaborator Author

@ctalledo ctalledo Jun 17, 2025

Choose a reason for hiding this comment

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

Yes agreed, I've reverted the change.

Comment on lines -31 to -33
rwLayerOpts := &layer.CreateRWLayerOpts{
StorageOpt: ctr.HostConfig.StorageOpt,
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Related to the other comment; looks like this is something not yet implemented, and for which we may need a tracking ticket.

If I'm not mistaken; options available here may depend on the storage driver used (with graph-drivers), and quite likely we currently don't have options yet for the containerd snapshotters (but there's some options, such as size that may be relevant, but perhaps not yet supported by containerd?

Copy link
Copy Markdown
Collaborator Author

@ctalledo ctalledo Jun 17, 2025

Choose a reason for hiding this comment

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

Got it, I've reverted that change too.

which we may need a tracking ticket

Who would be best to file such a ticket (I am afraid I don't understand the options for containerd-snapshotter well enough to write to create the description of the ticket)?

Copy link
Copy Markdown
Contributor

@corhere corhere left a comment

Choose a reason for hiding this comment

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

Please do not remove "unused" context.Context parameters. Plumbing contexts through the codebase is an ongoing process; the parameters will be used sooner or later.

@ctalledo ctalledo force-pushed the remove-unused-params branch 4 times, most recently from f65d21b to fb128a3 Compare June 17, 2025 00:50
@ctalledo
Copy link
Copy Markdown
Collaborator Author

ctalledo commented Jun 17, 2025

Please do not remove "unused" context.Context parameters. Plumbing contexts through the codebase is an ongoing process; the parameters will be used sooner or later.

Thanks @corhere.

I hear what you are saying, but there are at least one context variable I am removing above that is clearly not needed (see getLayers). Also, the context variable in checkImageDeleteConflict is unused and unclear that it will ever be needed (see discussion here).

@ctalledo ctalledo requested review from corhere and thaJeztah June 17, 2025 00:58
@ctalledo ctalledo force-pushed the remove-unused-params branch from fb128a3 to 705e5d8 Compare June 17, 2025 23:41
Signed-off-by: Cesar Talledo <[email protected]>
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.

3 participants