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

Add updates concerning dynamic profile generation #1321

Conversation

zadjii-msft
Copy link
Member

This is based on discussion with @DHowett-MSFT we had o*line. We're trying to
work through a way to prevent dynamic profiles from roaming to machines the
dynamic profiles might not exist on.

After writing this up, I'm not totally sure that it's a better design.

I'm making a PR for this element of the design into the other spec. It seemed like a pretty substantial change to the other spec that should almost be reviewed on its own. If we agree on this bit of it, I'll merge it in to be reviewed with the rest.

  This is based on discussion with @DHowett-MSFT we had o*line. We're trying to
  work through a way to prevent dynamic profiles from roaming to machines the
  dynamic profiles might not exist on.

  After writing this up, I'm not totally sure that it's a better design.
Copy link
Contributor

@DHowett-MSFT DHowett-MSFT left a comment

Choose a reason for hiding this comment

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

I've sat on this for a couple weeks, and I actually like it more than I thought I did. I have some language clarifications and an idea, though.

If a dynamic profile generator has determined that a profile should no longer be
We'll generate these dynamic profiles immediately after applying the defaults.
When a generator runs, it'll be able to create unique profile GUIDs for each
source it wants to generate a profile for. It'll attempt find any profiles that
Copy link
Contributor

Choose a reason for hiding this comment

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

It shouldn't attempt to find any profiles that exist -- right now, during the "early phase," there shouldn't be any profiles that exist except the ones in the defaults. The ones from the json file have been read from disk, but not yet turned into profile objects.

The generator will create a bunch of basics, which are then strictly overlaid with the user's json json tree. The generator doesn't ever need to query the user's store.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think there's one other step you missed. We need to make a first pass on the user's settings to make sure all the profiles end up in the right order. We'll do nothing in that pass other than instantiate a list of profiles with matching GUIDs. When we generate profiles dynamically, their settings will be applied to the profile objects that already exist, as if only to maintain the ordering.

Copy link
Contributor

Choose a reason for hiding this comment

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

That doesn't really matter, we can put profiles in order once we load the user's settings. We're using a vector right now but that's an implementation detail.

@@ -444,6 +488,39 @@ the `profiles.json` file. Fortunately though, users should be able to remove
much of the boilerplate from their `profiles.json` files, and trim it down just
to their modifications.

### Dynamic Profile Generators Need to be Enabled
With the current proposal, profiles that are generated by a dynamic profile
generator _need_ that generator to be enabled for the profile to appear in the
Copy link
Contributor

Choose a reason for hiding this comment

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

This is required for things like "I uninstalled my WSL distribution, why is it still hanging around" to work, anyway. Maybe if we bang on the language a bit to change "generator" to "source"? A "profile source" can be disabled, and that will remove all of the profiles that originated from that source.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the discussion around "profile generators can be slow" should be resolved by "don't do that, you are a bad plugin author" 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

This also opens us up to "default.json parser is just another type-of-source", which might be a safe mental model?

@@ -458,6 +535,15 @@ to their modifications.
behave correctly. It's possible that we could abstract our implementation into
a WinRT interface that extensions could implement, and be triggered just like
other dynamic profile generators.
- Additionally, we could expand the dynamic profile generator contract to
Copy link
Contributor

Choose a reason for hiding this comment

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

Now here is a thought. If we force the GUID, we can encode source: '{guid-of-source}' in the user copy of the profile. If a profile has a source, but that source didn't early-generate a profile of the same guid, THEN we just fail to apply. We don't need any logic to say "if the command line is blank, skip it"!

@@ -474,6 +560,10 @@ to their modifications.
that as the point of comparison to check if a setting's value has changed.
There may be more unknowns with this proposal, so I leave it for a future
feature spec.
- How do these play with dynamically generated profiles? If the user sets a
Copy link
Contributor

Choose a reason for hiding this comment

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

Above source-guid comment might help address this!

@DHowett-MSFT
Copy link
Contributor

DHowett-MSFT commented Jul 8, 2019

The flow becomes:

  1. load default.json from disk -> DefaultsJson
  2. load profiles.json from disk -> UserJson
  3. parse DefaultsJson into Profile objects -> new Profile objects 1
  4. run <all generators>::Generate -> new Profile objects 2
  5. union all Profile objects 1 and 2 -> Profile set 3
    • Set 3 contains only profiles with a total {guid, source} tuple.
  6. overlay UserJson.globals.defaults on all Profiles in set 3
  7. overlay UserJson. on all Profiles in set 3
    1. If a profile with a source is not attested by that source (check set 3), we can't overlay it (!) so it is never created, so it never needs to be deleted.

Done. User "global defaults" override all generator settings, profile specific settings override all settings, and generators have 0 reliance on UserJson.

@zadjii-msft
Copy link
Member Author

zadjii-msft commented Jul 31, 2019

@DHowett-MSFT how about:

When we load the settings, we'll perform the following steps, each mentioned in greater detail below:

  1. Load from disk the defaults.json (the default settings) -> DefaultsJson
  2. Load from disk the profiles.json (the user settings) -> UserJson
  3. Perform a preliminary scan of the user settings, and create all the profiles in order they appear in the user settings file. Fill in their guid and source properties (if they exist).
  4. Layer all settings from the defaults on the existing profiles, and create the default color schemes, as well as the default global settings.
    • To layer: if a profile exists already in the list of profiles with a matching guid and source, apply the settings to that Profile object. Otherwise, if there is no match, append it to the end of the list of profiles.
  5. Generate any dynamically generated profiles, if necessary. Layer them on top of existing profiles. If any profiles were appended in this manner, indicate that we'll need to save the updated settings.
  6. [Not covered in this spec] Apply the UserJson.globals.defaults settings to every profile, including default, generated and user profiles. (This will override generated settings for generated profiles).
  7. Layer all user settings upon the existing settings models.
  8. Validate the settings.
  9. If necessary, write the modified settings back to profiles.json.

I think functionally it's the same, with an added step to make sure the profiles appear in the order they appear in the user settings file

@DHowett-MSFT
Copy link
Contributor

I guess I just don't get why 4, 5 need to happen before 3. The total order can be enforced during 7, when we're "applying the user's settings". Before that, they have no order. 😄

Copy link
Contributor

@DHowett-MSFT DHowett-MSFT left a comment

Choose a reason for hiding this comment

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

THis is solid.

When a generator runs, it'll be able to create unique profile GUIDs for each
source it wants to generate a profile for. It'll attempt find any profiles that
exist in the list of profiles with a matching GUID, and apply the settings to
that profile if found, or it'll create a new profile to apply the settings to.
Copy link
Contributor

Choose a reason for hiding this comment

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

this wording still suggests that the generator knows-about the user profile object and updates it.

added to the user settings, all that will be added is the `name`, `guid`, and
`source`.

<!-- If a dynamic profile generator has determined that a profile should no longer be
Copy link
Contributor

Choose a reason for hiding this comment

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

nix commented code when merging

@zadjii-msft zadjii-msft merged commit dd2c4db into dev/migrie/s/754-cascading-settings-spec Aug 1, 2019
@zadjii-msft zadjii-msft deleted the dev/migrie/s/754-dynamic-profiles branch August 1, 2019 12:44
zadjii-msft added a commit that referenced this pull request Aug 20, 2019
* Start working on drafting this spec

* Really add a LOT of notes

* More spec updates.

  * Remove `hiddenProfiles` in favor of `profile.hidden`
  * Add info on how layering will work
  * add more powershell core info

* Finish remaining TODO sections

* Apply suggestions from code review

Fix simple typos

Co-Authored-By: Dustin L. Howett (MSFT) <duhowett@microsoft.com>

* Lots of feedback from PR

  * Try and make dynamic settings a bit clearer
  * more clearly call out serializing only what's different from a default-
    constructed `Profile`
  * Add more goals
  * add a blurb for user-default profile objects

* Add updates concerning dynamic profile generation (#1321)

* Add updates concerning dynamic profile generation

  This is based on discussion with @DHowett-MSFT we had o*line. We're trying to
  work through a way to prevent dynamic profiles from roaming to machines the
  dynamic profiles might not exist on.

  After writing this up, I'm not totally sure that it's a better design.

* Add some initial updates from discussion

* Pushing some updates here. I haven't given it a once over to ensure it's all consistent but it's worth reviewing @DHowett-MSFT

* Some minor updates from Dustin

* Fix a bunch of slightly more minor points in the spec

* Move "Profile Ordering" to "Future considerations"

* Add some notes on migrating profiles, GUID generation, de-duping profiles, and O R A N G E

* Fix the indenting here

* Update powershell core to be a dynamic profile, don't even mention other options.

* Remaining PR feedback

* Apply suggestions from code review

Co-Authored-By: Michael Niksa <miniksa@microsoft.com>

* remove a dead comment
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.

2 participants