Skip to content

Each-time build parameters #6828

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

Closed
bpmct opened this issue Mar 27, 2023 · 17 comments
Closed

Each-time build parameters #6828

bpmct opened this issue Mar 27, 2023 · 17 comments
Assignees

Comments

@bpmct
Copy link
Member

bpmct commented Mar 27, 2023

There are some use cases where a user may want to apply a parameter value for a single workspace build, but not persist that value for feature runs.

  • Force a rebuild/pull of the underlying container image
  • Pass a one-time token into a workspace

This kind of reminds me of build arguments or inputs for workflow_dispatch in GitHub actions

86147571-2de93700-babf-11ea-8a08-e4beffd3abe9

@bpmct bpmct changed the title One-time build parameters Each-time build parameters Mar 28, 2023
@mtojek
Copy link
Member

mtojek commented Mar 29, 2023

I guess that we have a couple of side comments to address first:

  1. In principle workspaces can be running for a long time, and can be affected by auto-stop, auto-start events. Once auto-start is triggered, should the workspace use parameters from the last build, or should coder block the auto-start mode?
  2. What is the expected behavior on clicking the Update button?
  3. What is the expected behavior on updating workspace settings (form)?
  4. I assume that it would be an extra popup that bumps up on clicking the Start button. Should we try to load parameters from the last build as suggested values?
  5. Each-time might be confusing as it won't be strictly each time. Alternative ideas for the provider properties - reprompt: true, user_prompt: true, inherited: false.

Similar concerns can be applied to CLI, but I guess that we can find answers based on the site/UI requirements.

EDIT:

I can start looking into this, and pair with @BrunoQuaresma on frontend changes, but it will defer works around the operability milestone.

@aaronlehmann
Copy link
Contributor

My thinking was that these parameters would automatically return to the default value after a successful workspace startup.

@mtojek
Copy link
Member

mtojek commented Mar 29, 2023

@aaronlehmann Could you please elaborate a bit more about your use-cases? Ben mentioned some of them in the issue description:

Force a rebuild/pull of the underlying container image
Pass a one-time token into a workspace

I'm afraid that one-time pass might be a bit confusing for regular users in terms of debugging. For instance: "I retried the failed build a few times, but I don't know what parameters I passed."

Force a rebuild/pull of the underlying container image

Is there any condition that justifies the need for "rebuild"? Maybe it can be "figured out" without prompting the end-user.

Pass a one-time token into a workspace

This is a common problem for integrating apps with Auth. For instance, in Github you can just create a Personal Access Token, that is limited to the single application and enables only relevant permissions. Users don't have to deal with OTP. Did you review if this option is available?

@aaronlehmann
Copy link
Contributor

My use case is "force a rebuild/pull of the underlying container image", not the one-time token.

Is there any condition that justifies the need for "rebuild"? Maybe it can be "figured out" without prompting the end-user.

So far this is based on heuristics, but sometimes base images will change and users will want to pick up those updates, so I want to give them an option to force a rebuild. I don't think the rebuild should be automatic whenever a base image changes, because it can slow down the startup process considerably and usually isn't necessary.

@mtojek
Copy link
Member

mtojek commented Mar 29, 2023

I understand your use case, but it will add unnecessary randomness to the solution. Template revisions are versioned, by ID and name. From the support perspective, the safest option would be to hardlink the Docker image under the hood with a template version. Users could decide if they prefer to stick to the older revision or whether they should update their templates.

If you allow users to force-update their workspace internals, you may deal with random workspace failures reported for the same template version.

Let me know your thoughts.

@aaronlehmann
Copy link
Contributor

In my use case, container images are not tied to a tenplate version. There is a single, shared template and users specify a source repository as a parameter. Repositories have instructions for building a container image specific to that repository (in a devcontainer.json file). Normally we will cache these builds, but I am looking for a way to override this caching behavior in specific cases when a rebuild should be forced.

A normal parameter doesn't work well for this because it means rebuilds will be forced on every restart goinfmg forward, until the user changes the parameter back.

Another possible way to address this would be to give the TF provider a way to change the parameter value back once it's done with the forced rebuild.

@mtojek
Copy link
Member

mtojek commented Mar 30, 2023

Normally we will cache these builds, but I am looking for a way to override this caching behavior in specific cases when a rebuild should be forced.

Yes, it is a tricky challenge. I'm not sure if it isn't more convenient to just stick to the latest version, but "cache it". Building Docker images in workspaces can be error-prone (mainly due to transient network issues), and takes time if the manifest is long.

I admit that I don't have an insight into your devcontainer.json files, but maybe it would be a good opportunity to optimize it on the other end. For instance, have a CI instance to build containers asynchronously and push images to the shared Docker repository. This way you could optimize the total time to provision a workspace - downloading an image + some minor file operations I guess.

Side note:
I know that I'm orbiting around the main purpose of this issue, but I'd like us to feel confident that this feature is the only and best way to address the challenge.

@aaronlehmann
Copy link
Contributor

Building Docker images in workspaces can be error-prone (mainly due to transient network issues), and takes time if the manifest is long.

Note that we aren't building these images in workspaces. They are built by a build service that supports caching.

For instance, have a CI instance to build containers asynchronously and push images to the shared Docker repository. This way you could optimize the total time to provision a workspace - downloading an image + some minor file operations I guess.

This kind of prebuilding is on our roadmap but I see it as a bit tangential to the use case of "give me a fresh image right now". The asynchronicity could be a problem: CI may not have finished pushing a build for the latest commit by the time a workspace is started.

Something like this might work if wrapped by a script that starts a build on the build server, waits for it to finish, and updates the workspace to use the newly-pushed image. The script would need to be able to update a workspace parameter containing the image digest, and ideally this parameter wouldn't be exposed to the user in the UI (to limit clutter and confusion).

A downside of going this route is that users need to run a script instead of clicking a "rebuild image now" button or checkbox in the UI (which might potentially be possible with one-time parameters?)

Basically, the behavior that I'm looking for is:

  • When starting a workspace for the first time, we use a cached image if available, unless the user requests a fresh build.
  • When restarting a workspace, use the same image it ran with before, unless the user wants to upgrade it.

In both cases, the "rebuild now" setting shouldn't be persistent.

@bpmct bpmct added this to the ❓Sprint 2 milestone Jun 16, 2023
@ammario ammario removed this from the ❓Sprint 2 milestone Jun 29, 2023
@mtojek mtojek self-assigned this Jul 3, 2023
@mtojek
Copy link
Member

mtojek commented Jul 4, 2023

@aaronlehmann
Copy link
Contributor

I'm curious what prompt_user means for the workflow. I was hoping to have a way to force a container rebuild by setting a parameter that only applies to the next workspace build, and automatically gets reverted after that. I don't think prompting the user at every startup would be a good way to accomplish this, since these "forced rebuilds" will be unusual.

Thinking about this some more, I wonder if I can script the behavior I want using the Coder API by clearing my force_rebuild parameter on workspace startup. I'm not sure if clearing the parameter value woukd trigger a new build, though (which I don't want in this case, since the intent is to prevent this one-time flag from applying to future builds).

@mtojek
Copy link
Member

mtojek commented Jul 4, 2023

I'm curious what prompt_user means for the workflow.

data "coder_parameter" "force_rebuild" {
  name         = "force_rebuild"
  display_name = "Force rebuild image"
  type         = "bool"
  description  = "Rebuild the Docker image rather than use the cached one."
  mutable      = true
  prompt_user  = "always"
}

prompt_user

Re-prompt the user for the parameter value.

always means that the workspace owner will be asked to input the value on starting or updating the workspace. Workspaces with enabled auto-start will reuse parameters from the last stopped build.

I don't think prompting the user at every startup would be a good way to accomplish this, since these "forced rebuilds" will be unusual.

We need to place it somewhere in the UI. As you can see in the issue description, it would be similar to running a Github workflow, which requires one more button click. Is it still aligned with your expectations?

If not, would you mind elaborating a bit more on the UI/UX side?

@aaronlehmann
Copy link
Contributor

We need to place it somewhere in the UI. As you can see in the issue description, it would be similar to running a Github workflow, which requires one more button click. Is it still aligned with your expectations?

The idea of an extra click to request a container rebuild (in this example) makes sense, but this makes it sound like the extra prompt would happen every time the user starts a workspace:

always means that the workspace owner will be asked to input the value on starting or updating the workspace. Workspaces with enabled auto-start will reuse parameters from the last stopped build.

My thinking was that in the rare cases where users want to set this parameter, they would click through to the "parameters" page in the UI and set it there (or, equivalently, run a script that uses the Coder API or CLI to set the parameter).

@mtojek
Copy link
Member

mtojek commented Jul 4, 2023

but this makes it sound like the extra prompt would happen every time the user starts a workspace:

That is correct.

My thinking was that in the rare cases where users want to set this parameter, they would click through to the "parameters" page in the UI and set it there (or, equivalently, run a script that uses the Coder API or CLI to set the parameter).

I'm not sure if this approach is super-efficient and intuitive. I'd rather set a transient build flag before starting the workspace (click Start) than click out through the Parameters page. What do you think, @bpmct?

Maybe we could add an extra menu option, Start with options, to start the workspace with one-time flags? Then, we would have to rename the prompt_user value from always to something like build_options.

@bpmct
Copy link
Member Author

bpmct commented Jul 5, 2023

Adding a "Start with options" menu item that goes to the parameters page (or a new "Build options" tab) is a good solution. I agree that adding a pop-up dialog for every build would be annoying for users, especially if 90% of the time they want to do a "normal" build using the default value of the "each time parameters."

re. the syntax: What do you think about ephemeral = true? Template admins should not be able to set mutable = false and ephemeral = true.

One other option for syntax is

data "coder_parameter" {
  # ...
  persistence = <ephemeral/immutable/mutable>

and gradually warn/deprecate the mutable=<true/false> field like other providers do when they consolidate fields.

@aaronlehmann
Copy link
Contributor

I also like the idea of "Start with options".

ephemeral = true seems like good simple syntax. I'd also be okay with persistence = emphemeral, but it might be good idea to keep mutability separate from persistence, since they are distinct concepts.

@BrunoQuaresma
Copy link
Collaborator

I think we can do something like this in the UI:
One-Time Parameters

  • Add a "more options" dropdown on "Restart" and "Start" actions
  • In the dropdown/popover we show a tiny form like GitHub does

Thoughts? @aaronlehmann I would appreciate your feedback.

@aaronlehmann
Copy link
Contributor

I love it! Thanks for working with me on this.

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

No branches or pull requests

5 participants