def make_configuration_apply_script(setup_tester_ssh_connection, script): # Enable writes run( setup_tester_ssh_connection, "mount -o remount,rw /", ) # Install the apply-device-config script tf = NamedTemporaryFile(delete=False) tf.write(script.encode("utf-8")) tf.close() try: run( setup_tester_ssh_connection, "mkdir -p /usr/lib/mender-configure/apply-device-config.d", ) put( setup_tester_ssh_connection, tf.name, key_filename=tf.name, remote_path="/usr/lib/mender-configure/apply-device-config.d/integration-test", ) run( setup_tester_ssh_connection, "chmod 755 /usr/lib/mender-configure/apply-device-config.d/integration-test", ) finally: os.unlink(tf.name) # Disable writes run( setup_tester_ssh_connection, "mount -o remount,ro /", )
def test_mender_configure_successful_install_needs_reboot( setup_test_container, setup_tester_ssh_connection): # Install a configuration apply script which requires reboot make_configuration_apply_script(setup_tester_ssh_connection, "#/bin/sh\nexit 20\n") # Generate a simple configuration artifact configuration = {"key": "value"} configuration_artifact = tempfile.NamedTemporaryFile(suffix=".mender", delete=False) configuration_artifact_name = configuration_artifact.name make_configuration_artifact(configuration, "configuration-artifact", configuration_artifact_name) # Install the configuration artifact try: put( setup_tester_ssh_connection, configuration_artifact_name, key_filename=setup_test_container.key_filename, remote_path="/data/configuration-artifact.mender", ) result = run( setup_tester_ssh_connection, "mender install /data/configuration-artifact.mender", warn=True, ) logging.debug(result) assert result.exited == 0 assert ( "At least one payload requested a reboot of the device it updated." in result.stdout) finally: os.unlink(configuration_artifact_name) # Verify the content of the configuration result = run( setup_tester_ssh_connection, "cat /var/lib/mender-configure/device-config.json", ) logging.debug(result) assert result.exited == 0 assert "key" in result.stdout, result assert "value" in result.stdout, result device_config = json.loads(result.stdout) assert device_config == configuration # Verify the needs-reboot file result = run( setup_tester_ssh_connection, "ls /data/mender/modules/v3/payloads/0000/tree/tmp/needs-reboot", warn=True, ) logging.debug(result) assert result.exited == 0
def set_timezone(timezone): with tempfile.NamedTemporaryFile() as fd: fd.write(("""{"timezone":"%s"}""" % timezone).encode()) fd.flush() put( setup_tester_ssh_connection, fd.name, key_filename=setup_test_container.key_filename, remote_path="/data/mender-configure/device-config.json", ) run( setup_tester_ssh_connection, "/usr/lib/mender-configure/apply-device-config.d/timezone /data/mender-configure/device-config.json", )
def test_timezone_script(setup_test_container, setup_tester_ssh_connection): run(setup_tester_ssh_connection, "mount / -o remount,rw") try: run( setup_tester_ssh_connection, "mkdir -p /usr/lib/mender-configure/apply-device-config.d", ) put( setup_tester_ssh_connection, "../../scripts/timezone", key_filename=setup_test_container.key_filename, remote_path= "/usr/lib/mender-configure/apply-device-config.d/timezone", ) run(setup_tester_ssh_connection, "mkdir -p /data/mender-configure") def set_timezone(timezone): with tempfile.NamedTemporaryFile() as fd: fd.write(("""{"timezone":"%s"}""" % timezone).encode()) fd.flush() put( setup_tester_ssh_connection, fd.name, key_filename=setup_test_container.key_filename, remote_path="/data/mender-configure/device-config.json", ) run( setup_tester_ssh_connection, "/usr/lib/mender-configure/apply-device-config.d/timezone /data/mender-configure/device-config.json", ) set_timezone("UTC") res = run(setup_tester_ssh_connection, "timedatectl status") assert re.search("Time zone: *UTC", res.stdout) is not None old_hour = run(setup_tester_ssh_connection, "date +%H").stdout.strip() set_timezone("Asia/Tokyo") res = run(setup_tester_ssh_connection, "timedatectl status") assert re.search("Time zone: *Asia/Tokyo", res.stdout) is not None new_hour = run(setup_tester_ssh_connection, "date +%H").stdout.strip() assert abs(int(new_hour) - int(old_hour)) > 5 finally: run(setup_tester_ssh_connection, "timedatectl set-timezone UTC") run(setup_tester_ssh_connection, "mount / -o remount,ro")
def test_mender_configure_successful_install(setup_test_container, setup_tester_ssh_connection): # Install a no-op configuration apply script make_configuration_apply_script(setup_tester_ssh_connection, "#/bin/sh\nexit 0\n") # Generate a simple configuration artifact configuration = {"key": "value"} configuration_artifact = tempfile.NamedTemporaryFile(suffix=".mender", delete=False) configuration_artifact_name = configuration_artifact.name make_configuration_artifact(configuration, "configuration-artifact", configuration_artifact_name) # Install the configuration artifact try: put( setup_tester_ssh_connection, configuration_artifact_name, key_filename=setup_test_container.key_filename, remote_path="/data/configuration-artifact.mender", ) result = run( setup_tester_ssh_connection, "mender install /data/configuration-artifact.mender", warn=True, ) logging.debug(result) assert result.exited == 0 finally: os.unlink(configuration_artifact_name) # Verify the content of the configuration result = run( setup_tester_ssh_connection, "cat /var/lib/mender-configure/device-config.json", ) logging.debug(result) assert "key" in result.stdout, result assert "value" in result.stdout, result device_config = json.loads(result.stdout) assert device_config == configuration # commit the installation result = run( setup_tester_ssh_connection, "mender commit", warn=True, ) logging.debug(result) assert result.exited == 0 # Generate a new configuration artifact configuration = {"new-key": "new-value"} configuration_artifact = tempfile.NamedTemporaryFile(suffix=".mender", delete=False) configuration_artifact_name = configuration_artifact.name make_configuration_artifact(configuration, "new-configuration-artifact", configuration_artifact_name) # Install the configuration artifact try: put( setup_tester_ssh_connection, configuration_artifact_name, key_filename=setup_test_container.key_filename, remote_path="/data/new-configuration-artifact.mender", ) result = run( setup_tester_ssh_connection, "mender install /data/new-configuration-artifact.mender", warn=True, ) logging.debug(result) assert result.exited == 0 finally: os.unlink(configuration_artifact_name) # Verify the content of the configuration result = run( setup_tester_ssh_connection, "cat /var/lib/mender-configure/device-config.json", ) logging.debug(result) assert "new-key" in result.stdout, result assert "new-value" in result.stdout, result device_config = json.loads(result.stdout) assert device_config == configuration
def test_mender_configure_failed_install_apply_fails( setup_test_container, setup_tester_ssh_connection): # Install a configuration apply script which fails in applying the new configuration make_configuration_apply_script( setup_tester_ssh_connection, """#/bin/sh if grep -q new-key "$1"; then exit 2 fi exit 0 """, ) # Install a pre-existing configuration configuration = {"key": "value"} configuration_file = tempfile.NamedTemporaryFile(suffix=".json", delete=False) configuration_file_name = configuration_file.name open(configuration_file_name, "w").write(json.dumps(configuration)) put( setup_tester_ssh_connection, configuration_file_name, key_filename=setup_test_container.key_filename, remote_path="/var/lib/mender-configure/device-config.json", ) os.unlink(configuration_file_name) # capture artifact and provides result = run( setup_tester_ssh_connection, "mender show-artifact 2>/dev/null", ) artifact = result.stdout result = run( setup_tester_ssh_connection, "mender show-provides 2>/dev/null", ) provides = result.stdout # Generate a simple configuration artifact new_configuration = {"new-key": "new-value"} configuration_artifact = tempfile.NamedTemporaryFile(suffix=".mender", delete=False) configuration_artifact_name = configuration_artifact.name make_configuration_artifact(new_configuration, "configuration-artifact", configuration_artifact_name) # Install the configuration artifact try: put( setup_tester_ssh_connection, configuration_artifact_name, key_filename=setup_test_container.key_filename, remote_path="/data/configuration-artifact.mender", ) result = run( setup_tester_ssh_connection, "mender install /data/configuration-artifact.mender", warn=True, ) logging.debug(result) assert result.exited != 0 assert ( "Installation failed: Update module terminated abnormally: exit status 2" in result.stderr) finally: os.unlink(configuration_artifact_name) # Verify the content of the configuration result = run( setup_tester_ssh_connection, "cat /var/lib/mender-configure/device-config.json", warn=True, ) logging.debug(result) assert result.exited == 0 assert "key" in result.stdout, result assert "value" in result.stdout, result device_config = json.loads(result.stdout) assert device_config == configuration # capture the new artifact and provides and verify they didn't change result = run( setup_tester_ssh_connection, "mender show-artifact 2>/dev/null", ) new_artifact = result.stdout result = run( setup_tester_ssh_connection, "mender show-provides 2>/dev/null", ) new_provides = result.stdout assert (new_artifact, new_provides) == (artifact, provides)
def test_mender_configure_failed_install_config_is_a_folder( setup_test_container, setup_tester_ssh_connection): # Install a no-op configuration apply script make_configuration_apply_script(setup_tester_ssh_connection, "#/bin/sh\nexit 0\n") # Lock the configuration file with a folder run( setup_tester_ssh_connection, "mkdir -p /var/lib/mender-configure/device-config.json", ) # capture artifact and provides result = run( setup_tester_ssh_connection, "mender show-artifact 2>/dev/null", ) artifact = result.stdout result = run( setup_tester_ssh_connection, "mender show-provides 2>/dev/null", ) provides = result.stdout # Generate a simple configuration artifact new_configuration = {"new-key": "new-value"} configuration_artifact = tempfile.NamedTemporaryFile(suffix=".mender", delete=False) configuration_artifact_name = configuration_artifact.name make_configuration_artifact(new_configuration, "configuration-artifact", configuration_artifact_name) # Install the configuration artifact try: put( setup_tester_ssh_connection, configuration_artifact_name, key_filename=setup_test_container.key_filename, remote_path="/data/configuration-artifact.mender", ) result = run( setup_tester_ssh_connection, "mender install /data/configuration-artifact.mender", warn=True, ) logging.debug(result) assert result.exited != 0 assert ( "Installation failed: Update module terminated abnormally: exit status 1" in result.stderr) finally: os.unlink(configuration_artifact_name) # capture the new artifact and provides and verify they didn't change result = run( setup_tester_ssh_connection, "mender show-artifact 2>/dev/null", ) new_artifact = result.stdout result = run( setup_tester_ssh_connection, "mender show-provides 2>/dev/null", ) new_provides = result.stdout assert (new_artifact, new_provides) == (artifact, provides)