Merge pull request #5747 from BOINC/vko_detect_wsl_version

[Windows] Detect WSL version of enabled distros.
This commit is contained in:
David Anderson 2024-08-11 19:35:45 -07:00 committed by GitHub
commit 20473d29b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 50 additions and 34 deletions

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2022 University of California
// https://boinc.berkeley.edu
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -253,11 +253,11 @@ void CLIENT_STATE::show_host_info() {
const WSL& wsl = host_info.wsls.wsls[i];
if (wsl.is_default) {
msg_printf(NULL, MSG_INFO,
" [%s] (default): %s (%s)", wsl.distro_name.c_str(), wsl.name.c_str(), wsl.version.c_str()
" [%s] <v%s> (default): %s (%s)", wsl.distro_name.c_str(), wsl.wsl_version.c_str(), wsl.os_name.c_str(), wsl.os_version.c_str()
);
} else {
msg_printf(NULL, MSG_INFO,
" [%s]: %s (%s)", wsl.distro_name.c_str(), wsl.name.c_str(), wsl.version.c_str()
" [%s] <v%s>: %s (%s)", wsl.distro_name.c_str(), wsl.wsl_version.c_str(), wsl.os_name.c_str(), wsl.os_version.c_str()
);
}
}

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2018 University of California
// https://boinc.berkeley.edu
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -23,7 +23,7 @@
#include "hostinfo.h"
bool get_available_wsls(std::vector<std::string>& wsls, std::string& default_wsl) {
bool get_available_wsls(std::vector<std::pair<std::string, DWORD>>& wsls, std::string& default_wsl) {
const std::string lxss_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Lxss";
HKEY hKey;
@ -65,20 +65,24 @@ bool get_available_wsls(std::vector<std::string>& wsls, std::string& default_wsl
break;
}
char wsl_name[buf_len];
DWORD wsl_name_len = sizeof(wsl_name);
DWORD wsl_state = 0;
DWORD wsl_state_len = sizeof(wsl_state);
ret = RegQueryValueEx(hSubKey, "State", NULL, NULL, (LPBYTE)&wsl_state, &wsl_state_len);
if (ret != ERROR_SUCCESS || wsl_state != 1) {
continue;
}
DWORD wsl_version = 1;
DWORD wsl_version_len = sizeof(wsl_version);
// there might be no version key, so we ignore the return value
RegQueryValueEx(hSubKey, "Version", NULL, NULL, (LPBYTE)&wsl_version, &wsl_version_len);
char wsl_name[buf_len];
DWORD wsl_name_len = sizeof(wsl_name);
ret = RegQueryValueEx(hSubKey, "DistributionName", NULL, NULL,
(LPBYTE)wsl_name, &wsl_name_len);
if ((ret == ERROR_SUCCESS) && (wsl_name_len < buf_len)) {
wsls.push_back(wsl_name);
wsls.push_back(std::make_pair(wsl_name, wsl_version));
if (std::string(wsl_guid) == std::string(default_wsl_guid)) {
default_wsl = wsl_name;
}
@ -117,8 +121,8 @@ std::wstring s2ws(const std::string& s)
return r;
}
bool create_wsl_process(const std::string& wsl_distro_name, const std::string& command, HANDLE* handle) {
return (pWslLaunch(s2ws(wsl_distro_name).c_str(), s2ws(command).c_str(), FALSE, in_read, out_write, out_write, handle) == S_OK);
bool create_wsl_process(const std::string& wsl_distro_name, const std::string& command, HANDLE* handle, bool use_current_work_dir = false) {
return (pWslLaunch(s2ws(wsl_distro_name).c_str(), s2ws(command).c_str(), use_current_work_dir, in_read, out_write, out_write, handle) == S_OK);
}
bool CreateWslProcess(const std::string& wsl_app, const std::string& command, HANDLE& handle) {
@ -226,7 +230,7 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
out_write = NULL;
pWslLaunch = NULL;
std::vector<std::string> distros;
std::vector<std::pair<std::string, DWORD>> distros;
std::string default_distro;
if (!get_available_wsls(distros, default_distro)) {
@ -270,7 +274,7 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
char wsl_dist_name[256];
char wsl_dist_version[256];
const std::string& distro = distros[i];
const std::string& distro = distros[i].first;
WSL wsl;
wsl.distro_name = distro;
if (distro == default_distro) {
@ -278,6 +282,7 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
} else {
wsl.is_default = false;
}
wsl.wsl_version = std::to_string(distros[i].second);
// lsbrelease
if (!create_wsl_process(distro, command_lsbrelease, &handle)) {
@ -344,16 +349,16 @@ int get_wsl_information(bool& wsl_available, WSLS& wsls) {
}
if (!os_name.empty()) {
wsl.name = os_name + " " + wsl_dist_name;
wsl.os_name = os_name + " " + wsl_dist_name;
}
else {
wsl.name = wsl_dist_name;
wsl.os_name = wsl_dist_name;
}
if (!os_version_extra.empty()) {
wsl.version = std::string(wsl_dist_version) + " [" + os_version_extra + "]";
wsl.os_version = std::string(wsl_dist_version) + " [" + os_version_extra + "]";
}
else {
wsl.version = wsl_dist_version;
wsl.os_version = wsl_dist_version;
}
wsls.wsls.push_back(wsl);
}

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2018 University of California
// https://boinc.berkeley.edu
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -23,27 +23,30 @@ WSL::WSL() {
void WSL::clear() {
distro_name = "";
name = "";
version = "";
os_name = "";
os_version = "";
is_default = false;
wsl_version = "1";
}
void WSL::write_xml(MIOFILE& f) {
char dn[256], n[256], v[256];
xml_escape(distro_name.c_str(), dn, sizeof(dn));
xml_escape(name.c_str(), n, sizeof(n));
xml_escape(version.c_str(), v, sizeof(v));
xml_escape(os_name.c_str(), n, sizeof(n));
xml_escape(os_version.c_str(), v, sizeof(v));
f.printf(
" <distro>\n"
" <distro_name>%s</distro_name>\n"
" <name>%s</name>\n"
" <version>%s</version>\n"
" <os_name>%s</os_name>\n"
" <os_version>%s</os_version>\n"
" <is_default>%d</is_default>\n"
" <wsl_version>%s</wsl_version>\n"
" </distro>\n",
dn,
n,
v,
is_default ? 1 : 0
is_default ? 1 : 0,
wsl_version.c_str()
);
}
@ -54,9 +57,10 @@ int WSL::parse(XML_PARSER& xp) {
return 0;
}
if (xp.parse_string("distro_name", distro_name)) continue;
if (xp.parse_string("name", name)) continue;
if (xp.parse_string("version", version)) continue;
if (xp.parse_string("os_name", os_name)) continue;
if (xp.parse_string("os_version", os_version)) continue;
if (xp.parse_bool("is_default", is_default)) continue;
if (xp.parse_string("wsl_version", wsl_version)) continue;
}
return ERR_XML_PARSE;
}

View File

@ -1,6 +1,6 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2018 University of California
// https://boinc.berkeley.edu
// Copyright (C) 2024 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
@ -23,10 +23,17 @@
#include "miofile.h"
#include "parse.h"
// this structure describes the information about every WSL (Windows Subsystem for Linux) installation enabled on the host
struct WSL {
// unique identifier of installed WSL distribution
std::string distro_name;
std::string name;
std::string version;
// name of the operating system
std::string os_name;
// version of the operating system
std::string os_version;
// version of WSL (currently 1 or 2)
std::string wsl_version;
// flag indicating whether this is the default WSL distribution
bool is_default;
WSL();