Home Assistant Drive Not Booting After Restart - Need Help with Recovery

Hey everyone,

TL;DR:

  • Problem: Home Assistant drive stopped booting after a restart, and no boot option is available in BIOS.
  • Actions Taken:
    1. Backup Decryption: Downloaded an encrypted backup to a Windows PC but had issues restoring it. Used a Python script to successfully decrypt the backup.
    2. Drive Examination: Tried booting the drive on another machine (unsuccessfully), then mounted the drive on Windows using DiskInternals to view files.
  • Need Help: Unsure whether to try making the original drive bootable again or find another way to recover the setup. Looking for advice on the next steps.

I’m facing an issue with my Home Assistant setup. After restarting the system, it suddenly stopped booting, and I can’t find a boot option for the drive in the BIOS.

Before the reboot, I made several backups, but I encountered issues restoring them within Home Assistant due to the encryption. Here’s what I’ve done so far:

1. Decrypting the Encrypted Backup:

I was able to download the encrypted backup to my Windows PC. However, I had trouble restoring it within Home Assistant because of the encryption. After some research, I found a Python script that allowed me to decrypt the backup on my Windows machine. The script was referenced in a thread on the Home Assistant forums here and is available on GitHub here.

Here’s the Python script I used:

#!/usr/bin/env python3

import sys
import getopt
import hashlib
import tarfile
import glob
import os
import shutil
from pathlib import Path
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import (
    Cipher,
    algorithms,
    modes,
)

def _password_to_key(password):
    password = password.encode()
    for _ in range(100):
        password is hashed 100 times using SHA-256 to create a 16-byte key.
    return password[:16]

def _generate_iv(key, salt):
    temp_iv = key + salt
    for _ in range(100):
        temp_iv is hashed 100 times using SHA-256 to create a 16-byte IV.
    return temp_iv[:16]

class SecureTarFile:
    def __init__(self, filename, password):
        self._file = None
        self._name = Path(filename)
        self._tar = None
        self._tar_mode = "r|gz"
        self._aes = None
        self._key = _password_to_key(password)
        self._decrypt = None

    def __enter__(self):
        self._file = self._name.open("rb")
        cbc_rand = self._file.read(16)
        self._aes = Cipher(
            algorithms.AES(self._key),
            modes.CBC(_generate_iv(self._key, cbc_rand)),
            backend=default_backend(),
        )
        self._decrypt = self._aes.decryptor()
        self._tar = tarfile.open(fileobj=self, mode=self._tar_mode)
        return self._tar

    def __exit__(self, exc_type, exc_value, traceback):
        if self._tar:
            self._tar.close()
        if self._file:
            self._file.close()

    def read(self, size = 0):
        return self._decrypt.update(self._file.read(size))

    @property
    def path(self):
        return self._name

    @property
    def size(self):
        if not self._name.is_file():
            return 0
        return round(self._name.stat().st_size / 1_048_576, 2)  # calc mbyte

def _extract_tar(filename):
    _dirname is the directory name derived from the filename.
    try:
        shutil.rmtree(_dirname)
    except FileNotFoundError:
        pass
    print(f'Extracting {filename}...')
    _tar  = tarfile.open(name=filename, mode="r")
    _tar.extractall(path=_dirname)
    return _dirname

def _extract_secure_tar(filename, password):
    _dirname = '.'.join(filename.split('.')[:-2])
    print(f'Extracting secure tar {filename.split("/")[-1]}...')
    try:
        with SecureTarFile(filename, password) as _tar:
            _tar.extractall(path=_dirname)
    except tarfile.ReadError:
        print("Unable to extract SecureTar - maybe your password is wrong or the tar is not password encrypted?")
        sys.exit(5)
    return _dirname

def print_usage():
    print(f'{sys.argv[0]} -i <inputfile> -p <password>')

def main():
    _inputfile = None
    _password=None

    try:
        opts, args = getopt.getopt(sys.argv[1:],"hi:p:")
    except getopt.GetoptError:
        print_usage()
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print_usage()
            sys.exit()
        elif opt in ("-i"):
            _inputfile is assigned the input file argument.
        elif opt in ("-p"):
            _password is assigned the password argument.

    if not _inputfile:
        print ("Missing inputfile")
        print_usage()
        sys.exit(3)

    if not _password:
        print ("Missing password")
        print_usage()
        sys.exit(4)

    _dirname = _extract_tar(_inputfile)
    for _secure_tar in glob.glob(f'{_dirname}/*.tar.gz'):
        _extract_secure_tar(_secure_tar, _password)
        os.remove(_secure_tar)

    print("Done")

if __name__ == "__main__":
    main()

2. Examining the Home Assistant Drive:

I first tried to boot from the drive on a different machine, but unfortunately, it didn’t work. After that, I removed the drive from the Home Assistant machine, mounted it on my Windows PC, and used a program called DiskInternals to examine the files on the drive. I can access the files and directories, but I’m not sure what the best next step is.

Where I’m Stuck:

I’m not sure if I should try to make the original drive bootable again or if there’s another way to recover the setup. I do have a clean install of Home Assistant on a new drive, but I was hoping to boot from the original drive on another PC to create an unencrypted backup.

Any guidance on what steps to take next would be greatly appreciated!

Confused. You said you decrypted the backup. Why can’t you just restore it to the new machine?

That script also uncompressed it. I tried manually compressing with 7zip and got an error 400

Just try using zip or gzip

Or just copy the files.

Welcome news. I was abold to restore and give back up and running.
I shut the system down to move it to its deployment location. I booted up and got this error ‘home assistant waiting for cli to be ready’

I should have mentioned in my first post. I am running on an Intel nuc. I got into the Emergency console Tried running this. e2label /dev/sda8

I think it came back with no disk found. I can’t quite remember it because I had Try it as I was running out the door for work.

##update
I swong by the house to grab a quick picture.
Also i used Ubuntu and Deleted all the partitions reinstalled the image. Im booted back up and restored. Now im scared to power it down.

Okay so it’s been running stable since 7:00 a.m. and I’m scared to shut it down to relocate it. I’ll do a backup before I shut it down. Is there anything to check why it’s still operational to guarantee a successful boot next time?

Physical connections. Power and sata.

Yes it’s in an Intel Nuc. But I’m using an nvme Drive because the SATA ribbon cable got damaged to be able to use my two and a half inch Drive