Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 62 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,76 +109,112 @@ Do not hesitate to fork this repository, and submit a pull request with your imp

## Landscape for IoT / Ubuntu Core devices

_Note: some scripts may require python3-requests deb (or PyPI requests) in order to function correctly. It is automatically installed in most environments (including the Landscape Client Snap) but that might not always be the case._
Scripts in this section use the [snap-http library](https://github.com/canonical/snap-http) to interact with the snapd REST API. The library is bundled with landscape-client.

### Snap Management

- **Tutorial**: Install a snap using a python wearfile and dump script output to a temporary file for debugging on the device.
- **Tutorial**: Install a snap and dump script output to a temporary file for debugging on the device.
- [**install-snap-debug.sh**](./core/snaps/install-snap-debug.sh)

- **Tutorial**: Install a snap using a python script and the SnapD REST API
- **Tutorial**: Install a snap
- [**install-snap.py**](./core/snaps/install-snap.py)

- **Tutorial**: Run an attached python script
- [**run-attached-script.sh**](./core/snaps/run-attached-script.sh)
- **Tutorial**: Remove a snap
- [**remove-snap.py**](./core/snaps/remove-snap.py)

- **Tutorial**: Install a snap using python and the snap-http library
- [**snap-http-install.py**](./core/snaps/snap-http-install.py)
- **Tutorial**: Refresh a snap
- [**refresh-snap.py**](./core/snaps/refresh-snap.py)

- **Tutorial**: Remove a snap using python and the snap-http library
- [**snap-http-remove.py**](./core/snaps/snap-http-remove.py)
- **Tutorial**: Hold snap updates
- [**hold-snaps.py**](./core/snaps/hold-snaps.py)

- **Tutorial**: Update snapd configuration using Python and the snap-http library
- [**update-snap-config.py**](./core/snaps/update-snap-config.py)
- **Tutorial**: Unhold snap updates
- [**unhold-snaps.py**](./core/snaps/unhold-snaps.py)

- **Tutorial**: Set the refresh timer using Python and the snap-http library
- **Tutorial**: Set the refresh timer
- [**set-refresh-timer.py**](./core/snaps/set-refresh-timer.py)

- **Tutorial**: Put device into managed mode (disable automatic snap refreshes)
- [**snap-http-remove.py**](./core/snaps/snap-http-managed-mode.py)
- **Tutorial**: Put a device into managed mode (disable automatic snap refreshes)
- [**managed-mode.py**](./core/snaps/managed-mode.py)

### Snap Configuration

- **Tutorial**: Get snap configuration
- [**get-conf.py**](./core/config/get-conf.py)

- **Tutorial**: Set snap configuration
- [**set-conf.py**](./core/config/set-conf.py)

### Snap Services

- **Tutorial**: Enable a snap service using Python and the snap-http library
- **Tutorial**: Enable a snap service
- [**enable-service.py**](./core/services/enable-service.py)

- **Tutorial**: Restart a snap service using Python and the snap-http library
- [**restart-services.py**](./core/services/restart-services.py)
- **Tutorial**: Restart a snap service
- [**restart-service.py**](./core/services/restart-service.py)

- **Tutorial**: Stop a snap service using Python and the snap-http library
- **Tutorial**: Stop a snap service
- [**stop-service.py**](./core/services/stop-service.py)

### Snap Interfaces

- **Tutorial**: Connect a snap interface using Python and the snap-http library
- **Tutorial**: Connect a snap interface
- [**connect-interface.py**](./core/interfaces/connect-interface.py)

- **Tutorial**: Disconnect a snap interface using Python and the snap-http library
- **Tutorial**: Disconnect a snap interface
- [**disconnect-interface.py**](./core/interfaces/disconnect-interface.py)

- **Tutorial**: Get interface connections using Python and the snap-http library
- **Tutorial**: Get interface connections
- [**get-connections.py**](./core/interfaces/get-connections.py)

### Logs

- **Tutorial**: Display logs for all snaps using Python and the snap-http library
- **Tutorial**: Display logs for a snap
- [**snapd-logs.py**](./core/logs/snapd-logs.py)

- **Tutorial**: Push landscape-client's logs to an FTP server using Python
- **Tutorial**: Push landscape-client's logs to an FTP server
- [**ftp-client-logs.py**](./core/logs/ftp-client-logs.py)

### User Management

- **Tutorial**: Add an Ubuntu SSO user to a Core device using Python and the snap-http library
- **Tutorial**: Add an Ubuntu SSO user to a Core device
- [**add-sso-user.py**](./core/users/add-sso-user.py)

- **Tutorial**: Add a system user to a Core device using Python and the snap-http library
- **Tutorial**: Add a system user to a Core device
- [**add-system-user.py**](./core/users/add-system-user.py)

- **Tutorial**: Remove a user from a Core device
- [**remove-user.py**](./core/users/remove-user.py)

### Confdb

- **Tutorial**: Enable the experimental confdb and confdb-control features
- [**enable-confdb.py**](./core/confdb/enable-confdb.py)

- **Tutorial**: Acknowledge a confdb-schema assertion into snapd
- [**acknowledge-confdb-schema.py**](./core/confdb/acknowledge-confdb-schema.py)

- **Tutorial**: Set values in a confdb view
- [**set-confdb.py**](./core/confdb/set-confdb.py)

- **Tutorial**: Get values from a confdb view
- [**get-confdb.py**](./core/confdb/get-confdb.py)

- **Tutorial**: Grant an operator delegated access to confdb views
- [**delegate-confdb.py**](./core/confdb/delegate-confdb.py)

- **Tutorial**: Revoke an operator's delegated confdb access
- [**undelegate-confdb.py**](./core/confdb/undelegate-confdb.py)

- **Tutorial**: Retrieve the confdb-control assertion
- [**get-confdb-control-assertion.py**](./core/confdb/get-confdb-control-assertion.py)

### Attachments

- **Tutorial**: Run an attached script
- [**run-attached-script.sh**](./core/attachments/run-attached-script.sh)

### Debugging

- **Tutorial**: Collect a large amount of SnapD and core system information that could be useful when debugging a system with Canonical Support
- [**snap-debug-info.py**](./debugging/snap-debug-info.sh)
- [**snap-debug-info.sh**](./debugging/snap-debug-info.sh)
3 changes: 3 additions & 0 deletions core/attachments/run-attached-script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

python3 $LANDSCAPE_ATTACHMENTS/restart-service.py
134 changes: 134 additions & 0 deletions core/confdb/acknowledge-confdb-schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env python3

from landscape.client import snap_http

# Acknowledge a confdb-schema assertion into snapd, along with its prerequisite
# account and account-key assertions.
assertion = """\
type: account
authority-id: canonical
account-id: f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN
display-name: Stephen Mwangi
timestamp: 2024-01-03T10:36:48.475339Z
username: st3v3nmw
validation: unproven
sign-key-sha3-384: BWDEoaqyr25nF5SNCvEv2v7QnM9QsfCc0PBMYD_i2NGSQ32EF2d4D0hqUel3m8ul

AcLBUgQAAQoABgUCZZU4wAAA0scQABIiB5aAhqNNv70gAJPq42FfzuFaH+0H8bEjDRaEt73kFmo9
ZzV2kHbr5r1WrZn7wPFqSrxBzi9dspCozc9nZi2pdV+S8xcFHFA29aGcGWrT3vs4U8Jv31ydqnQ8
iiwQbgPCVTeGHbAFJqn2pk4opcqLD74Cdh+6kVVmCc3XdcrPHvqI7Cowu6SbEEAGEhTTuLZOpXGr
/rcTtpZvDCw6lCTsUkkpqBgDB4gBZPKijKQpqN4cyKbh1UMlEZOd0u+c+uEtbFgHmLkL6BG9Szny
+SdWZTyHc3L332hPMunM941H+z0M1arGqmkkRaA+xXCdBRVOvqT7SCyxuApzi8Sm2qOoCWcqoFKj
AFdmfPg5Z1Sp6CyUzMRC3GuLODdMahdzz2zkxu4imYOgR4NqfSv5tbw+M2ZXk9Jv7kmdHU5i0scW
8zr8T28LbCCxdm1x8lFbytTDf6sa8iKOK9v3Sz4cEmrpJWikocVSOWLvE/2C8Fzkm2FJRiIZZ0BL
LCMocgEf1i0IaKw6/VdHn0m01uYS8y30Y72S8hkpUo0NTgj90a6Gw+/RDTXY+6F4IqwNhqQOQJBz
scsrCeNF7NkgKvDNJx/Cth11ztIWDHQsTagGElXLPvO7fNz47l5qVDFUH/MXj7GPzCkW5KBJ9AbU
RfhfoQ4nYrvl796kWhDsD08RRDJp

type: account-key
authority-id: canonical
public-key-sha3-384: xkd_Y2ay5N2Uo14v_wsCtfVJYLAVbJgxbiKM8Ne4mZBflaROriZgk2nb5i9Oebum
account-id: f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN
name: snapcraft
since: 2024-03-06T08:43:58Z
body-length: 717
sign-key-sha3-384: BWDEoaqyr25nF5SNCvEv2v7QnM9QsfCc0PBMYD_i2NGSQ32EF2d4D0hqUel3m8ul

AcbBTQRWhcGAARAAwfGMiOrB4ST1np6prpDWBlivmdkULG2F9QTYCnKz0uNmLkiHFqe4MN+XDtek
NPC66L0ZSx6IQ74ZLlb3/djdZ8t/mbI/d/nAL3IFrC5aYLrcKtX/e03lKDvzThQUFDPgB31PbZuD
XakbbSG9HjcLGBLVC/jMqBsKQaBarNkddSXwqL0FnKGLWbxIPnbuJ8Zxny/nW9+LU5E5LfuAvxNe
oBYO1cPOlhUfR0XhJiBQqKMDSRiXqIWrr2OYxrnDZgphIgo+WWBfqiYM3vSmNzt36R/AkyfrWq08
bU+s8nc22Ms4KlSYEWFVddz2hbhYvMrjoNgXq85J2O1DkQQWA9gOZXpxskFP3mEd2T/ofS028v0I
YHs4ST/QJWSTsJT2PhtUO6PeNjlAhZ4NMJZlnI3PJt/5c3d5He/SZ6H54B/19tMs3KAgxzXTX7Qx
646qFBF+1ZTsVeZ9UusEbyyZJDexcZVZiVKL+4K+xDjOlXo0Erm8luVkk0I4TwjLgPK8+aPsd0l6
t7rE0KcrUsPmoNcuca1++XD0dJNMwLNkCQDvXk7q0xIr7L/ue231I5dcPW0PT3d76wA/kR3woA+V
tO7yy1Qop0npAE4XzoNSTdlNCzsuWzUgCzlFwLnDIKGPNv3wZFIQUduou8YlAMu3ZTPNJduG0Ylh
RKvjES9B9mRBoNUAEQEAAQ==

AcLBUgQAAQoABgUCZegszgAAJ6AQALEDhdPkEhR5etc4St6D4jcdyt52+IXKUlhiqs+pU/37yHya
p1cSB6HufvykSGshusJ+JENaDOIMIu0zXWMbzJM+mUVYSRn+PLDc5jkgiZQin6FUDf5d+wby3B2B
L2slA3NPf21bYodqCGZPsYKg3V7hDhUIYDE4n12XY00lwU6RsA5e6t9CPJQb899W7hyRxNunfBnS
w5/zHPD+r88VnyKpwqHhbwxIJAtPTE+UFxq57HYwJXvvL5V3KZ/9iF7YyyAsy2FwMyJgpMkS/QSm
3B2KPcGB3tNtWAv3gVEzYcKnFqWfYXZP/qvhQVpB5aSUKTnQFWf0DLFARnfZJxuUNy4SQEVU0Xhq
ZVPiQUDj2HBR6QsLzYH4ySLGiL+iBygIVKYXnm5baP+XNJsN2BKU751aXT1keOELxgJmv8fBahQc
X9Lg/EinlvxBzsrtv+O6CHckVxEsxoVMhRNJM6nFd4dA8leXDxLd0NokMufRf3PDjMIupBSptS7Q
hGXqGUdVV+5PwT+5anvSnxRqd/6IqLrq9M3eBF2PdLGWP0Bx8IVVuIWGPGMMxvHDtYcfYVbcdxu3
LseyUyXh56uPMXPW2CVdAYHdTsSDVYD2l/ksYpA4Cd7tyBeJ7btWh8n9YsZ3HZrk6hasNF0VKURm
fvYaDRZCi27SyGIRI5OXQBmoa2zn

type: confdb-schema
authority-id: f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN
revision: 1
account-id: f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN
name: network
timestamp: 2026-01-21T10:19:23+00:00
views:
proxy-admin:
rules:
-
access: read-write
content:
-
request: url
storage: url
-
request: bypass
storage: bypass
request: {protocol}
storage: proxy.{protocol}
proxy-state:
rules:
-
access: read
request: https
storage: proxy.https
-
access: read
request: ftp
storage: proxy.ftp
body-length: 487
sign-key-sha3-384: xkd_Y2ay5N2Uo14v_wsCtfVJYLAVbJgxbiKM8Ne4mZBflaROriZgk2nb5i9Oebum

{
"storage": {
"aliases": {
"protocol": {
"choices": [
"http",
"https",
"ftp"
],
"type": "string"
}
},
"schema": {
"proxy": {
"keys": "${protocol}",
"values": {
"schema": {
"bypass": {
"type": "array",
"unique": true,
"values": "string"
},
"url": "string"
}
}
}
}
}
}

AcLBcwQAAQoAHRYhBHCftZeyXSJlNBvC+h+HHdMBlPLtBQJpjdWQAAoJEB+HHdMBlPLtomUP/iFa
BxCtGrwOzgVNbzmkSJXqf0LRbTGLyQQkCe5lV/X9PKBa4J+I4y7QGrUDAXQwvsSUJgcsR+99NgnA
IJE6mfZos8IXK/1TKRPUM/umeb4CfcLu6xuCwc/PFZnJhxTOK3FQddONXCXqCfQStx4KvRIfPu/S
nybbuMNQrepcvDSMY1YF18nX3kmC4WXnsySFJI5EDkdDNDC5C4mM85khyORdApHXSUewNVWghIP7
JjB0NeYxysJl3rrRcppfeGpB5Akx7lVJiTmGkCzvkDTymizMj4S6sveBGn5SLQPZz44X6jGG95il
EE//X9bM/bEEe2+s0gzIy4OWdDVVFU/X1uxzC6jlI+gwSpbhExKStdapC8nU7phoFvIlABLw7h2L
wFC7n84l95fR6f+9FPm1UKFqoBTO4pexTcihA3SNrKvD3oFyU3GnWZgfI1rgMOVdQnOYrOuaQMCO
lLZG0GgktRb9l/XekJexadsAnbhe8AF1Fb4pUM6eqAoIryy4CRetonlPyCDcFtOy+O4ARgsqYDfi
7YxA1g29kjYDox1Q/5Sb64ZRC68XAyCWF19E3sj4I/MLQ7/c429q5PF2AMMuoB3Z3Do6LmE3awlN
esGfztMtfdb2nRoH595JYbd55L8szS9zvJziSYXWCQ27BOJdxTU8JJaMGvpUOMbjD3YSqGb3
"""

snap_http.add_assertion(assertion)
13 changes: 13 additions & 0 deletions core/confdb/delegate-confdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env python3

from landscape.client import snap_http

# Grant an operator the ability to remotely manage confdb views on this device.
snap_http.delegate_confdb(
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN", # operator account-id
authentications=["operator-key", "store"],
views=[
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN/network/proxy-admin",
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN/network/proxy-state",
],
)
11 changes: 11 additions & 0 deletions core/confdb/enable-confdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env python3

from landscape.client import snap_http

snap_http.set_conf(
"system",
{
"experimental.confdb": True,
"experimental.confdb-control": True,
},
)
8 changes: 8 additions & 0 deletions core/confdb/get-confdb-control-assertion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env python3

from landscape.client import snap_http

# Retrieve the confdb-control assertion, which records which operators have
# been granted delegated access to confdb views on this device.
response = snap_http.get_assertions("confdb-control")
print(response.result.decode())
34 changes: 34 additions & 0 deletions core/confdb/get-confdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env python3
import time
from pprint import pprint

from landscape.client import snap_http

# Get all values accessible through a confdb view.
# confdb reads are async so the result must be retrieved by
# polling the returned change.
response = snap_http.get_confdb(
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN", # account-id
"network", # confdb-schema name
"proxy-state", # view name
)
while True:
change = snap_http.check_change(response.change)
if change.result["status"] == "Done":
pprint(change.result["data"]["values"])
break
time.sleep(0.1)

# Get specific keys from a confdb view.
response = snap_http.get_confdb(
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN",
"network",
"proxy-state",
keys=["https"],
)
while True:
change = snap_http.check_change(response.change)
if change.result["status"] == "Done":
pprint(change.result["data"]["values"])
break
time.sleep(0.1)
23 changes: 23 additions & 0 deletions core/confdb/set-confdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python3

from landscape.client import snap_http

# Set values in a confdb view.
snap_http.set_confdb(
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN", # account-id
"network", # confdb-schema name
"proxy-admin", # view name
{
"https.url": "http://proxy.example.com:8080",
"https.bypass": ["localhost", "192.168.0.0/24"],
"ftp.url": "ftp://proxy.example.com:8080",
},
)

# Unset a value by passing None.
snap_http.set_confdb(
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN",
"network",
"proxy-admin",
{"ftp": None},
)
14 changes: 14 additions & 0 deletions core/confdb/undelegate-confdb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python3

from landscape.client import snap_http

# Revoke all delegated confdb access from an operator.
snap_http.undelegate_confdb("f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN")

# To revoke access to specific views or authentication methods only,
# pass views and/or authentications.
snap_http.undelegate_confdb(
"f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN",
authentications=["store"],
views=["f22PSauKuNkwQTM9Wz67ZCjNACuSjjhN/network/proxy-admin"],
)
Loading
Loading