summaryrefslogtreecommitdiffstats
path: root/meta-agl-lxc/recipes-graphics
diff options
context:
space:
mode:
authorNaoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>2021-10-10 00:50:39 +0900
committerNaoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>2021-11-22 12:08:19 +0900
commitd8ab3ff4c17bc7638f366822ca7907fd58edff42 (patch)
tree8bf71fd5f0d32f649c1dcc68a4a48d2826560607 /meta-agl-lxc/recipes-graphics
parentc75a3e084b4cb988e0bdb31b7a9618fdb5a5bdf2 (diff)
Create image specific weston setting method
In patch of "Fix: weston is not running after BSP 5.5 merged in cluster-demo", I created common weston-init recipe for container guest. This patch add image specific weston setting method. Bug-AGL: SPEC-4099 Signed-off-by: Naoto Yamaguchi <naoto.yamaguchi@aisin.co.jp> Change-Id: I0a47749932dc384e8a983b43214aefd939ccd06e
Diffstat (limited to 'meta-agl-lxc/recipes-graphics')
-rw-r--r--meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.cluster-guest.ini (renamed from meta-agl-lxc/recipes-graphics/wayland/weston-init-guest/weston.ini)2
-rw-r--r--meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.default.ini9
-rw-r--r--meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.ivi-guest.ini14
-rw-r--r--meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest_0.1.bb34
-rw-r--r--meta-agl-lxc/recipes-graphics/wayland/weston-init-guest_0.1.bb19
5 files changed, 67 insertions, 11 deletions
diff --git a/meta-agl-lxc/recipes-graphics/wayland/weston-init-guest/weston.ini b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.cluster-guest.ini
index 2c05c58a..c709d60d 100644
--- a/meta-agl-lxc/recipes-graphics/wayland/weston-init-guest/weston.ini
+++ b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.cluster-guest.ini
@@ -6,4 +6,4 @@ repaint-window=34
[shell]
panel-position=none
-background-color=0xff808080
+background-color=0xff000000
diff --git a/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.default.ini b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.default.ini
new file mode 100644
index 00000000..c709d60d
--- /dev/null
+++ b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.default.ini
@@ -0,0 +1,9 @@
+[core]
+backend=drm-backend.so
+require-input=false
+modules=systemd-notify.so
+repaint-window=34
+
+[shell]
+panel-position=none
+background-color=0xff000000
diff --git a/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.ivi-guest.ini b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.ivi-guest.ini
new file mode 100644
index 00000000..a664f5e0
--- /dev/null
+++ b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest/weston.ivi-guest.ini
@@ -0,0 +1,14 @@
+[core]
+shell=ivi-shell.so
+backend=drm-backend.so
+require-input=false
+modules=systemd-notify.so,ivi-controller.so
+
+[ivi-shell]
+ivi-input-module=ivi-input-controller.so
+ivi-id-agent-module=ivi-id-agent.so
+
+[desktop-app-default]
+default-surface-id=9801
+default-surface-id-max=9821
+
diff --git a/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest_0.1.bb b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest_0.1.bb
new file mode 100644
index 00000000..740fa8ff
--- /dev/null
+++ b/meta-agl-lxc/recipes-graphics/wayland/weston-ini-conf-guest_0.1.bb
@@ -0,0 +1,34 @@
+SUMMARY = "Configuration file for the Weston and AGL Wayland compositors for guest container"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
+
+SRC_URI = " \
+ file://weston.default.ini \
+ file://weston.cluster-guest.ini \
+ file://weston.ivi-guest.ini \
+"
+
+S = "${WORKDIR}"
+
+inherit allarch
+
+# Default weston.ini
+WESTON_INI_FILE ??= "weston.default.ini"
+
+# Set container specific weston.ini
+WESTON_INI_FILE:aglcontainercluster ?= "weston.cluster-guest.ini"
+WESTON_INI_FILE:aglcontainerivi ?= "weston.ivi-guest.ini"
+
+do_install() {
+ install -D -p -m0644 ${WORKDIR}/${WESTON_INI_FILE} ${D}${sysconfdir}/xdg/weston/weston.ini
+}
+
+FILES:${PN} += " \
+ ${sysconfdir}/xdg/weston/weston.ini \
+ "
+CONFFILES:${PN} += " \
+ ${sysconfdir}/xdg/weston/weston.ini \
+ "
+RDEPENDS:${PN} = "weston-init-guest"
+RPROVIDES:${PN} = "weston-ini"
+RCONFLICTS:${PN} = "weston-ini-conf"
diff --git a/meta-agl-lxc/recipes-graphics/wayland/weston-init-guest_0.1.bb b/meta-agl-lxc/recipes-graphics/wayland/weston-init-guest_0.1.bb
index e18dbe52..c95f92e0 100644
--- a/meta-agl-lxc/recipes-graphics/wayland/weston-init-guest_0.1.bb
+++ b/meta-agl-lxc/recipes-graphics/wayland/weston-init-guest_0.1.bb
@@ -2,9 +2,7 @@ SUMMARY = "Startup script and systemd unit file for the Weston Wayland composito
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/COPYING.MIT;md5=3da9cfbcb788c80a0384361b4de20420"
-
SRC_URI = "file://weston.env \
- file://weston.ini \
file://weston.service \
"
@@ -13,7 +11,6 @@ S = "${WORKDIR}"
inherit features_check systemd
do_install() {
- install -D -p -m0644 ${WORKDIR}/weston.ini ${D}${sysconfdir}/xdg/weston/weston.ini
install -Dm644 ${WORKDIR}/weston.env ${D}${sysconfdir}/default/weston
# Install Weston systemd service and accompanying udev rule
@@ -26,22 +23,24 @@ do_install() {
PACKAGE_ARCH = "${MACHINE_ARCH}"
-# rdepends on weston which depends on virtual/egl
+# rdepends on weston-init-guest which depends on wayland
REQUIRED_DISTRO_FEATURES = "wayland"
-FILES_${PN} += " \
+FILES:${PN} += " \
${sysconfdir}/xdg/weston/weston.ini \
${systemd_system_unitdir}/weston.service \
${sysconfdir}/default/weston \
"
-CONFFILES_${PN} += " \
+CONFFILES:${PN} += " \
${sysconfdir}/xdg/weston/weston.ini \
${sysconfdir}/default/weston \
"
SYSTEMD_PACKAGES = "${PN}"
-SYSTEMD_SERVICE_${PN} = "weston.service"
+SYSTEMD_SERVICE:${PN} = "weston.service"
SYSTEMD_AUTO_ENABLE = "enable"
-RDEPENDS_${PN} = "weston"
-
-RCONFLICTS_${PN} = "weston-init"
+RDEPENDS:${PN} = " \
+ weston \
+ weston-ini \
+ "
+RCONFLICTS:${PN} = "weston-init"
e */ .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) 2018 "IoT.bzh"
 * Author "Romain Forlot" <romain.forlot@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, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "influxdb.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <systemd/sd-event.h>

#include "../utils/list.h"

struct metrics_list {
	struct series_t serie;
	json_object *metricsJ;
	afb_api_t api;
};

static void fill_n_send_values(void *c, json_object *valuesJ)
{
	struct list *it = NULL;
	int length = json_object_get_string_len(valuesJ), i = 0, j = 0;
	struct metrics_list *m_list = (struct metrics_list *)c;
	json_object *one_metric = json_object_new_object();

	for (i = 0; i < length; i++) {
		if(!i)
			m_list->serie.timestamp = json_object_get_int64(valuesJ);
		else {
			if(set_value(m_list->serie.serie_columns.tags, valuesJ, i)) {
				if(set_value(m_list->serie.serie_columns.fields, valuesJ, j)) {
					AFB_API_ERROR(m_list->api, "No tags nor fields fits.");
				}
				j++;
			}
		}
	}

	/* Build a metric object to add in the JSON array */
	json_object_object_add(one_metric, "name", json_object_new_string(m_list->serie.name));
	json_object_object_add(one_metric, "timestamp", json_object_new_int64(m_list->serie.timestamp));
	for(it = m_list->serie.serie_columns.tags; it != NULL; it = it->next)
		json_object_object_add(one_metric, m_list->serie.serie_columns.tags->key, m_list->serie.serie_columns.tags->value);
	for(it = m_list->serie.serie_columns.fields; it != NULL; it = it->next)
		json_object_object_add(one_metric, m_list->serie.serie_columns.fields->key, m_list->serie.serie_columns.fields->value);

	json_object_array_add(m_list->metricsJ, one_metric);
}

static void fill_key(void *c, json_object *columnJ)
{
	int length = json_object_get_string_len(columnJ);
	const char *column = json_object_get_string(columnJ);
	struct metrics_list *m_list = (struct metrics_list *)c;

	if(strncasecmp(&column[length-2], "_t", 2) == 0) {
		add_key(&m_list->serie.serie_columns.tags, column, "");
	}
	else if(strncasecmp(&column[length-2], "_f", 2) == 0) {
		add_key(&m_list->serie.serie_columns.fields, column, "");
	}
}

static void unpack_metric_from_db(void *ml, json_object *metricJ)
{
	struct metrics_list *m_list = (struct metrics_list*)ml;
	json_object *columnsJ = NULL, *valuesJ = NULL;

	if(wrap_json_unpack(metricJ, "{ss, so, so!}",
					 "name", &m_list->serie.name,
					 "columns", &columnsJ,
					 "values", &valuesJ)) {
		AFB_API_ERROR(m_list->api, "Unpacking metric goes wrong");
		return;
	 }

	wrap_json_array_for_all(columnsJ, fill_key, m_list);
	wrap_json_array_for_all(valuesJ, fill_n_send_values, m_list);
}

static json_object *unpack_series(afb_api_t apiHandle, json_object *seriesJ)
{
	struct metrics_list m_list = {
		.serie = {
			.name = NULL,
			.serie_columns = {
				.tags = NULL,
				.fields = NULL
			},
			.timestamp = 0
		},
		.metricsJ = json_object_new_array(),
		.api = apiHandle
	};

	wrap_json_array_for_all(seriesJ, unpack_metric_from_db, (void*)&m_list);

	return m_list.metricsJ;
}

static void forward_to_garner(afb_api_t apiHandle, const char *result, size_t size)
{
	int id = 0;
	json_object *resultsJ = NULL,
				*seriesJ = NULL,
				*metrics2send = NULL,
				*call_resultJ = NULL,
				*db_dumpJ = json_tokener_parse(result);

	if( wrap_json_unpack(db_dumpJ, "{so!}",
					 "results", &resultsJ) ||
		wrap_json_unpack(resultsJ, "[{si,so!}]",
					 "statement_id", &id,
					 "series", &seriesJ)) {
//		AFB_DEBUG("Unpacking results from influxdb request. Request results was:\n%s", result);
		return;
	}

	if(seriesJ) {
		metrics2send = unpack_series(apiHandle, seriesJ);
		if(json_object_array_length(metrics2send)) {
			if(afb_api_call_sync_legacy(apiHandle, "garner", "write", metrics2send, &call_resultJ)) {
				AFB_API_ERROR(apiHandle, "Metrics were sent but not done, an error happens. Details: %s", json_object_to_json_string(call_resultJ));
			}
		}
	}
	else {
		AFB_API_ERROR(apiHandle, "Empty response. Request results was:\n%s", result);
	}
}

static void influxdb_read_curl_cb(void *closure, int status, CURL *curl, const char *result, size_t size)
{
	if(!closure)
		return;
	afb_api_t apiHandle = (afb_api_t)closure;
	long rep_code = curl_wrap_response_code_get(curl);
	switch(rep_code) {
		case 200:
			AFB_API_DEBUG(apiHandle, "Read correctly done");
			forward_to_garner(apiHandle, result, size);
			break;
		case 400:
			AFB_API_ERROR(apiHandle, "Unacceptable request. %s", result);
			break;
		case 401:
			AFB_API_ERROR(apiHandle, "Invalid authentication. %s", result);
			break;
		default:
			AFB_API_ERROR(apiHandle, "Unexptected behavior. %s", result);
			break;
	}
}

static CURL *make_curl_query_get(afb_api_t apiHandle, const char *url)
{
	CURL *curl;
	char *args[5];
	char query[255] = {};
	char last_ts[30] = {};
	char *now;
	int length_now;

	args[0] = "epoch";
	args[1] = "ns";
	args[2] = "q";
	strcat(query, "SELECT * FROM /^.*$/");
	args[4] = NULL;
	length_now = asprintf(&now, "%lu", get_ts());

	int rootdir_fd = afb_api_rootdir_get_fd(apiHandle);
	int fd_last_read = openat(rootdir_fd, "last_db_read", O_CREAT | O_RDWR, S_IRWXU);
	if (fd_last_read < 0)
		return NULL;

	/* Reading last timestamp recorded and get metric from that point until now
	   else write the last timestamp */
	if(read(fd_last_read, last_ts, sizeof(last_ts)) == 0) {
		if(write(fd_last_read, now, length_now) != length_now)
			AFB_API_ERROR(apiHandle, "Error writing last_db_read file: %s\n", strerror( errno ));
	}
	else {
		strcat(query, " WHERE time >= ");
		strncat(query, last_ts, strlen(last_ts));
		close(fd_last_read);
		fd_last_read = openat(rootdir_fd, "last_db_read", O_TRUNC | O_RDWR);
		if (write(fd_last_read, now, length_now) != length_now)
			AFB_API_ERROR(apiHandle, "Error writing last_db_read file: %s", strerror( errno ));
	}

	args[3] = query;
	curl = curl_wrap_prepare_get(url, NULL, (const char * const*)args);

	return curl;
}

static int influxdb_read(sd_event_source *s, uint64_t usec, void *userdata)
{
	CURL *curl;
	struct reader_args *r_args = NULL;
	CtlSourceT *source = NULL;
	if(userdata) {
		source = (CtlSourceT*)userdata;
		r_args = (struct reader_args*)source->context;
	}
	else {
		return ERROR;
	}

	char url[URL_MAXIMUM_LENGTH]; /* Safe limit for most popular web browser */

	make_url(url, sizeof(url), r_args->host, r_args->port, "query");
	curl = make_curl_query_get(source->api, url);
	curl_wrap_do(curl, influxdb_read_curl_cb, (void*)source->api);

	/* Reschedule next run */
	sd_event_source_set_time(s, usec + r_args->delay);

	return 0;
}

/*
 * TODO RFOR: reader functions are not used for the moment
 */
CTLP_CAPI(read_from_influxdb, source, argsJ, eventJ)
{
	int err = 0;
	uint64_t usec;
	struct sd_event_source *evtSource = NULL;

	/* Set a cyclic cb call each 1s to call the read callback */
	sd_event_now(afb_api_get_event_loop(source->api), CLOCK_MONOTONIC, &usec);
	err = sd_event_add_time(afb_api_get_event_loop(source->api), &evtSource, CLOCK_MONOTONIC, usec+1000000, 250, influxdb_read, (void*)source);
	if(!err)
		err = sd_event_source_set_enabled(evtSource, SD_EVENT_ON);

	return err;
}