~aleteoryx/muditaos

d78756363915ab8360ccc19e94d9c04be126401b — lblach 5 years ago 46f4d35
[EGD-5309] Add a new message Abort in Update endpoint API

In order to be able to interrupt the OS update after its launch in
the phone, it was necessary to implement the new "Abort" message
for the Update Endpoint API.
M module-services/service-desktop/endpoints/update/UpdateEndpoint.cpp => module-services/service-desktop/endpoints/update/UpdateEndpoint.cpp +19 -0
@@ 35,6 35,25 @@ auto UpdateEndpoint::handle(Context &context) -> void

auto UpdateEndpoint::run(Context &context) -> sys::ReturnCodes
{
    std::string cmd = context.getBody()[parserFSM::json::updateprocess::command].string_value();
    if (cmd == parserFSM::json::updateprocess::commands::abort) {
        auto owner        = static_cast<ServiceDesktop *>(ownerServicePtr);
        auto currentState = owner->updateOS->status;
        if (currentState <= updateos::UpdateState::ExtractingFiles) {
            owner->updateOS->setUpdateAbortFlag(true);
            context.setResponseBody(json11::Json::object({{parserFSM::json::updateprocess::updateAborted, true}}));
            context.setResponseStatus(http::Code::OK);
            MessageHandler::putToSendQueue(context.createSimpleResponse());
            return sys::ReturnCodes::Success;
        }
        else {
            context.setResponseBody(json11::Json::object({{parserFSM::json::updateprocess::updateAborted, false}}));
            context.setResponseStatus(http::Code::NotAcceptable);
            MessageHandler::putToSendQueue(context.createSimpleResponse());
            return sys::ReturnCodes::Failure;
        }
    }

    std::string fileName = context.getBody()["fileName"].string_value();
    auto path            = purefs::dir::getUpdatesOSPath() / fileName;
    auto fileExists      = std::filesystem::exists(path.c_str());

M module-services/service-desktop/endpoints/update/UpdateMuditaOS.cpp => module-services/service-desktop/endpoints/update/UpdateMuditaOS.cpp +36 -4
@@ 54,6 54,11 @@ UpdateMuditaOS::UpdateMuditaOS(ServiceDesktop *ownerService) : owner(ownerServic

updateos::UpdateError UpdateMuditaOS::setUpdateFile(fs::path updateFileToUse)
{
    if (isUpdateToBeAborted()) {
        setUpdateAbortFlag(false);
        return informError(updateos::UpdateError::UpdateAborted, "update aborted");
    }

    updateFile = purefs::dir::getUpdatesOSPath() / updateFileToUse;
    if (std::filesystem::exists(updateFile.c_str())) {
        versionInformation = UpdateMuditaOS::getVersionInfoFromFile(updateFile);


@@ 78,7 83,7 @@ updateos::UpdateError UpdateMuditaOS::setUpdateFile(fs::path updateFileToUse)

updateos::UpdateError UpdateMuditaOS::runUpdate()
{
    informDebug("Prepraring temp dir");
    informDebug("Preparing temp dir");

    updateRunStatus.startTime   = utils::time::getCurrentTimestamp().getTime();
    updateRunStatus.fromVersion = bootConfig.to_json();


@@ 86,20 91,33 @@ updateos::UpdateError UpdateMuditaOS::runUpdate()

    updateos::UpdateError err = prepareTempDirForUpdate();
    if (err != updateos::UpdateError::NoError) {
        return informError(err, "runUpdate can't prepare temp directory for update");
        if (err == updateos::UpdateError::UpdateAborted) {
            return informError(updateos::UpdateError::UpdateAborted, "update aborted");
        }
        else {
            return informError(err, "runUpdate can't prepare temp directory for update");
        }
    }

    informDebug("Unpacking update");
    if ((err = unpackUpdate()) == updateos::UpdateError::NoError) {
    err = unpackUpdate();
    if (err == updateos::UpdateError::NoError) {
        informUpdate(status, "Unpacked");
    }
    else if (err == updateos::UpdateError::UpdateAborted) {
        return informError(updateos::UpdateError::UpdateAborted, "update aborted");
    }
    else {
        return informError(err, "%s can't be unpacked", updateFile.c_str());
    }

    if ((err = verifyChecksums()) == updateos::UpdateError::NoError) {
    err = verifyChecksums();
    if (err == updateos::UpdateError::NoError) {
        informUpdate(status, "Verify checksums");
    }
    else if (err == updateos::UpdateError::UpdateAborted) {
        return informError(updateos::UpdateError::UpdateAborted, "update aborted");
    }
    else {
        return informError(err, "Checksum verification failed");
    }


@@ 149,6 167,10 @@ updateos::UpdateError UpdateMuditaOS::unpackUpdate()
    status = updateos::UpdateState::ExtractingFiles;
    std::rewind(updateTar.stream);
    while ((mtar_read_header(&updateTar, &tarHeader)) != MTAR_ENULLRECORD) {
        if (isUpdateToBeAborted()) {
            setUpdateAbortFlag(false);
            return updateos::UpdateError::UpdateAborted;
        }
        if (std::string(tarHeader.name) == "./") {
            mtar_next(&updateTar);
            continue;


@@ 200,6 222,11 @@ std::string UpdateMuditaOS::readContent(const char *filename) noexcept

updateos::UpdateError UpdateMuditaOS::verifyChecksums()
{
    if (isUpdateToBeAborted()) {
        setUpdateAbortFlag(false);
        return informError(updateos::UpdateError::UpdateAborted, "update aborted");
    }

    status = updateos::UpdateState::ChecksumVerification;

    auto lineBuff = std::make_unique<char[]>(


@@ 491,6 518,11 @@ const fs::path UpdateMuditaOS::getUpdateTmpChild(const fs::path &childPath)

updateos::UpdateError UpdateMuditaOS::prepareTempDirForUpdate()
{
    if (isUpdateToBeAborted()) {
        setUpdateAbortFlag(false);
        return updateos::UpdateError::UpdateAborted;
    }

    status = updateos::UpdateState::CreatingDirectories;

    updateTempDirectory = purefs::dir::getTemporaryPath() / utils::filesystem::generateRandomId(updateos::prefix_len);

M module-services/service-desktop/endpoints/update/UpdateMuditaOS.hpp => module-services/service-desktop/endpoints/update/UpdateMuditaOS.hpp +11 -1
@@ 66,7 66,8 @@ namespace updateos
        NoBootloaderFile,
        CantOpenBootloaderFile,
        CantAllocateBuffer,
        CantLoadBootloaderFile
        CantLoadBootloaderFile,
        UpdateAborted
    };

    enum class UpdateState


@@ 171,10 172,19 @@ class UpdateMuditaOS : public updateos::UpdateStats
    {
        return updateHistory;
    }
    void setUpdateAbortFlag(bool flag)
    {
        updateAbort = flag;
    }
    bool isUpdateToBeAborted() const noexcept
    {
        return updateAbort;
    }

  private:
    std::vector<FileInfo> filesInUpdatePackage;
    mtar_t updateTar      = {};
    std::atomic_bool updateAbort = false;
    ServiceDesktop *owner = nullptr;

    void storeRunStatusInDB();

M module-services/service-desktop/parser/ParserUtils.hpp => module-services/service-desktop/parser/ParserUtils.hpp +11 -0
@@ 130,6 130,7 @@ namespace parserFSM
        inline constexpr auto errorCode        = "errorCode";
        inline constexpr auto statusCode       = "statusCode";
        inline constexpr auto updateHistory    = "updateHistory";

        namespace filesystem
        {
            inline constexpr auto command = "command";


@@ 141,6 142,16 @@ namespace parserFSM
            } // namespace commands
        }     // namespace filesystem

        namespace updateprocess
        {
            inline constexpr auto command       = "command";
            inline constexpr auto updateAborted = "updateAborted";
            namespace commands
            {
                inline constexpr auto abort = "abort";
            } // namespace commands
        }     // namespace updateprocess

        namespace messages
        {
            inline constexpr auto id           = "id";