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

Revise the way previews are controlled #1290

Merged
merged 2 commits into from
May 6, 2018
Merged

Revise the way previews are controlled #1290

merged 2 commits into from
May 6, 2018

Conversation

joeduffy
Copy link
Member

@joeduffy joeduffy commented Apr 28, 2018

I found the flag --force to be a strange name for skipping a preview,
since that name is usually reserved for operations that might be harmful
and yet you're coercing a tool to do it anyway, knowing there's a chance
you're going to shoot yourself in the foot.

I also found that what I almost always want in the situation where
--force was being used is to actually just run a preview and have the
confirmation auto-accepted. Going straight to --force isn't the right
thing in a CI scenario, where you actually want to run a preview first,
just to ensure there aren't any issues, before doing the update.

In a sense, there are four options here:

  1. Run a preview, ask for confirmation, then do an update (the default).
  2. Run a preview, auto-accept, and then do an update (the CI scenario).
  3. Just run a preview with neither a confirmation nor an update (dry run).
  4. Just do an update, without performing a preview beforehand (rare).

This change enables all four workflows in our CLI.

Rather than have an explosion of flags, we have a single flag,
--preview, which can specify the mode that we're operating in. The
following are the values which correlate to the above four modes:

  1. "": default (no --preview specified)
  2. "auto": auto-accept preview confirmation
  3. "only": only run a preview, don't confirm or update
  4. "skip": skip the preview altogether

As part of this change, I redid a bit of how the preview modes
were specified. Rather than booleans, which had some illegal
combinations, this change introduces a new enum type. Furthermore,
because the engine is wholly ignorant of these flags -- and only the
backend understands them -- it was confusing to me that
engine.UpdateOptions stored this flag, especially given that all
interesting engine options also accepted a dryRun boolean. As of
this change, the backend.PreviewBehavior controls the preview options.

@joeduffy
Copy link
Member Author

@lukehoban @CyrusNajmabadi I am very open to feedback on this change. I originally just renamed the flags, but then realized the need for option (2) -- this is what LM, and I suspect most CI folks, will do -- and the illegal combinations of flags felt really kludgy.

At the same time, --preview=skip, etc. is a little "wordy" (though, if we expanded the flags to be sufficiently descriptive to tell you what they actually do, those get wordy too).

@lukehoban
Copy link
Member

this is what LM, and I suspect most CI folks, will do

FWIW - In our own CI (integration test framework) we accomplish this via pulumi update —preview followed by pulumi update —force. I don’t find it terrible that that requires two separate commands, though I’m not opposed to the proposed change here either. I do agree that in practice —force hasn’t felt quite right.

Is there a simpler change where we just change the name of —force? Perhaps —yes or —apply or —skipPreview?

@joeduffy
Copy link
Member Author

That's where I started, but it just felt kludgy. All the places where we check for bad combinations of flags, etc. Plus, a benefit I had hoped this would lead to is not having to run the command twice (this was at least 50% of why I was excited about the change in the first place!)

@lukehoban
Copy link
Member

Just to summarize for myself - here's the four common cases I can imagine:

  1. Normal inner loop development:
    • Before: pulumi update
    • After: pulumi update
  2. "simple" CI/CD:
    • Before: pulumi update --preview followed by pulumi update --force
    • After: pulumi update --preview=auto
  3. Rich CI/CD workflow with preview approval:
    • Before: pulumi update --preview in approval stage followed by pulumi update --force in application stage.
    • After: pulumi update --preview=only in approval stage followed by pulumi update --preview=skip in application stage.
  4. Impatient inner loop development:
    • Before: pulumi update --force
    • After: pulumi update --preview=skip (or pulumi update --preview=auto).

FWIW - It's partly the fact that I believe (3) will be the proper way to do CI/CD longterm (fundamentally two different steps), that makes me less worried about (2) being two steps as well - and in fact lightly prefer that these two feel more similar (in fact, identical in our existing model) across the two CI/CD workflows.

Net, while I understand the motivation for the change, I don't feel like the "afters" above are clearly better than the "befores". Thoughts? (I would still look for another word instead of force)

Would also love @CyrusNajmabadi input, as he's thought a fair bit about this as well.

@joeduffy
Copy link
Member Author

joeduffy commented Apr 29, 2018

I suspect things will change even more once we get to sophisticated approval workflows.

The thing I hate about all of this is that we're using flags to perform logically distinct actions. That feels awkward to me, and screams out for commands. What if we

  • Keep preview to mean, just run the preview
  • Offer two flags for update: --auto-approve and --skip-preview

Going back to your scenarios, we then end up with

  1. Normal inner loop development:
    • Before: pulumi update
    • After: pulumi update
  2. "simple" CI/CD:
    • Before: pulumi update --preview followed by pulumi update --force
    • After: pulumi update --auto-approve
  3. Rich CI/CD workflow with preview approval:
    • Before: pulumi update --preview in approval stage followed by pulumi update --force in application stage.
    • After: pulumi preview in approval stage followed by either pulumi update --auto-approve (always recommended) or pulumi update --skip-preview (for impatients) in application stage.
  4. Impatient inner loop development:
    • Before: pulumi update --force
    • After: pulumi update --skip-preview

@joeduffy
Copy link
Member Author

By the way, when I said

I suspect things will change even more once we get to sophisticated approval workflows.

I say this because I expect us to want something entirely different. For example:

$ pulumi update --from=./some-build.artifact

where some-build.artifact was output by our tool and contains a full archive of the program to be run (PPC-like), complete with the prior preview's output so that the update can note any deviations.

@CyrusNajmabadi
Copy link
Contributor

I'm not sure how i feel aobut this. It only seems to affect hte following case:

"i want to auto approve if there was no issue". Which only saves slightly over "just run normal update, and then approve manually" or just running "--preview" then "--force".

Noodling on this a bit to see if anything comes to mind as strictly superior.

@CyrusNajmabadi
Copy link
Contributor

I think part of my issue is this:

skip (no preview, just update), auto (auto-accept)")

The difference between these is just too subtle for me to think is valuable to give to a user. auto-accept essentially means: "go do it" and "skip" just means "go do it". So really, all that happens here is if the preview is printed out or not... which seems pretty minor and unessential a thing to provide control over.

It would likely also have a difference if the preview caused an error. however, that's also extremely subtle.

@ellismg
Copy link
Contributor

ellismg commented May 4, 2018

After using the new system for a few days, here's some feedback:

  1. I still really wish I could type pulumi preview When I'm doing exploration, seeing what will happen is what I care about most. In fact, I really care about the "diff" view there, because it helps me correlate what I'm writing with the API shapes exposed by the SDK. Typing pulumi update --preview --diff feels like a real mouthful here.

  2. When I get into a tight edit, debug loop, I find myself doing pulumi update --force often, because I don't actually care about the preview. But I really dislike training myself to pass a flag called --force for this case.

What Joe outlines in his last message feels right to me. Instead of --auto-approve, however, I'd probably just use the --yes flag we used to have.

@lukehoban
Copy link
Member

Instead of --auto-approve, however, I'd probably just use the --yes flag we used to have.

I like this.

@joeduffy
Copy link
Member Author

joeduffy commented May 5, 2018

All that sounds great. Thanks, I'll proceed with this set of updates.

@joeduffy
Copy link
Member Author

joeduffy commented May 5, 2018

A quick question for folks. It's annoying that commands like pulumi update and pulumi destroy will require --yes every single time when run in a non-interactive setting like CI. An alternative which I think I like better is to simply switch to --yes when running in non-interactive. Thoughts?

@joeduffy joeduffy force-pushed the preview_flag branch 8 times, most recently from 6268214 to cdcb987 Compare May 6, 2018 16:39
I found the flag --force to be a strange name for skipping a preview,
since that name is usually reserved for operations that might be harmful
and yet you're coercing a tool to do it anyway, knowing there's a chance
you're going to shoot yourself in the foot.

I also found that what I almost always want in the situation where
--force was being used is to actually just run a preview and have the
confirmation auto-accepted.  Going straight to --force isn't the right
thing in a CI scenario, where you actually want to run a preview first,
just to ensure there aren't any issues, before doing the update.

In a sense, there are four options here:

1. Run a preview, ask for confirmation, then do an update (the default).
2. Run a preview, auto-accept, and then do an update (the CI scenario).
3. Just run a preview with neither a confirmation nor an update (dry run).
4. Just do an update, without performing a preview beforehand (rare).

This change enables all four workflows in our CLI.

Rather than have an explosion of flags, we have a single flag,
--preview, which can specify the mode that we're operating in.  The
following are the values which correlate to the above four modes:

1. "": default (no --preview specified)
2. "auto": auto-accept preview confirmation
3. "only": only run a preview, don't confirm or update
4. "skip": skip the preview altogether

As part of this change, I redid a bit of how the preview modes
were specified.  Rather than booleans, which had some illegal
combinations, this change introduces a new enum type.  Furthermore,
because the engine is wholly ignorant of these flags -- and only the
backend understands them -- it was confusing to me that
engine.UpdateOptions stored this flag, especially given that all
interesting engine options _also_ accepted a dryRun boolean.  As of
this change, the backend.PreviewBehavior controls the preview options.
This changes the CLI interface in a few ways:

* `pulumi preview` is back!  The alternative of saying
  `pulumi update --preview` just felt awkward, and it's a common
  operation to want to perform.  Let's just make it work.

* There are two flags consistent across all update commands,
  `update`, `refresh`, and `destroy`:

    - `--skip-preview` will skip the preview step.  Note that this
      does *not* skip the prompt to confirm that you'd like to proceed.
      Indeed, it will still prompt, with a little warning text about
      the fact that the preview has been skipped.

    * `--yes` will auto-approve the updates.

This lands us in a simpler and more intuitive spot for common scenarios.
@joeduffy
Copy link
Member Author

joeduffy commented May 6, 2018

I've gone with this latest idea, of not requiring --yes in non-interactive scenarios. This still feels a little rough, so I would encourage you guys (@CyrusNajmabadi @ellismg @lukehoban) to think about the ideal workflows here. For instance, it now feels odd that we require a --yes in all cases for stack rm, and yet not destroy. Prior my change, we would prompt you twice to do a destroy, which surely feels wrong, and so I removed one of them and made all update commands consistent.

@joeduffy joeduffy merged commit c5b702e into master May 6, 2018
@joeduffy joeduffy deleted the preview_flag branch May 6, 2018 21:18
@lindydonna lindydonna added the impact/breaking Fixing this issue will require a breaking change label May 20, 2018
@CyrusNajmabadi
Copy link
Contributor

I'll def have to try this out. However, a lot of the tweaks seem sensible to me. Especially about having defualt behavior in non-tty sessions. The tty seems like the place where we can say "we're interactive with teh user, not a script, so we can def involve them more." If it's a script, we can just presume the user knows what they're doing and proceed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
impact/breaking Fixing this issue will require a breaking change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants