billw2 / rpi-clone

A shell script to clone a booted disk.
BSD 3-Clause "New" or "Revised" License
2.56k stars 335 forks source link

Update RPi OS logic detection #152

Open martignoni opened 1 year ago

martignoni commented 1 year ago
martignoni commented 1 year ago

Should work with Bookworm (and hopefully later Debian versions).

gpongelli commented 1 year ago

hi @martignoni , I was looking to your changes , I've tried them manually and osversion in my case is empty.

those are the result from my raspberry

pi@raspberrypi:~ $ cat /proc/device-tree/model
Raspberry Pi 4 Model B Rev 1.2

pi@raspberrypi:~ $ cat /etc/os-release 
PRETTY_NAME="Raspbian GNU/Linux bookworm/sid"
NAME="Raspbian GNU/Linux"
VERSION_CODENAME=bookworm
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"

pi@raspberrypi:~ $ cat /etc/rpi-issue 
Raspberry Pi reference 2019-09-26
Generated using pi-gen, https://github.com/RPi-Distro/pi-gen, 80d486687ea77d31fc3fc13cf3a2f8b464e129be, stage5

as you can see, the /etc/os-version misses the VERSION_ID field .

With the original code, at least the "raspbian" variable is set to 1.

martignoni commented 1 year ago

Hi @gpongelli,

You'll see that in your case the rpios variable (which replaces variable raspbian) is correctly set to 1.

What you describe is not a problem, since osversion is only used to detect recent versions of RPiOS.

In your case, you've an older release, there's no VERSION_ID in your /etc/os-release, so osversion is empty; the comparison on line 38 evaluates to false, so rpios_recent=0 and your older release is adequately detected.

Recent versions of RPiOS all have a VERSION_ID in their /etc/os-release, so in this case the comparison on line 38 evaluates correctly to true.

gpongelli commented 1 year ago

Hi @martignoni , I’ve no idea what’s “recent” for you but, as you can see I’m on bookworm, that’s the actual testing release.

I’ve tried today to upgrade (again) over testing and the os-release had not changed.

martignoni commented 1 year ago

There is a misunderstanding here: I'm speaking of recent releases of RPiOS images.

And my bad: I did not notice that your image was upgraded. For the record, upgrading an RPi image to a new OS version is not recommended and not supported. I assume rpi-clone too is not supported in these cases.

Side note: Debian testing versions never have a VERSION_ID defined.

gpongelli commented 1 year ago

There is a misunderstanding here: I'm speaking of recent releases of RPiOS images.

And my bad: I did not notice that your image was upgraded. For the record, upgrading an RPi image to a new OS version is not recommended and not supported. I assume rpi-clone too is not supported in these cases.

Even if it’s not recommended, it can be done (and it worked, waiting for official bookworm), so why rpi-clone shouldn’t also be supported ?

martignoni commented 1 year ago

If you find a way to check for a version number in Debian testing release, I'd be glad to include it in this PR.

framps commented 1 year ago

Not sure what's the purpose of this check. Maybe it's worth to remove this check?

martignoni commented 1 year ago

This is needed because as of RPiOS Buster (and later), the boot partition size has changed. See https://github.com/billw2/rpi-clone/blob/07f536e9d93cb5b50635415ee0fa46f498614ee4/rpi-clone#L1348-L1356 and https://github.com/billw2/rpi-clone/blob/07f536e9d93cb5b50635415ee0fa46f498614ee4/rpi-clone#L1609-L1624.

gpongelli commented 1 year ago

Hi @martignoni , I've just tested rpi-clone on my rpi and it worked correctly.

The only changes I did had been this one here:


    if ((raspbian)) && [[ "$pretty" == *"buster"* ]]
    then
        raspbian_buster=1
    fi
+   if ((raspbian)) && [[ "$pretty" == *"bookworm"* ]]
+   then
+       raspbian_buster=1
+   fi

this because there's no way to get version 11 with any of following methods:

No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux bookworm/sid
Release:    n/a
Codename:   bookworm
PRETTY_NAME="Raspbian GNU/Linux bookworm/sid"
NAME="Raspbian GNU/Linux"
VERSION_CODENAME=bookworm
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
 Static hostname: ...
       Icon name: computer
      Machine ID:....
         Boot ID: ....
Operating System: Raspbian GNU/Linux bookworm/sid 
          Kernel: Linux 5.15.84-v7l+
    Architecture: arm
martignoni commented 1 year ago

Your "fix" would not fix the bug: the problem will occur again when Debian reaches its next version after Bookworm.

framps commented 1 year ago

Agree. Then every new Debian version requires a change in rpi-clone. Wouldn't it make sense to test backwards and not forwards?

gpongelli commented 1 year ago

I know it is not future-proof, but it’s just to demonstrate that rpi-clone works also on upgraded rpi (even not so pure raspbian, because in the past I’ve mixed it with Debian due to more recent sw version needed).

agree with @framps about reversing the detection logic

edit: To address future boot changes other than the one already in place (or any os changes that impacts rpi-clone), a more correct check could be done parsing history/release table in webpages like this one or this one through an external script.

framps commented 1 year ago

a more correct check could be done parsing history/release table in webpages

I agree. That's the more general approach. But this creates a dependency of rpi-clone on an existing network connection I don't like.

martignoni commented 1 year ago

Wouldn't it make sense to test backwards and not forwards?

Not sure I understand, can you elaborate?

framps commented 1 year ago

As @gpongelli wrote here he added a new if statement to set raspibian_buster. This will have to be done for every new release. Why don't we just negate the test and assume raspbian_buster is 1 and reset it to zero for older releases. They will not change any more :wink:

martignoni commented 1 year ago

Here are the PRETTY_NAMEs for all Raspbian/RPiOS supported releases:

32bit

PRETTY_NAME="Raspbian GNU/Linux 7 (wheezy)" PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)" PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)" PRETTY_NAME="Raspbian GNU/Linux 10 (buster)" PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"

64bit

PRETTY_NAME="Debian GNU/Linux 10 (buster)" PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"

For (unsupported) testing/sid releases, the PRETTY_NAME does not have any number and no VERSION_ID, as already said before. A few examples (we cannot exclude that some adventurous rpi-clone user has updated their official RPiOS buster version to a testing bullseye one):

32bit

PRETTY_NAME="Raspbian GNU/Linux bookworm/sid" PRETTY_NAME="Raspbian GNU/Linux bullseye/sid"

64bit

PRETTY_NAME="Debian GNU/Linux bullseye/sid" PRETTY_NAME="Debian GNU/Linux bookworm/sid"

We can conclude that for the test to work also for unsupported versions, we've to test whether the PRETTY_NAME contains either "wheezy", "jessie" or "stretch", and conclude that in this case this is not a recent version.

This (not as elegant as actual PR) bit of code would work. Any comment welcome: bash is not my first language 😊

rpios=0
rpios_recent=0
if [ -f /etc/os-release ]
then
  osversion=`cat /etc/os-release | grep PRETTY | cut -d'"' -f2`
  osversion=${osversion##* } # Remove everything before last space
  osversion=`echo ${osversion} | cut -d"(" -f2 | cut -d")" -f1` # Remove parens if needed
  osversion=${osversion%/*} # Remove everything after last slash
  if [[ -e /etc/rpi-issue ]]; then
    rpios=1
  fi
  if ((rpios)) && !([[ "${osversion}" = "wheezy" ]] || [[ "${osversion}" = "jessie" ]] || [[ "${osversion}" = "stretch" ]] ); then
    rpios_recent=1
  fi
fi
framps commented 1 year ago

I like regex :smile:

rpios=0
rpios_recent=0

if [[ -f /etc/os-release ]]; then
   if [[ -f /etc/rpi-issue ]]; then
      rpios=1
   fi
   pretty="$(grep PRETTY /etc/os-release)"
   if ((rpios)) && [[ ! "$pretty" =~ wheezy|jessie|stretch ]]; then
      rpios_recent=1
   fi
fi