Check manually for available updates

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.