Automatic Updates Still Not Quite Right

Hi - Following on from a previous post, after applying update 3.9.0 automatically via a Cron job (Using Titanfall’s upgrade script) I received a ‘Whoops something went wrong’ when browsing to the site. If I specify /update in the URL it displays ‘update successful’ and everything works.

The script is working wonders, but it’s almost as if Invoice Ninja is not reading version.txt in /storage after each update, thus forcing me to manually specify /update.

Previously I believed it may have had something to do with permissions, when copying the files over WinSCP - obviously this is no longer the case now.

Any ideas what’s going on here?

Thanks

Contents of laraval-error.log

[2017-10-31 08:18:47] production.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError [0] : /var/www/ninja/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007.php [Line 227] => Class ‘ZipArchive’ not found {“context”:“PHP”,“user_id”:1,“account_id”:1,“user_name”:“User”,“method”:“POST”,“url”:“URL/reports”,“previous”:“URL/reports”,“user_agent”:“Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36”,“ip”:“Gateway IP”,“count”:1,“is_console”:“no”,“is_api”:“no”,“db_server”:“mysql”} []
[2017-10-31 08:20:00] production.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError [0] : /var/www/ninja/vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007.php [Line 227] => Class ‘ZipArchive’ not found {“context”:“PHP”,“user_id”:1,“account_id”:1,“user_name”:“User”,“method”:“POST”,“url”:“URL/reports”,“previous”:“URL/reports”,“user_agent”:“Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36”,“ip”:“Gateway IP”,“count”:2,“is_console”:“no”,“is_api”:“no”,“db_server”:“mysql”} []
[2017-11-02 13:00:59] production.ERROR: Error: [BrotliDecompress] invalid distance {“context”:“JavaScript”,“user_id”:0,“account_id”:0,“user_name”:"",“method”:“GET”,“url”:“URL/view/1zvkjk1g3ke8thjofb1n8ytm09qpy3cy”,“previous”:“URL/view/1zvkjk1g3ke8thjofb1n8ytm09qpy3cy”,“user_agent”:“Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13G36 Safari/601.1”,“ip”:“Gateway IP”,“count”:1,“is_console”:“no”,“is_api”:“no”,“db_server”:“mysql”} []
[2017-11-09 11:34:37] production.ERROR: Illuminate\Database\QueryException [42S22] : /var/www/ninja/vendor/laravel/framework/src/Illuminate/Database/Connection.php [Line 729] => SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘invoices.partial_due_date’ in ‘field list’ (SQL: select coalesce(invoices.partial_due_date, invoices.due_date) due_date, invoices.balance, invoices.public_id, invoices.invoice_number, clients.name as client_name, contacts.email, contacts.first_name, contacts.last_name, clients.currency_id, clients.public_id as client_public_id, clients.user_id as client_user_id, invoice_type_id from invoices left join clients on clients.id = invoices.client_id left join contacts on contacts.client_id = clients.id where invoices.account_id = 1 and clients.deleted_at is null and contacts.deleted_at is null and invoices.is_recurring = 0 and invoices.quote_invoice_id is null and invoices.balance > 0 and invoices.is_deleted = 0 and invoices.deleted_at is null and invoices.is_public = 1 and contacts.is_primary = 1 and coalesce(invoices.partial_due_date, invoices.due_date) < 2017-11-09 order by invoices.due_date asc limit 50) {“context”:“PHP”,“user_id”:1,“account_id”:1,“user_name”:“User”,“method”:“GET”,“url”:“URL/dashboard”,“previous”:“URL/login”,“user_agent”:“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36”,“ip”:“Gateway IP”,“count”:1,“is_console”:“no”,“is_api”:“no”,“db_server”:“mysql”} []
[2017-11-09 11:34:42] production.ERROR: Illuminate\Database\QueryException [42S22] : /var/www/ninja/vendor/laravel/framework/src/Illuminate/Database/Connection.php [Line 729] => SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘invoices.partial_due_date’ in ‘field list’ (SQL: select coalesce(invoices.partial_due_date, invoices.due_date) due_date, invoices.balance, invoices.public_id, invoices.invoice_number, clients.name as client_name, contacts.email, contacts.first_name, contacts.last_name, clients.currency_id, clients.public_id as client_public_id, clients.user_id as client_user_id, invoice_type_id from invoices left join clients on clients.id = invoices.client_id left join contacts on contacts.client_id = clients.id where invoices.account_id = 1 and clients.deleted_at is null and contacts.deleted_at is null and invoices.is_recurring = 0 and invoices.quote_invoice_id is null and invoices.balance > 0 and invoices.is_deleted = 0 and invoices.deleted_at is null and invoices.is_public = 1 and contacts.is_primary = 1 and coalesce(invoices.partial_due_date, invoices.due_date) < 2017-11-09 order by invoices.due_date asc limit 50) {“context”:“PHP”,“user_id”:1,“account_id”:1,“user_name”:“User”,“method”:“GET”,“url”:“URL/dashboard”,“previous”:“URL/login”,“user_agent”:“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36”,“ip”:“Gateway IP”,“count”:2,“is_console”:“no”,“is_api”:“no”,“db_server”:“mysql”} []
[2017-11-09 11:35:39] production.ERROR: Illuminate\Database\QueryException [42S22] : /var/www/ninja/vendor/laravel/framework/src/Illuminate/Database/Conn

Thanks for the logs but they don’t explain why the version.txt file wasn’t read.

Permissions all look correct for /storage.

Any ideas why this is happening? - This is going to cause problems ultimately, as following all automatic updates I’m going to have to ensure I’m navigating to /update afterwards… which isn’t great.

Thanks

Version.txt is present, with the correct owner and permissions in /storage. It’s contents list the current version number… weird.

I’m not sure… one workaround may be to add a call to /update in the script.

Many thanks Hillel - I’ve contacted Titanfail to see if this is doable. What exactly is called when navigating to /update? Thanks

The database migrations are run and the cache is cleared.

So it runs?

composer dump-autoload --optimize
php artisan optimize --force
php artisan migrate
php artisan db:seed --class=UpdateSeeder

Yup

Would you mind pasting me the output of the cron when it runs the update?

Hi Titanfail - There’s not much to see in /var/syslog other than I can verify the script runs as scheduled with cron. I don’t have an MTA installed, so there isn’t any output.

Nov 9 03:00:01 hostname CRON[24972]: (root) CMD (/usr/local/bin/invoice_ninja_automatic_update_script_v4.5.7.sh)
Nov 9 03:03:15 hostname CRON[24971]: (CRON) info (No MTA installed, discarding output)
Nov 9 03:03:15 hostname CRON[24971]: (CRON) info (No MTA installed, discarding output)

The script is definitely updating Invoice Ninja - but for some reason I still need to navigate to /update in order to perform the database migrations, otherwise I just get a ‘whoops something went wrong’.

I suppose something could be added to the end of the script that would perform the database migration as mentioned above?

That should work, as long as it’s inside the case statement. Line 78 right before the status output would be a good place I’d think.

As for why the rest isn’t running when you go to login after an update, I honestly have no idea. The update script is just something I hammered together to automate the manual process, so there’s definitely something the scripts don’t like about your specific install, suddenly. What that is, is unfortunately above my skillset, as I’m not a developer. :frowning:

Thanks Titanfail - does this look OK?

	printf 'Removing downloaded ZIP file "%s" ...\n\nRemoving temporary folder "%s" ...\n\n' "$ninja_zip" "$tempdir"
	rm -rf "$tempdir/"
	
	#Perform database migration
	
	composer dump-autoload –optimize
	php artisan optimize –force
	php artisan migrate
	php artisan db:seed –class=UpdateSeeder

	printf '%s - Invoice Ninja successfully updated to v%s!\n\n' "$(date)" "$ninja_current"
	;;
esac

I’d recommend loading /update rather than run the commands separately.

How would I script doing that?

You could use wget

wget -O - https://ninja/update should work presumably