Skip to content

Commit 7a363d0

Browse files
committed
MDEV-39126: Feedback plugin to use /etc/os-release
* Updated the feedback plugin to use /etc/os-release instead of the obsolete /etc/lsb-release for OS discovery. * Fallback to /etc/lsb-release and /etc/*-release is maintained for older systems. * Added regression tests for os-release parsing.
1 parent 78d0d53 commit 7a363d0

2 files changed

Lines changed: 97 additions & 14 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
--echo # MDEV-39126: Feedback plugin to use /etc/os-release
2+
--source include/not_embedded.inc
3+
4+
# 1. Create the skip file unconditionally, using the MDEV prefix
5+
perl;
6+
my $dir = $ENV{'MYSQLTEST_VARDIR'};
7+
my $skip_file = "$dir/tmp/mdev39126_skip_test.inc";
8+
open(my $fh, '>', $skip_file) or die "Could not open $skip_file: $!";
9+
10+
if (! -f "/etc/os-release") {
11+
print $fh "skip No /etc/os-release found;\n";
12+
}
13+
close($fh);
14+
EOF
15+
16+
# Source the file and then clean it up immediately
17+
--source $MYSQLTEST_VARDIR/tmp/mdev39126_skip_test.inc
18+
--remove_file $MYSQLTEST_VARDIR/tmp/mdev39126_skip_test.inc
19+
20+
# Get the value from the plugin into an mtr variable
21+
let $os_val = `SELECT variable_value FROM information_schema.feedback WHERE variable_name = 'os'`;
22+
23+
# Export the mtr variable to the environment so Perl can read it
24+
let $ENV{'os_val'} = $os_val;
25+
26+
# 2. Compare the value directly in Perl to avoid creating a second file
27+
perl;
28+
my $os_val = $ENV{'os_val'};
29+
my $expected = "";
30+
31+
if (open(my $fh, '<', '/etc/os-release')) {
32+
while (my $line = <$fh>) {
33+
chomp $line;
34+
if ($line =~ /^PRETTY_NAME="?(.*?)"?$/) {
35+
$expected = $1;
36+
last;
37+
}
38+
}
39+
close($fh);
40+
}
41+
42+
# Print the result so it gets recorded in the .result file
43+
if ($os_val eq $expected) {
44+
print "os matches PRETTY_NAME\n";
45+
} else {
46+
print "Mismatch! Got: '$os_val', Expected: '$expected'\n";
47+
}
48+
EOF
49+
50+
--echo # End of 10.11 tests

plugin/feedback/utils.cc

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -266,27 +266,59 @@ int prepare_linux_info()
266266

267267
#ifdef TARGET_OS_LINUX
268268
/*
269-
let's try to find what linux distribution it is
270-
we read *[-_]{release,version} file in /etc.
269+
Let's try to find what Linux distribution it is.
270+
We first check for the modern and portable /etc/os-release:
271271
272-
Either it will be /etc/lsb-release, such as
272+
==> /etc/os-release <==
273+
PRETTY_NAME="Ubuntu 22.04.2 LTS"
274+
275+
If not found, we fall back to /etc/lsb-release:
273276
274277
==> /etc/lsb-release <==
275-
DISTRIB_ID=Ubuntu
276-
DISTRIB_RELEASE=8.04
277-
DISTRIB_CODENAME=hardy
278278
DISTRIB_DESCRIPTION="Ubuntu 8.04.4 LTS"
279279
280-
Or a one-liner with the description (/etc/SuSE-release has more
281-
than one line, but the description is the first, so it can be
282-
treated as a one-liner).
280+
Or a one-liner with the description (/etc/SuSE-release has more
281+
than one line, but the description is the first, so it can be
282+
treated as a one-liner).
283283
284-
We'll read lsb-release first, and if it's not found will search
285-
for other files (*-version *-release *_version *_release)
286-
*/
284+
We'll read os-release first, then lsb-release, and if neither is found
285+
we will search for other files (*-version *-release *_version *_release).
286+
*/
287287
int fd;
288288
have_distribution= false;
289-
if ((fd= my_open("/etc/lsb-release", O_RDONLY, MYF(0))) != -1)
289+
290+
/* 1. First try the modern portable way: /etc/os-release */
291+
if ((fd= my_open("/etc/os-release", O_RDONLY, MYF(0))) != -1)
292+
{
293+
size_t len= my_read(fd, (uchar*)distribution, sizeof(distribution)-1, MYF(0));
294+
my_close(fd, MYF(0));
295+
if (len != (size_t)-1)
296+
{
297+
distribution[len]= 0; // safety
298+
char *found= strstr(distribution, "PRETTY_NAME=");
299+
if (found)
300+
{
301+
have_distribution= true;
302+
char *end= strstr(found, "\n");
303+
if (end == NULL)
304+
end= distribution + len;
305+
found+= 12; // Length of "PRETTY_NAME="
306+
307+
if (*found == '"' && end[-1] == '"')
308+
{
309+
found++;
310+
end--;
311+
}
312+
*end= 0;
313+
314+
char *to= strmov(distribution, "os-release: ");
315+
memmove(to, found, end - found + 1);
316+
}
317+
}
318+
}
319+
320+
/* 2. Fallback to older /etc/lsb-release if os-release is not found */
321+
if (!have_distribution && (fd= my_open("/etc/lsb-release", O_RDONLY, MYF(0))) != -1)
290322
{
291323
/* Cool, LSB-compliant distribution! */
292324
size_t len= my_read(fd, (uchar*)distribution, sizeof(distribution)-1, MYF(0));
@@ -301,7 +333,7 @@ int prepare_linux_info()
301333
char *end= strstr(found, "\n");
302334
if (end == NULL)
303335
end= distribution + len;
304-
found+= 20;
336+
found+= 20; // Length of "DISTRIB_DESCRIPTION="
305337

306338
if (*found == '"' && end[-1] == '"')
307339
{
@@ -316,6 +348,7 @@ int prepare_linux_info()
316348
}
317349
}
318350

351+
319352
/* if not an LSB-compliant distribution */
320353
for (uint i= 0; !have_distribution && i < array_elements(masks); i++)
321354
{

0 commit comments

Comments
 (0)