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

Lookup WSL distros in the registry #10967

Merged
12 commits merged into from
Aug 24, 2021
Merged

Lookup WSL distros in the registry #10967

12 commits merged into from
Aug 24, 2021

Conversation

zadjii-msft
Copy link
Member

@zadjii-msft zadjii-msft commented Aug 17, 2021

This PR converts the WSL distro generator to use the registry to lookup
WSL distros instead of trying to parse the results of wsl.exe.
wsl.exe sometimes takes a very long time to launch the WSL service,
which means that on the first launch of the Terminal, WSL distros can
sometimes be missing entirely!

References

PR Checklist

Detailed Description of the Pull Request / Additional comments

This is maybe a little BODGY, but hey we get tons of reports of this
root cause.

Validation Steps Performed

Ran it locally, it did well. Ran a wsl --shutdown, then booted the
terminal - seemed to do well. I never was able to repro the slowness
myself, but I'd suspect this'll fix it.

@ghost ghost added Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalConnection Issues pertaining to the terminal<->backend connection interface Issue-Bug It either shouldn't be doing this or needs an investigation. Priority-2 A description (P2) Product-Terminal The new Windows Terminal. labels Aug 17, 2021
@github-actions
Copy link

github-actions bot commented Aug 17, 2021

@check-spelling-bot Report

Unrecognized words, please review:

  • lpc
  • lpcb
  • lpft
  • Lxss
  • recieves
Previously acknowledged words that are now absent LPCCH lpcs SPACEBAR Unregister xIcon yIcon
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the [email protected]:microsoft/terminal.git repository
on the dev/migrie/b/9905-7199-6160 branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/68294f863d2adfafd6937324486b499fea73b8ab.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/issues/comments/900526429" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@github-actions
Copy link

github-actions bot commented Aug 17, 2021

@check-spelling-bot Report

Unrecognized words, please review:

  • lpc
  • lpcb
  • lpft
  • Lxss
  • recieves
Previously acknowledged words that are now absent LPCCH lpcs SPACEBAR Unregister xIcon yIcon
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the [email protected]:microsoft/terminal.git repository
on the dev/migrie/b/9905-7199-6160 branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/68294f863d2adfafd6937324486b499fea73b8ab.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/issues/comments/900550860" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
{
std::vector<std::wstring> names{};
names.reserve(guidStrings.size());
if (_getWslNames(wslRootKey, guidStrings, names))
Copy link
Member

Choose a reason for hiding this comment

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

I believe it would be better to use exception handling as opposed to using booleans.

@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Aug 17, 2021
@DHowett
Copy link
Member

DHowett commented Aug 19, 2021

Notes from looking at the registry keys:

  1. In the future (i will file) we can use the PackageFamilyName value to generate a better icon by default (!) for distros that came from packages
  2. I was going to say "let's understand State, which is one of the values in the distro key" but then i decided eh, it will be fine

@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Aug 23, 2021
@github-actions

This comment has been minimized.

@vadimkantorov

This comment has been minimized.

@zadjii-msft

This comment has been minimized.

@vadimkantorov

This comment has been minimized.

@DHowett

This comment has been minimized.

src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
*valueLengthNeededWithNull = (length / sizeof(wchar_t));
// If you add one for another trailing null, then there'll actually
// be _two_ trailing nulls in the buffer.
return status == ERROR_MORE_DATA ? ERROR_SUCCESS : status;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure these are HRESULTs

Copy link
Member

Choose a reason for hiding this comment

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

(I am also not certain I understand how this function works/what it is expecting)

src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
@vadimkantorov

This comment has been minimized.

@DHowett DHowett added the AutoMerge Marked for automatic merge by the bot when requirements are met label Aug 23, 2021
@ghost
Copy link

ghost commented Aug 23, 2021

Hello @DHowett!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@miniksa miniksa removed the AutoMerge Marked for automatic merge by the bot when requirements are met label Aug 23, 2021
Copy link
Member

@miniksa miniksa left a comment

Choose a reason for hiding this comment

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

Approve with comments. Unmark automerge so you can see them before it rockets off.

src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
// - <none>
// Return Value:
// - the HKEY if it exists and we can read it, else nullptr
static HKEY openWslRegKey()
Copy link
Member

Choose a reason for hiding this comment

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

You can't have these return the wil::unique_hkey straight up?

Copy link
Member

Choose a reason for hiding this comment

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

+1 for returning RAII wrappers.

Copy link
Member

Choose a reason for hiding this comment

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

My preferred API surface when smart wrappers is involved -- and this extends to WRL::ComPtr and all similar variants -- is this:

smart_wrapper_thing GetAThing(); // produce shared wrapper
thing GetAThing(); // produce dumb thing, see note 1
void TakeAThingOptional(thing*); // consume only -- non-owning and non-shared -- optional
void TakeAThing(thing&); // consume only -- non-owning and non-shared -- required

Of course, ref vs pointer is a decision you can make for the specific type. HKEY is by nature optional.

Putting the smart_wrapper into the consuming contract forces the caller to have that type (bad) and implies some ownership semantics (dependent on the type).

(1) In general, a function that returns a smart wrapper is subject to the same restrictions as one that returns the thing directly (like HKEY openWslRegKey): it must ensure that if an exception is encountered before the smart wrapper is populated, it does not leak the resource. Registry functions don't throw, so the need for returning a smart wrapper is reduced. That makes HKEY open... okay in my book so long as we make sure to cover the error conditions.

src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp Outdated Show resolved Hide resolved
// - <none>
// Return Value:
// - the HKEY if it exists and we can read it, else nullptr
static HKEY openWslRegKey()
Copy link
Member

Choose a reason for hiding this comment

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

+1 for returning RAII wrappers.

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

I think I have to block because Leonard pointed out a logic error?

@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Aug 24, 2021
Copy link
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

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

LBTM

Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

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

@zadjii-msft I asked Leonard to block it so I could approve, leaving you with two once you dismiss his. For timezone purposes, it's likely easier on you to dismiss his when you've fixed it 😄

@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Aug 24, 2021
@DHowett DHowett added the AutoMerge Marked for automatic merge by the bot when requirements are met label Aug 24, 2021
@ghost ghost merged commit f9a844d into main Aug 24, 2021
@ghost ghost deleted the dev/migrie/b/9905-7199-6160 branch August 24, 2021 13:10
DHowett pushed a commit that referenced this pull request Aug 25, 2021
This PR converts the WSL distro generator to use the registry to lookup
WSL distros instead of trying to parse the results of `wsl.exe`.
`wsl.exe` sometimes takes a very long time to launch the WSL service,
which means that on the first launch of the Terminal, WSL distros can
sometimes be missing entirely!

## References
* Also related is #6160, but I feel that deserves a separate PR for
  warning when the default profile is a dynamic profile who's source
  indicated it was gone. 

## PR Checklist
* [x] Closes #9905
* [x] Closes #7199
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

This is maybe a little BODGY, but hey we get tons of reports of this
root cause.

## Validation Steps Performed

Ran it locally, it did well. Ran a `wsl --shutdown`, then booted the
terminal - seemed to do well. I never was able to repro the slowness
myself, but I'd suspect this'll fix it.
@ghost
Copy link

ghost commented Aug 31, 2021

🎉Windows Terminal Preview v1.10.2383.0 has been released which incorporates this pull request.:tada:

Handy links:

@ghost
Copy link

ghost commented Aug 31, 2021

🎉Windows Terminal Preview v1.11.2421.0 has been released which incorporates this pull request.:tada:

Handy links:

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Settings Issues related to settings and customizability, for console or terminal Area-TerminalConnection Issues pertaining to the terminal<->backend connection interface AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Bug It either shouldn't be doing this or needs an investigation. Needs-Second It's a PR that needs another sign-off Priority-2 A description (P2) Product-Terminal The new Windows Terminal.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Slow loading time on first use WSL terminal not available sometimes in "New Tab" dropdown on start-up
5 participants