Snapctl not working and asking for context

When using snapctl command in shell of a snap or even on console I get following error:

test1@localhost:~$ snapctl get core
error: error running snapctl: cannot get without a context
test1@localhost:~$

But using snap command I get o/p

test1@localhost:/home/test1$ snap get core watchdog
Key                        Value
watchdog.runtime-timeout   3m
watchdog.shutdown-timeout  8m
test1@localhost:/home/test1$

How to generate this context? Even when using snapd-glib I get context error.

the context is an environment variable … i think it is generated by snap-confine on app startup … (probably @zyga-snapd can elaborate on this) …

$ snap run --shell htop -c "env | grep CONTEXT"
SNAP_CONTEXT=NpsLw3N2bWw4JMbmR2xp208n29RX28nfSp5tgNGcqhGS

snapctl can only run inside a snap, it isnt designed for interactive use …

So, I did run the snapctl inside a snap shell as well

test1@localhost:/home/test1$ env | grep CONTEXT
SNAP_CONTEXT=-zW8yoHmXaxQfUzVcNxy39iP-2qphTU2aJNkib2XgUtk3QM3olwy
test1@localhost:/home/test1$ snapctl get core

test1@localhost:/home/test1$ sudo snapctl get core
error: error running snapctl: cannot get without a context
test1@localhost:/home/test1$

dont run sudo inside snaps either (it might behave differently than you expect :wink: )

better do the privilege escalation outside when calling snap run --shell

well, it returned {} … i’m not sure an unprivileged snap is actually allowed to query/set core settings without using snapd-control and the snapd REST API …

Have tried using snapd REST API via snapd-glib too (code snippet below). I get same issue.

g_auto(GStrv) args = g_strsplit ("get;core;watchdog", ";", -1);
g_autofree gchar *stdout_output = NULL;
g_autofree gchar *stderr_output = NULL;
gboolean result = snapd_client_run_snapctl_sync (client, "ABC", args, &stdout_output, &stderr_output, NULL, &error);
g_assert_no_error (error);

By unprivileged what do you mean? Some type of assertion (snap-declaration)? I have that too:

test1@localhost:~$ snap known snap-declaration snap-name=[REMOVED INTENTIONALLY]
type: snap-declaration
authority-id: canonical
series: 16
snap-id: [REMOVED INTENTIONALLY]
publisher-id: [REMOVED INTENTIONALLY]
snap-name: [REMOVED INTENTIONALLY]
timestamp:  [REMOVED INTENTIONALLY]
sign-key-sha3-384: [REMOVED INTENTIONALLY]

AcLBUgQAAQo[REMOVED INTENTIONALLY]M10ckqwNLN
test1@localhost:~$

well, did you also add/connect the snapd-control plug before attempting to use snapd-glib ? just using the library does not magically grant access for your snap to the REST API.

with unprivileged i mean a snap not using the REST API and not using the extra privileges the snapd-control interface grants …

Thanks @ogra . Had missed it. But even after adding snapd-control:

ERROR:/home/xyz/parts/dev-stat/src/dev_stat.c:608:main: assertion failed (error == NULL): access denied (snapd-error-quark, 5)

root@localhost:/home/test1# snap connections | grep snapd-control
snapd-control            [MASKED]:snapd-control     :snapd-control          manual
root@localhost:/home/test1#

Tried using
sudo journalctl --output=short --follow --all | sudo snappy-debug -r

but didn’t get anything there

well, i’m not sure if snapd-control works for locally installed snaps, it is tightly tied to brand stores so it might not work easily without one … (i have never played with it outside of a brand-store context)

Well, this is a brand store app. A basic version is present in store. Since I am enhancing it, I am not pushing it store and installing. Instead I’m building the snap in host, scp’ing it to device and then installing in devmode.

test1@localhost:~$ snap list | grep [REMOVED]
[REMOVED]    0.0.2.2             x21   latest/beta  -               devmode
test1@localhost:~$

If you have missed, the snap-declaration that I gave above suggests its a brand store app.

I was wrong in using the snap that I did for this experiment. It did not have snap-declaration for snapd-control. When used within a snap having snapd-control declaration, this worked.

Also, understood that snapctl works only in context of a snap. When run in a shell of snap (using sudo snap run --shell .) with following code, able to get output.

char ctx[100];
snprintf(ctx, 100, "%s", getenv("SNAP_CONTEXT"));
snapd_client_set_socket_path(client, "/run/snapd.socket");
g_auto(GStrv) args = g_strsplit ("services", ";", -1);
g_auto(GStrv) args = g_strsplit ("get;core;watchdog", ";", -1);
g_autofree gchar *stdout_output = NULL;
g_autofree gchar *stderr_output = NULL;
gboolean result = snapd_client_run_snapctl_sync (client, ctx, args, &stdout_output, &stderr_output, NULL, &error);
g_assert_no_error (error);
g_assert_true (result);
printf("stdout: %s\n", stdout_output);
printf("stderr: %s\n", stderr_output);