Hello,
I’m trying to check for updates using the API so users or our device can upgrade at their convenience. I get the 200 or 204 HTTP responses depending on wether there is an update or not as expected. But if there is an update and I run mender check-update
I get a 409 Conflict response.
from base64 import b64encode
import json
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
import requests
import requests.auth
import requests.packages
from requests.exceptions import ConnectionError as RequestsConnectionError
SERVER = 'https://eu.hosted.mender.io/api/devices/v1'
def sign(data, key) -> bytes:
signer = PKCS1_v1_5.new(key)
digest = SHA256.new()
digest.update(data.encode())
signed = signer.sign(digest)
return b64encode(signed)
def authenticate(api: requests.Session) -> None:
with open('/var/lib/mender/mender-agent.pem') as private_key_file:
private_key = RSA.importKey(private_key_file.read())
data = json.dumps({
'id_data': json.dumps({'SerialNumber': 'abc-12345'}),
'pubkey': str(private_key.publickey().exportKey(), 'utf-8') + '\n',
'tenant_token': '**********',
})
signature = sign(data, private_key)
headers = {
'X-MEN-Signature': signature,
'Content-Type': 'application/json',
'Accept': 'application/json',
}
rsp = api.post(f'{SERVER}/authentication/auth_requests',
data=data, headers=headers)
if rsp.status_code != 200:
raise ValueError(
'Authentication failed - {} - {}\n{}'.format(
rsp.status_code, rsp.reason, rsp.text
)
)
api.headers['Authorization'] = 'Bearer {}'.format(rsp.text)
def check_for_updates(api) -> None:
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
}
params = {
'artifact_name': 'v0.6.7',
'device_type': 'raspberrypi-cm3',
}
rsp = api.get(
f'{SERVER}/deployments/device/deployments/next',
headers=headers,
params=params,
)
if rsp.status_code == 204:
print('No updates available')
return
elif rsp.status_code != 200:
raise ValueError(
f'Could not check for updates: {rsp.status_code} - {rsp.reason}')
print('Update available')
with requests.Session() as api:
authenticate(api)
check_for_updates(api)
And this is the log:
Apr 10 12:14:28 abc-12345 mender[651]: time="2023-04-10T12:14:28Z" level=info msg="Forced wake-up from sleep"
Apr 10 12:14:28 abc-12345 mender[651]: time="2023-04-10T12:14:28Z" level=info msg="Forcing state machine to: update-check"
Apr 10 12:14:28 abc-12345 mender[651]: time="2023-04-10T12:14:28Z" level=info msg="State transition: check-wait [Idle] -> update-check [Sync]"
Apr 10 12:14:28 abc-12345 mender[651]: time="2023-04-10T12:14:28Z" level=info msg="Validating the Update Info: https://mender.blob.core.windows.net/artifacts/63d0e1084382797544ae12fe%2Fc61b5d2e-8688-4a38-a666-af555d5f19db?rscd=attachment%3B+filename%3D%22v0.6.8.mender%22&se=2023-04-11T12%3A14%3A28Z&sig=HiNbtuzLFAc3I2atOeBo209zI%2FqVRLxAQ6vXtjBbS4E%3D&sp=r&sr=b&st=2023-04-10T12%3A14%3A28Z&sv=2020-02-10 [name: v0.6.8; devices: [raspberrypi-cm3]]"
Apr 10 12:14:28 abc-12345 mender[651]: time="2023-04-10T12:14:28Z" level=info msg="State transition: update-check [Sync] -> update-fetch [Download_Enter]"
Apr 10 12:14:28 abc-12345 mender[651]: time="2023-04-10T12:14:28Z" level=info msg="Running Mender client version: 3.5.0"
Apr 10 12:14:30 abc-12345 mender[651]: time="2023-04-10T12:14:30Z" level=info msg="State transition: update-fetch [Download_Enter] -> update-store [Download_Enter]"
Apr 10 12:14:30 abc-12345 mender[651]: time="2023-04-10T12:14:30Z" level=info msg="Installer: authenticated digital signature of artifact"
Apr 10 12:14:30 abc-12345 mender[651]: time="2023-04-10T12:14:30Z" level=info msg="Opening device \"/dev/mmcblk0p2\" for writing"
Apr 10 12:14:30 abc-12345 mender[651]: time="2023-04-10T12:14:30Z" level=info msg="Native sector size of block device /dev/mmcblk0p2 is 512 bytes. Mender will write in chunks of 1048576 bytes"
Thanks.