Upgrading/updating Home Assistant with a script

Tags: #<Tag:0x00007f326c2f43b0>

Hi all,
I am trying to upgrade Home Assistant with a shellscript

ha_update: pip3 install homeassistant=={{ states.sensor.ha_version_latest }}

Then I run from the UI:
shell_command.ha_update
But this throws me an error

Error running command: `pip3 install homeassistant=={{ states.sensor.ha_version_latest }}`, return code: 1

NoneType: None

The sensor is populated by a MQTT command:


So am I doing something wrong or is that approach in general doable?
Thanks for all hints.
Br

I assume then you’re running the Home Assistant Core install method? Look in Configuration -> Info

yes i do use the manual installation of HA. I guess that is what you call HA core

Why not leave the version argument out if you’re always updating to the latest available?

1 Like

Have a look at the log file and see what was logged when you ran it, there should be some error/warning/whatever

When I run it with the basic upgrade command:

pip3 install --upgrade homeassistant

I get a timeout error?

2020-11-04 17:16:13 ERROR (MainThread) [homeassistant.components.shell_command] Timed out running command: `pip3 install --upgrade homeassistant`, after: 60s
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/components/shell_command/__init__.py", line 81, in async_service_handler
    process.communicate(), COMMAND_TIMEOUT
  File "/usr/lib/python3.7/asyncio/tasks.py", line 423, in wait_for
    raise futures.TimeoutError()
concurrent.futures._base.TimeoutError

As of 0.114 shell commands are limited to 60 seconds runtime.

Thanks.
Any other solutions to update HA “within HA”?
BR

In my own experience, this will almost always take more than 60 seconds because even after the update is complete, other components are updated on first run.

Have you thought about just detecting the change and calling an external script to handle the update itself and maybe just read the output or result you want from a log somewhere?

I’ll admit it’s not a thing I’ve ever wanted to do.

My process is:

  1. Config check
  2. Upgrade
  3. Config check
  4. Fix all the problems
  5. Restart HA

That doesn’t lend itself to mashing a button in HA

1 Like

Hi and thanks for all the replies. Very much appreciated.

how would I achieve this?

Some background. I need to maintain several “sub” instances of HA that I don´t have direct access to (at least not to the “backend”). So the the idea was:

  1. Test the HA version on my main HA instance
  2. Post the HA version to upgrade to (not the most recent one) on a webserver
  3. Create a sensor on the the sub HA instances that fetches the HA version to.
  4. create an automation on the sub HA instance that will check on latest version and current version and if latest version > current version run a script to do the upgrade.
  5. Upgrade is applied on next scheduled restart

Of course i could create a cron job on my RPI to do the job but I would like to avoid this when there is a solution “inside” HA.
Hope that explains something.
Thanks and regards

How will you handle a broken upgrade then? What happens when HA fails to start?

You need shell (SSH) access to these systems. At the very least interactive access to upgrade/downgrade HA, and start the service.

In exceptions I could always get ssh access.

Simplicity ftw! :wink:

I admit it’s tough to not see every problem as a nail when you have a very nice shiny hammer :thinking:

That´s though not solving my problem. I might look into appdaemon

Using the shell command you may be able to fork a process that is outside the scope of the 60 second timeout.

I tried to do exactly this by using nohup in the shell command:

ssh -i /pathtokey/keyfile [email protected] "nohup sh /pathtoscript/update_ha.sh &"

The script below DOES work when run from the command line, but for some reason that has escaped me it doesn’t work when called from within HA (HA stops and then restarts without updating). This is on a Mac running in a VENV so some of the commands would change for a Pi.

#!/bin/bash

launchctl bootout gui/<uid> '/Users/username/Library/LaunchAgents/org.homeassistant.plist'
wait
source '/Users/username/homeassistant/bin/activate'
pip3 install --upgrade homeassistant
wait
deactivate
launchctl bootstrap gui/<uid> '/Users/username/Library/LaunchAgents/org.homeassistant.plist'

Nice! Well, I would redirect to a log file to troubleshoot. Another option (other than nohup) would be screen.

You should be able to avoid source/deactivate by calling /Users/username/homeassistant/bin/pip3 install --upgrade homeassistant

Well @bbrendon I’m not sure what part of your advice worked, but my button in HA now successfully shuts it down, updates to the latest version, and restarts (at least it did once). It doesn’t make any sense, but it seemed like adding a custom output file is what made the difference.
The shell command:

  update_ha: 'ssh -i /Users/username/.homeassistant/ssh/keyfile [email protected] "nohup sh /Users/username/.homeassistant/www/scripts/update_ha.sh > update_ha.out 2>&1"'

The script:

#!/bin/bash

launchctl bootout gui/<uid> '/Users/username/Library/LaunchAgents/org.homeassistant.plist'
wait
/Users/username/homeassistant/bin/pip3 install --upgrade homeassistant
wait
launchctl bootstrap gui/<uid> '/Users/username/Library/LaunchAgents/org.homeassistant.plist'

1 Like

For those who are interested in the solution that I implemented in the end. All intentions to upgrade HA within HA failed (or at least I couldn´t find a way to do so). So I modified the script a little bit and run it as cron job (once a month).

 !/bin/bash

# stop HA

sudo systemctl stop [email protected]

# Become user 'homeassistant'

sudo su -s /bin/bash homeassistant <<'EOF'

# Activate the virtualenv

source /srv/homeassistant/bin/activate

# Install Home Assistant

pip3.8 install -r /home/homeassistant/.homeassistant/homeassistant_requirement.txt --log /home/homeassistant/.homeassistant/homeassistant_update_log.txt

exit

EOF

# start HA

sudo systemctl start [email protected]

What I do is to populate the

homeassistant_requirement.txt

file with a install command like:

homeassistant==2020.12.1
1 Like