summaryrefslogtreecommitdiffstats
path: root/recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2024-05-12 15:28:59 -0400
committerScott Murray <scott.murray@konsulko.com>2024-05-27 16:03:25 +0000
commit2e0fd28b2470f6d81bfb1b0b273af5742060ed6a (patch)
treebc485361a96ada08b826b02f7141ae5f7565c2f9 /recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb
parentea7e39dc258c5e7d3a46ffb31b3321331ba9e900 (diff)
Rework KVM demo configuration
Changes: - Move KVM demo configuration and image recipes to a new sub-layer, meta-agl-kvm-demo, to keep things that may not be buildable with just the agl-demo feature separate to avoid confusion. It will hopefully also avoid clutter in recipes-platform/images. This sub-layer is pulled in when the agl-kvm setup feature is given to aglsetup.sh. - Remove the agl-kvm-host-kuksa and agl-kvm-host-audio setup features. - Add new *-guest and *-guest-preconfigured flavors of the Flutter IVI and IC images under meta-agl-kvm-demo that that have the desired configuration changes baked in. - Add required qemu-config recipe variants for the new guest image flavors. At the moment there is more duplication of configuration for this than is desired, and some reworking of agl-qemu-runner configuration may come as a follow up to avoid this. - Remove qemu-config recipe variants for unused Qt guest images. If it becomes desirable to use the Qt demo images as guests this can be revisited. - Added agl-kvm-demo-flutter-preconfigured image variant that supports the full demo setup (i.e. "green machine" with steering wheel, equivalent to CES 2024 demos). NOTES: - The agl-kvm-demo image remains and builds roughly the same image as before, with the KUKSA.val databroker running in the IVI guest and cluster support enabled. Replacing this image with a bbclass abstraction and an e.g. agl-kvm-demo-flutter image is under consideration. Bug-AGL: SPEC-5138 Change-Id: I64936208fd032e5ba47366e3a7ff572dc18338e4 Signed-off-by: Scott Murray <scott.murray@konsulko.com> Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl-demo/+/29918 ci-image-build: Jenkins Job builder account Tested-by: Jenkins Job builder account ci-image-boot-test: Jenkins Job builder account
Diffstat (limited to 'recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb')
-rw-r--r--recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb29
1 files changed, 0 insertions, 29 deletions
diff --git a/recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb b/recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb
deleted file mode 100644
index f0bc93fd3..000000000
--- a/recipes-config/qemu-config/qemu-config-agl-cluster-demo-flutter.bb
+++ /dev/null
@@ -1,29 +0,0 @@
-SUMMARY = "Setting files for agl-cluster-demo-plaform-flutter guest VM"
-LICENSE = "MIT"
-LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
-
-inherit systemd allarch
-
-SRC_URI = "file://${QEMU_IMAGE}.conf"
-
-do_configure[noexec] = "1"
-do_compile[noexec] = "1"
-
-QEMU_IMAGE = "agl-cluster-demo-flutter"
-QEMU_UNIT = "agl-qemu-runner@${QEMU_IMAGE}.service"
-
-do_install() {
- # Install template unit links
- install -d ${D}${systemd_system_unitdir}
- ln -sf agl-qemu-runner@.service ${D}${systemd_system_unitdir}/${QEMU_UNIT}
- install -d ${D}${systemd_system_unitdir}/multi-user.target.wants
- ln -sf ${systemd_system_unitdir}/${QEMU_UNIT} ${D}${systemd_system_unitdir}/multi-user.target.wants/${QEMU_UNIT}
-
- # Install conf file
- install -d ${D}${sysconfdir}/agl-qemu-runner
- install -m 0644 ${WORKDIR}/${QEMU_IMAGE}.conf ${D}${sysconfdir}/agl-qemu-runner/
-}
-
-FILES:${PN} += "${systemd_system_unitdir}"
-
-RDEPENDS:${PN} += "agl-qemu-runner qemu-config-vmnet0"
eral.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (C) 2016 "IoT.bzh"
 * Author Fulup Ar Foll <fulup@iot.bzh>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, something express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <json-c/json_object.h> 

#include "wrap-json.h"
#include "ctl-binding.h"

STATIC PolicyCtlConfigT *ctlHandle = NULL;

// List Avaliable Configuration Files
STATIC json_object* ScanForConfig (char* searchPath) {
    json_object *responseJ;
    DIR  *dirHandle;
    char *dirPath;
    char* dirList= strdup(searchPath);
    
    responseJ = json_object_new_array();
    for (dirPath= strtok(dirList, ":"); dirPath && *dirPath; dirPath=strtok(NULL,":")) {
         struct dirent *dirEnt;
         
        dirHandle = opendir (dirPath);
        if (!dirHandle) {
            AFB_NOTICE ("CONFIG-SCANNING dir=%s not readable", dirPath);
            continue;
        } 
        
        AFB_NOTICE ("CONFIG-SCANNING:ctl_listconfig scanning: %s", dirPath);
        while ((dirEnt = readdir(dirHandle)) != NULL) {
            // Unknown type is accepted to support dump filesystems
            if (dirEnt->d_type == DT_REG || dirEnt->d_type == DT_UNKNOWN) {
                struct json_object *pathJ = json_object_new_object();
                json_object_object_add(pathJ, "dirpath", json_object_new_string(dirPath));
                json_object_object_add(pathJ, "filename", json_object_new_string(dirEnt->d_name));
                json_object_array_add(responseJ, pathJ);
            }
        }
    }
    
    free (dirList);    
    return (responseJ);
}

PUBLIC void ctlapi_authorize (PolicyCtlEnumT control, afb_req request) {
    json_object*tmpJ;
    
    json_object* queryJ= afb_req_json(request);
    int done=json_object_object_get_ex(queryJ, "closing", &tmpJ);
    if (done) return;
    
}


// List Avaliable Configuration Files
PUBLIC void ctlapi_config (struct afb_req request) {
    json_object*tmpJ;
    char *dirList;
    
    json_object* queryJ = afb_req_json(request);
    if (queryJ && json_object_object_get_ex (queryJ, "cfgpath" , &tmpJ)) {
        dirList = strdup (json_object_get_string(tmpJ));
    } else {    
        dirList = strdup (CONTROL_CONFIG_PATH); 
        AFB_NOTICE ("CONFIG-MISSING: use default CONTROL_CONFIG_PATH=%s", CONTROL_CONFIG_PATH);
    }
   
    // get list of config file
    struct json_object *responseJ = ScanForConfig(dirList);
    
    if (json_object_array_length(responseJ) == 0) {
       afb_req_fail(request, "CONFIGPATH:EMPTY", "No Config Found in CONTROL_CONFIG_PATH"); 
    } else {
        afb_req_success(request, responseJ, NULL);
    }
    
    return;
}

STATIC PolicyActionT **PolicyLoadActions (json_object *actionsJ) {
    int err;
    PolicyActionT ** actions;
    
    // unpack individual action object
    int actionUnpack (json_object *actionJ,  PolicyActionT *action) {
        
        err= wrap_json_unpack(actionJ, "{ss,s?s,s?s,s?s,s?s,s?s !}"
            , "label",&action->label, "info",&action->info, "callback",&action->callback, "query",&queryJ, "api",&action->api, "verb", &action->verb);
        if (err) {
            AFB_ERROR ("POLICY-LOAD-ACTION Missing something label|info|callback|api|verb|query in %s", json_object_get_string(actionJ));
            return -1;
        }
        if (!action->callback || !(action->api && action->verb)) {
            AFB_ERROR ("POLICY-LOAD-ACTION Missing something callback|(api+verb) in %s", json_object_get_string(actionJ));            
            return -1;            
        }        
        return 0;
    };
            
    // action array is close with a nullvalue;
    if (json_object_get_type(actionsJ) == json_type_array) {
        int count = json_object_array_length(actionsJ);
        actions = calloc (count+1, sizeof(PolicyActionT));
        
        for (int idx=0; idx < count; idx++) {
            json_object *actionJ = json_object_array_get_idx(actionsJ, idx);
            err = actionUnpack (actionJ, &actions[idx]);
            if (err) goto OnErrorExit;
        }
        
    } else {
        actions = calloc (2, sizeof(PolicyActionT));  
        err = actionUnpack (actionsJ, &actions[0]);
        if (err) goto OnErrorExit;
    }
    
    return actions;
    
 OnErrorExit:
    return NULL;
    
}

// load control policy from file using json_unpack https://jansson.readthedocs.io/en/2.9/apiref.html#parsing-and-validating-values
STATIC PolicyCtlConfigT *PolicyLoadConfig (const char* filepath) {
    json_object *policyConfigJ, *ignoreJ, *actionsJ;
    PolicyCtlConfigT *policyConfig = calloc (1, sizeof(PolicyCtlConfigT));
    int err;
    
    // Load JSON file
    policyConfigJ= json_object_from_file(filepath);
    if (!policyConfigJ) goto OnErrorExit;
    
    json_object *metadataJ, *onloadJ, *controlsJ, *eventsJ;
    err= wrap_json_unpack(policyConfigJ, "{s?o,so,s?o,so,so !}", "$schema", &ignoreJ, "metadata",&metadataJ, "onload",&onloadJ, "controls",&controlsJ, "events",&eventsJ);
    if (err) {
        AFB_ERROR ("POLICY-LOAD-ERRROR Missing something metadata|onload|controls|events in %s", json_object_get_string(policyConfigJ));
        goto OnErrorExit;
    }
    
    PolicyHandleT *policyHandle = calloc (1, sizeof(PolicyHandleT));
    err= wrap_json_unpack(metadataJ, "{so,s?s,s?s !}", "label", &policyHandle->label, "info",&policyHandle->info, "version",&policyHandle->version);
    if (err) {
        AFB_ERROR ("POLICY-LOAD-CONFIG Missing something label|info|version in %s", json_object_get_string(metadataJ));
        goto OnErrorExit;
    }
    
    if (onloadJ) {
        err= wrap_json_unpack(onloadJ, "{s?o,s?s,s?s !}", "info",&ignoreJ, "label",&ignoreJ, "actions",&actionsJ);
        if (err) {
            AFB_ERROR ("POLICY-LOAD-CONFIG Missing something label|info|plugin|actions in %s", json_object_get_string(metadataJ));
            goto OnErrorExit;
        }
        policyConfig->onload = PolicyLoadActions (actionsJ);
    }
    
    return policyControl;
    
OnErrorExit:
    return NULL;
}

// Load default config file at init
PUBLIC int PolicyInit () {
    int index, err;
    
    
    // search for default policy config file
    json_object* responseJ = ScanForConfig(CONTROL_CONFIG_PATH);
    
    for (index=0; index < json_object_array_length(responseJ); index++) {
        json_object *entryJ=json_object_array_get_idx(responseJ, index);
        
        char *filename; char*dirpath;
        err= wrap_json_unpack (entryJ, "{s:s, s:s !}", "dirpath",  &dirpath,"filename", &filename);
        if (err) {
            AFB_ERROR ("POLICY-INIT HOOPs invalid config file path = %s", json_object_get_string(entryJ));
            goto OnErrorExit;
        }
        
        if (strcasestr(filename, CONTROL_CONFIG_FILE)) {
            char filepath[255];
            strncpy(filepath, dirpath, sizeof(filepath)); 
            strncat(filepath, "/", sizeof(filepath)); 
            strncat(filepath, filename, sizeof(filepath)); 
            ctlHandle = PolicyLoadConfig (filepath);
            if (!ctlHandle) goto OnErrorExit;
            break;
        }
    }
    
    // no policy config found remove control API from binder
    if (index == 0)  goto OnErrorExit;
    
    AFB_NOTICE ("SUCCES: Audio Control Policy Init");
    return 0;
    
OnErrorExit:
    AFB_NOTICE ("ERROR: Audio Control Policy Init");
    return 1;    
}