Skip to content

Conversation

@mtrmac
Copy link
Contributor

@mtrmac mtrmac commented Jul 12, 2018

@runcom , others: RFC

While testing a related change I have noticed that skopeo layers sets DockerDaemonInsecureSkipTLSVerify always to true, because the --tls-verify option is not declared for skopeo layers; and the way urfave/cli is used, there was no connection between the option declaration and reading the value, so it’s way too easy to omit one or the other. (In particular, cli.BoolT can return false if the option is not found, or on any other error, really, not only when the user has explicitly provided a false value.)

So, this motivated a comprehensive rework of the CLI data management; instead of copy&pasting strings and hoping to never make a typo (which is just not good enough for security options), create a struct someCommandOptions holding well-typed argument values, and set up the cli.Flag structures to write data in there; command handlers then use the values directly instead of using string lookup via *cli.Context. See the ‘Create an "options" structure for each command’ commit message for a detailed writeup of the structure change.

Given the explicit data structures, we can then fully model an optionalBool and optionalString argument type, and actually completely distinguish between a missing and default-valued argument values (well, as far as we can get without a native Go “optional” type mechanism).

(WIP because I need to finish and clean up the tests.)


Finally, this allows explicitly modeling the shared image-related options --src-*/--dest-* for copy, or --* for other commands, and expressing the relationships as explicit data structure pointers. That, however, made it much more visible that --authfile (introduced in #453 , and I’m afraid this design is pretty much my fault) is an irregular case: it is shared across the sources/destinations, but it is not a global flag; that forces all users to manage the scope of the flag explicitly, see how sharedOpts needs to be added everywhere. @umohnani8 @rhatdan @TomSweeneyRedHat Would it be reasonable to make --authfile a global flag, without backward compatibility (i.e. skopeo --authfile=… copy instead of skopeo copy --authfile=…)? I guess not, but I thought I’d at least ask.

@rhatdan
Copy link
Member

rhatdan commented Jul 12, 2018

Already out of date.

@giuseppe PTAL

@giuseppe
Copy link
Member

LGTM

Also is there any user of skopeo layers? IIRC it was already deprecated some time ago, and atomic that was using it at the time moved as well to skopeo copy. Would it make sense to drop skopeo layers completely?

@runcom
Copy link
Member

runcom commented Jul 13, 2018

I'd love to drop skopeo layers completely, there have been plenty of time to notice it's deprecated.

@rhatdan
Copy link
Member

rhatdan commented Jul 13, 2018

Can we drop it from the help/man pages first and see if anyone notices?

@mtrmac mtrmac force-pushed the cli-parsing branch 6 times, most recently from 35ed5a3 to b869a83 Compare July 18, 2018 15:34
@mtrmac mtrmac changed the title RFC WIP: Reliable CLI parsing RFC: Reliable CLI parsing Jul 18, 2018
@mtrmac
Copy link
Contributor Author

mtrmac commented Jul 18, 2018

This is now finished, including comprehensive tests for --tls-verify, the original impetus. Any more comments before I merge it? Opinions on moving --authfile?

@umohnani8
Copy link
Member

I am fine with making --authfile a global flag, but then we will probably have to make this change in podman and buildah as well. @rhatdan WDYT?

@rhatdan
Copy link
Member

rhatdan commented Jul 18, 2018

SGTM

@mtrmac mtrmac force-pushed the cli-parsing branch 3 times, most recently from e1993f1 to 8274191 Compare August 29, 2018 12:11
@rhatdan
Copy link
Member

rhatdan commented Sep 21, 2018

@mtrmac What do you want to do with this PR?

@mtrmac
Copy link
Contributor Author

mtrmac commented Sep 26, 2018

@mtrmac What do you want to do with this PR?

@rhatdan Get it merged, ideally. The discussion of the --authfile change above was a bit unclear to me and I failed to follow up.

Though, I guess, on balance, I’m willing to live with the code ugliness in order not to break --authfile.

Let me rebase this some time…

@rhatdan
Copy link
Member

rhatdan commented Sep 30, 2018

@runcom Lets get this merged.

mtrmac added 21 commits December 7, 2018 00:28
Replace commandTimeoutContextFromGlobalOptions with
globalOptions.commandTimeoutContext.  This requires passing
globalOptions to more per-command *Options state.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
contextFromGlobalOptions now uses globalOptions instead
of cli.Context.Global* .  That required passing globalOptions
through a few more functions.

Now, "all" that is left are all the non-global options
handled in contextFromGlobalOptions.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This is similar to the previous *Options structures, but this one
will support differing sets of options, in particular for the
copy source/destination.

The way the return values of imageFlags() are integrated into
creation of a cli.Command forces fakeContext() in tests to do
very ugly filtering to have a working *imageOptions available
without having a copyCmd() cooperate to give it to us.  Rather
than extend copyCmd(), we do the filtering, because the reliance
on copyCmd() will go away after all flags are migrated, and so
will the filtering and fakeContext() complexity.

Finally, rename contextFromGlobalOptions to not lie about only
caring about global options.

This only introduces the infrastructure, all flags continue
to be handled in the old way.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
We don't want to worry about mismatch of the flagPrefix value
between imageFlags() and contextFromImageOptions().  For now,
record it in imageOptions; eventually we will stop using it in
contextFromImageOptions and remove it again.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This is one of the ugliest parts; we need an extra parameter to support
the irregular screds/dcreds aliases.

This was previously unsupported by (skopeo layers).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This was previously unsupported by (skopeo layers).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This was previously unsupported by (skopeo layers)

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This was previously only supported in (skopeo copy).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This was previously only supported in (skopeo copy).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This is an extension of imageOptions that carries destination-specific
flags.

This will allow us to handle --dest-* flags without also exposing
pointless --src-* flags.

(This is, also, where the type-safety somewhat breaks down;
after all the work to make the data flow and availability explicit,
everything ends up in an types.SystemContext, and it's easy enough
to use a destination-specific one for sources.  OTOH, this is
not making the situation worse in any sense.)

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This introduces YET ANOTHER *Options structure, only to share this
option between copy source and destination.  (We do need to do this,
because the libraries, rightly, refuse to work with source and
destination declaring its own versino of the --authfile flag.)

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
All the contextFromImage{,Dest}Options flags are now defined in
imageFlags/imageDestFlags.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
contextFromImageOptions is finally not using any string-based lookup
in cli.Context, so we don't need to record this value any more.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
We no longer need the *cli.Context parameter, and at that point
it looks much cleaner to make this a method (already individually;
it will be even cleaner after a similar imageDestOptions conversion).

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This is analogous to the imageOptions.newSystemContext conversion.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
It was not really any clearer when broken out. We already have
a pair of trivial src/dest API calls before this, so adding
a similar src/dest call for SystemContext follows the pattern.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
We no longer need it for handling flags.

Also, require the caller to explicitly pass an image name to parseImage
instead of, horribly nontransparently, using the first CLI option.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
That in turn makes sure that the cli.String() etc. flag access functions
are not used, and all flag handling is done using the *Options structures
and the Destination: members of cli.Flag.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Signed-off-by: Miloslav Trmač <mitr@redhat.com>
@mtrmac
Copy link
Contributor Author

mtrmac commented Dec 6, 2018

@rhatdan rebased.

@rhatdan
Copy link
Member

rhatdan commented Dec 7, 2018

LGTM

@rhatdan rhatdan merged commit a51e38e into containers:master Dec 7, 2018
@mtrmac mtrmac deleted the cli-parsing branch December 8, 2018 14:25
This was referenced Mar 27, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants