Compare commits

..

72 Commits

Author SHA1 Message Date
8e88b5a7f1 feat(auth): remote and local third-party authentication
Some checks reported warnings
arcad/emissary/pipeline/head This commit is unstable
2023-08-14 14:42:23 -06:00
42d49eb090 feat: move client to public package
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-06-25 11:46:33 -06:00
4217850c30 chore: adding demo cast
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-06-23 18:38:49 +02:00
4a58847d52 chore: update readme
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-06-23 06:42:25 -06:00
42559408da chore: update logo
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-06-23 06:26:27 -06:00
a5fbe3e6e0 chore: add logo
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-06-22 09:05:16 -06:00
d73e027ee3 doc: uci configuration deployment tutorial
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-05-26 15:53:00 +02:00
054744e3e9 fix: systemd units
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-05-25 21:23:15 +02:00
0e664bce44 doc: add first steps tutorial (fr) 2023-05-25 21:22:56 +02:00
58ef3b0077 doc: add emissary introduction
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-05-24 10:15:48 +02:00
6a976c0b51 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-26 15:56:15 +02:00
d188af81af chore: update edge lib without goproxy
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-25 13:54:01 +02:00
e975381b4f fix(controller,app): correctly detect ip address for cookie domain resolution
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-24 13:49:53 +02:00
0d03a708f9 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-24 12:23:45 +02:00
64ea0e05a9 fix(app,handler): use real ip
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-21 20:04:37 +02:00
10844a15a3 chore: update spec samples 2023-04-21 20:03:21 +02:00
0394e34055 feat: update arcad/edge dependency
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-21 20:02:18 +02:00
541d30d74f feat(controller,app): share module integration
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-21 13:10:03 +02:00
87a45090e0 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-21 12:45:51 +02:00
fcd159c0fb chore: use go 1.20.2
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-20 19:28:30 +02:00
eda02c6be3 feat: update arcad/edge dependency
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-04-20 19:21:30 +02:00
ef3048b005 feat(controller,app): use new edge new mountpoints api
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-20 12:23:17 +02:00
51e1dc3b2d fix(server,api): return 'not found' errors 2023-04-20 12:22:30 +02:00
3d01cf0f93 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-20 11:01:04 +02:00
bb03b3a54a feat(controller,app): compress http responses
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-20 10:59:27 +02:00
813f837291 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-14 16:29:09 +02:00
ed35ee5002 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 13:48:33 +02:00
4b5bc0bc82 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 12:08:13 +02:00
dee62184b9 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 11:35:51 +02:00
76656e8dbf feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 11:28:22 +02:00
41b1619fc1 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 11:05:12 +02:00
35d5ee868f chore: update sample specs
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-12 11:10:11 +02:00
765257b4b1 feat(datastore): add basic testsuite for agent repository
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-12 11:09:53 +02:00
2315ee7b61 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-11 15:11:15 +02:00
86a6d81e1d chore: execute tests before commit on edge lib update
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-11 12:06:16 +02:00
c4427dfd2b feat(controller,app): sort apps by id 2023-04-11 12:05:51 +02:00
280b0fbd50 feat(controller,app): validate app manifests on app load 2023-04-11 12:05:19 +02:00
8fb86c600f feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-11 11:13:41 +02:00
12f8b3aa25 chore: add task to update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-06 20:56:43 +02:00
2d2dc29c84 feat: update arcad/edge dependency 2023-04-06 20:56:00 +02:00
4cf53d9f15 chore: tidy dependencies
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-06 19:25:01 +02:00
34e4769b49 feat: update edge dependency
Some checks reported warnings
arcad/emissary/pipeline/head This commit is unstable
2023-04-06 19:19:23 +02:00
47c2546d54 fix(controller,app): break loop when app is found
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-06 18:25:34 +02:00
21173911fb feat: update edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-06 18:17:17 +02:00
b213b8d1ae fix(module,app): handle non existent interface in app url resolver
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-06 15:57:00 +02:00
9dcddc5566 chore(jenkins): cancel older jobs
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-06 15:12:06 +02:00
9a46c9d3d0 chore: tidy dependencies
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-06 15:08:23 +02:00
69f183d126 chore(jenkins): do not wait emissary-firmware job completion
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-06 15:07:35 +02:00
e8829170e5 feat(sqlite): use busy_timeout pragma to prevent database locking errors 2023-04-06 15:06:16 +02:00
253c93dbac fix(module,app): handle host without port in cookie domain identification
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-06 11:00:35 +02:00
d2f865ccbb chore: tidy dependencies
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-06 10:44:05 +02:00
7ee4344adc fix(jenkins): do not trigger emissary-firmware with dirty tag
Some checks reported warnings
arcad/emissary/pipeline/head This commit is unstable
2023-04-06 10:40:05 +02:00
06b1235707 fix(module,app): handle hosts without port
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-04-06 10:21:52 +02:00
2e1ee44e6a feat(module,app): iface-based app url resolving
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-04-05 23:21:43 +02:00
242a247222 feat: add mdns controller
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-04-04 20:26:19 +02:00
562d698066 feat(controller, app): add fetch module
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-04-02 18:05:53 +02:00
909549f056 feat(agent): do not block execution of controllers on error
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-01 19:44:00 +02:00
7d551a8312 feat(auth): accept clock skew for token validation
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-01 19:30:45 +02:00
d02eb91b11 feat(agent): add contactedAt attribute to agent
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-01 14:33:19 +02:00
d2bcdd2999 feat(storage,agent): add label attribute
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-01 13:28:18 +02:00
c638fe102b chore(jenkins): use global git config for credentials
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-03-31 17:31:44 +02:00
273265c3ef feat(agent,run): start proxy controller after app one
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-03-31 17:29:33 +02:00
3e02a9f031 chore(controller,app): refactor app server mutex usage
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-03-31 17:28:52 +02:00
b52c687643 feat(sqlite): add default pragmas to dsn 2023-03-31 17:27:54 +02:00
8119a01bf6 chore: add jenkins pipeline
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-03-31 17:24:33 +02:00
e5b6c5e949 chore(sqlite): use wal journal mode and enable fk checks by default 2023-03-29 20:58:46 +02:00
9c69dc7ec8 feat(auth): use utc time 2023-03-29 20:49:44 +02:00
4e6b450338 feat(storage,sqlite): log row closing errors 2023-03-29 20:10:06 +02:00
351f22e216 feat(controller,app): automatically redirect requests to cookie domain 2023-03-29 17:29:16 +02:00
854a6ae41b fix(controller,app): include auth configuration in changes detection 2023-03-29 15:32:23 +02:00
a48c2ebe14 fix(controller,app): update app repository on spec changes 2023-03-29 11:27:47 +02:00
cdd78e4031 chore: update go.mod 2023-03-28 20:48:00 +02:00
91 changed files with 3475 additions and 451 deletions

5
.gitignore vendored
View File

@ -4,9 +4,10 @@ dist/
/tools
/tmp
/state.json
/emissary.sqlite
/emissary.sqlite*
/.gitea-release
/agent-key.json
/apps
/server-key.json
/.emissary-token
/.emissary-token
/out

85
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,85 @@
@Library('cadoles') _
pipeline {
agent {
dockerfile {
label 'docker'
filename 'Dockerfile'
dir 'misc/jenkins'
}
}
stages {
stage('Cancel older jobs') {
steps {
script {
def buildNumber = env.BUILD_NUMBER as int
if (buildNumber > 1) milestone(buildNumber - 1)
milestone(buildNumber)
}
}
}
stage('Run unit tests') {
steps {
script {
withCredentials([
usernamePassword([
credentialsId: 'forge-jenkins',
usernameVariable: 'GIT_USERNAME',
passwordVariable: 'GIT_PASSWORD'
])
]) {
sh '''
git config --global credential.https://forge.cadoles.com.username "$GIT_USERNAME"
git config --global credential.https://forge.cadoles.com.helper '!f() { test "$1" = get && echo "password=$GIT_PASSWORD"; }; f'
export GOPRIVATE=forge.cadoles.com/arcad/edge
make test
'''
}
}
}
}
stage('Release') {
when {
anyOf {
branch 'master'
branch 'develop'
}
}
steps {
script {
withCredentials([
usernamePassword([
credentialsId: 'forge-jenkins',
usernameVariable: 'GITEA_RELEASE_USERNAME',
passwordVariable: 'GITEA_RELEASE_PASSWORD'
])
]) {
sh 'make gitea-release'
}
def currentVersion = sh(returnStdout: true, script: 'make full-version').trim()
if (currentVersion.endsWith('-dirty')) {
unstable('Could not trigger emissary-firmware build, dirty version !')
} else {
build(
job: "../emissary-firmware/${env.GIT_BRANCH}",
parameters: [
[$class: 'StringParameterValue', name: 'emissaryRelease', value: currentVersion]
],
wait: false
)
}
}
}
}
}
post {
always {
cleanWs()
}
}
}

View File

@ -135,7 +135,7 @@ gitea-release: tools/gitea-release/bin/gitea-release.sh goreleaser
GITEA_RELEASE_COMMITISH_TARGET="$(GIT_VERSION)" \
GITEA_RELEASE_IS_DRAFT="false" \
GITEA_RELEASE_BODY="" \
GITEA_RELEASE_ATTACHMENTS="$(shell find .gitea-release/* -type f)" \
GITEA_RELEASE_ATTACHMENTS="$$(find .gitea-release/* -type f)" \
tools/gitea-release/bin/gitea-release.sh
tools/gitea-release/bin/gitea-release.sh:
@ -150,4 +150,17 @@ AGENT_ID ?= 1
load-sample-specs:
cat misc/spec-samples/app.emissary.cadoles.com.json | ./bin/server api agent spec update -a $(AGENT_ID) --no-patch --spec-data - --spec-name app.emissary.cadoles.com
cat misc/spec-samples/proxy.emissary.cadoles.com.json | ./bin/server api agent spec update -a $(AGENT_ID) --no-patch --spec-data - --spec-name proxy.emissary.cadoles.com
cat misc/spec-samples/proxy.emissary.cadoles.com.json | ./bin/server api agent spec update -a $(AGENT_ID) --no-patch --spec-data - --spec-name proxy.emissary.cadoles.com
cat misc/spec-samples/mdns.emissary.cadoles.com.json | ./bin/server api agent spec update -a $(AGENT_ID) --no-patch --spec-data - --spec-name mdns.emissary.cadoles.com
full-version:
@echo $(FULL_VERSION)
update-edge-lib:
git pull --rebase
GOPROXY=direct GOPRIVATE=forge.cadoles.com/arcad/edge go get -u forge.cadoles.com/arcad/edge
go mod tidy
$(MAKE) test
git add go.mod go.sum
git commit -m "feat: update arcad/edge dependency"
git push

View File

@ -1,4 +1,6 @@
# Emissary
<p align="center">
<img width="400" src="./misc/resources/logo.svg" />
</p>
Control plane for "edge" (and OpenWRT-based) devices.
@ -14,6 +16,8 @@ Download the pre-compiled binaries from the [releases page](https://forge.cadole
See [`doc`](./doc/README.md)
## Licence
## Licence & mentions
AGPL-3.0
[AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html#license-text)
Logo by [@aardouin](https://forge.cadoles.com/aardouin)

858
casts/emissary.cast Normal file
View File

@ -0,0 +1,858 @@
{"version": 2, "width": 240, "height": 82, "timestamp": 1687535780, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}, "title": "Emissary in action"}
[1.096253, "o", "Identity added: /home/pcaseiro/.ssh/id_rsa (/home/pcaseiro/.ssh/id_rsa)\r\n"]
[1.099418, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
[1.214747, "o", "\u001b]0;cadoles/emissary\u0007"]
[1.319126, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[m\u001b[1mpcaseiro@numenor\u001b[0m\u001b[1m:~/code/cadoles/emissary\u001b[0m (pts/25 \u001b[4m/bin/zsh 5.9\u001b[24m UltimaThule) \u001b[1m17:56:22 \u001b[0m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[39m\u001b[32mmaster\u001b[39m\u001b[35m|\u001b[39m\u001b[32m\u001b[39m\u001b[0m\u001b[31m\u001b[39m\u001b[0m\u001b[33m+1\u001b[39m\u001b[0m…3\u001b[32m\u001b[39m\u001b[0m\u001b[33m\u001b[39m\u001b[0m\u001b[35m]\u001b[39m\r\n\u001b[7m!429 Z1 ?0 L3\u001b[27m \u001b[1m~/code/cadoles/emissary →\u001b[0m \u001b[K\u001b[194C 100%\u001b[199D\u001b[?1h\u001b=\u001b[?2004h"]
[3.647795, "o", "\u001b[32mt\u001b[39m"]
[3.719657, "o", "\b\u001b[1m\u001b[31mt\u001b[1m\u001b[31mm\u001b[0m\u001b[39m"]
[3.830544, "o", "\b\b\u001b[1m\u001b[31mt\u001b[1m\u001b[31mm\u001b[1m\u001b[31mu\u001b[0m\u001b[39m"]
[4.003306, "o", "\b\b\b\u001b[0m\u001b[32mt\u001b[0m\u001b[32mm\u001b[0m\u001b[32mu\u001b[32mx\u001b[39m\u001b[1m \u001b[0m"]
[4.382336, "o", "\b\u001b[0m \b\u001b[?1l\u001b>\u001b[?2004l\u001b[K\r\r\n"]
[4.38264, "o", "\u001b]0;tmux\u0007"]
[4.39146, "o", "\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;82r\u001b[>c\u001b[>q\u001b[1;1H"]
[4.391933, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:zsh* \"numenor\" 17:56 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"]
[4.392315, "o", "\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?2004l\u001b[1;1H\u001b[1;82r\u001b[1;1H\u001b[?7727h\u001b[?7727h"]
[4.392677, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:zsh* \"numenor\" 17:56 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"]
[5.392151, "o", "\u001b[?25l\u001b[120C│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[1;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1"]
[5.392363, "o", "K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[1;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:zsh* \"numenor\" 17:56 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;122H"]
[5.528654, "o", "\u001b[HIdentity added: /home/pcaseiro/.ssh/id_rsa (/home/pcaseiro/.ssh/id_rsa)\u001b[50C"]
[5.531563, "o", "\r\n \u001b[1;122H"]
[5.749901, "o", "\u001b[1;81r\u001b[3;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[2d\u001b[1K\r\u001b[36mtmux \u001b[39m\u001b[1mpcaseiro@numenor:~/code/cadoles/emissary\u001b(B\u001b[m (pts/26 \u001b[4m-zsh 5.9\u001b(B\u001b[m UltimaThule) \u001b[1m17:56:26 \u001b(B\u001b[m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[32mmaster\u001b[35m|\u001b[33m+1\u001b[39m…3\u001b[35m]\r\n\u001b[39m\u001b[7m!430 Z1 ?0 L2\u001b(B\u001b[m \u001b[1m~/code/cadoles/emissary →\u001b(B\u001b[m \u001b[74X\u001b[74C 100%\u001b[1X\u001b[1;82r\u001b[1;122H"]
[6.471831, "o", "Identity added: /home/pcaseiro/.ssh/id_rsa (/home/pcaseiro/.ssh/id_rsa)\u001b[2;122H"]
[6.474732, "o", " \u001b[2;122H"]
[6.565444, "o", "\u001b[?25l\u001b[1;121H\u001b[32m│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[39m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[3;41H\u001b[?2004h"]
[6.686474, "o", "\u001b[1;81r\u001b[3;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[2d\u001b[K\u001b[36mtmux \u001b[39m\u001b[1mpcaseiro@numenor:~/code/cadoles/emissary\u001b(B\u001b[m (pts/27 \u001b[4m-zsh 5.9\u001b(B\u001b[m UltimaThule) \u001b[1m17:56:27 \u001b(B\u001b[m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[32mmaster\u001b[35m|\u001b[33m+1\u001b[39m…3\u001b[35m]\u001b[3;122H\u001b[39m\u001b[7m!430 Z1 ?0 L2\u001b(B\u001b[m \u001b[1m~/code/cadoles/emissary →\u001b(B\u001b[m \u001b[73X\u001b[73C 100%\u001b[K\u001b[1;82r\u001b[3;41H"]
[7.461303, "o", "\r\nbck-i-search: _\u001b[105X\u001b[3;41H"]
[7.748982, "o", "asciinema rec --cols 240 -t \"Emissary in action\" casts/emissary.ca\u001b[4ms\u001b(B\u001b[mt\u001b[4;15Hs_\u001b[3;107H"]
[7.900863, "o", "\u001b[8D\u001b[4mss\u001b[6C\u001b(B\u001b[ms\u001b[4;16Hs_\u001b[3;99H"]
[8.02899, "o", "\u001b[41G\u001b[4mssh\u001b(B\u001b[m openwrt \u001b[4;17Hh_\u001b[3;41H"]
[10.029326, "o", "\u001b[4Cemissary-server\u001b[19D"]
[10.55251, "o", "\u001b[32mssh\u001b[39m\u001b[16C\u001b[61X\u001b[4;120H\u001b[1K\r\u001b[?2004l"]
[10.903301, "o", "Welcome to Alpine!\u001b[6;1HThe Alpine Wiki contains a large amount of how-to guides and general\r\ninformation about administrating Alpine systems.\r\nSee <https://wiki.alpinelinux.org/>.\u001b[10;1HYou can setup the system with the command: setup-alpine\u001b[12;1HYou may change this message by editing /etc/motd.\u001b[14;1Hemissary:~# "]
[11.269977, "o", "\u001b[?25l\u001b[1;121H\u001b[32m│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[39m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:ss"]
[11.27011, "o", "h* \"numenor\" 17:56 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[14;13H"]
[11.374342, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[3;162H\u001b[?2004h"]
[11.734148, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:zsh* "]
[11.734179, "o", " \"numenor\" 17:56 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[3;162H"]
[11.737856, "o", "\u001b[31m\u001b[1ms\u001b(B\u001b[m"]
[11.918625, "o", "\b\u001b[32mss\u001b(B\u001b[m"]
[12.1028, "o", "\b\b\u001b[32mssh\u001b(B\u001b[m"]
[12.272136, "o", " "]
[12.768316, "o", "o"]
[12.880351, "o", "p"]
[12.999971, "o", "e"]
[13.168165, "o", "n"]
[13.383201, "o", "w"]
[13.551917, "o", "r"]
[13.719397, "o", "t"]
[14.318327, "o", "\u001b[K\u001b[4;122H\u001b[?2004l"]
[14.449636, "o", "\u001b[2BBusyBox v1.35.0 (2023-03-27 07:03:24 UTC) built-in shell (ash)\u001b[8;122H"]
[14.451825, "o", " _______ ________ __\u001b[9;122H | |.-----.-----.-----.| | | |.----.| |_\u001b[10;122H | - || _ | -__| || | | || _|| _|\u001b[11;122H |_______|| __|_____|__|__||________||__| |____|\u001b[12;122H |__| W I R E L E S S F R E E D O M\u001b[13;122H -----------------------------------------------------\u001b[14;122H OpenWrt 22.03.2, r19803-9a599fee93\u001b[15;122H -----------------------------------------------------\u001b[16;122H"]
[14.463042, "o", "=== WARNING! =====================================\u001b[17;122HThere is no root password defined on this device!\u001b[18;122HUse the \"passwd\" command to set up a new password\u001b[19;122Hin order to prevent unauthorized SSH logins.\u001b[20;122H--------------------------------------------------\u001b[21;122H"]
[14.463903, "o", "root@OpenWrt:~# "]
[14.791692, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:ssh* "]
[14.791733, "o", " \"numenor\" 17:56 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;138H"]
[15.6169, "o", "\u001b[1;81r\u001b[2;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[1d\u001b[Kroot@OpenWrt:~# \u001b[2;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[1;138H\u001b[K\u001b[1;82r\u001b[1;138H"]
[16.197477, "o", "\u001b[?25l\u001b[17D\u001b[32m│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[39m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[14;13H"]
[16.712675, "o", "\u001b[1;81r\u001b[2;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[1d\u001b[1K\u001b[Hemissary:~# \u001b[2;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[1;13H\u001b[108X\u001b[1;82r\u001b[1;13H"]
[20.46497, "o", "e"]
[20.64927, "o", "c"]
[20.760832, "o", "h"]
[20.840642, "o", "o"]
[20.944446, "o", " "]
[21.05675, "o", "\""]
[21.409471, "o", "T"]
[21.536293, "o", "h"]
[21.62476, "o", "e"]
[21.776569, "o", " "]
[21.88008, "o", "s"]
[21.9763, "o", "e"]
[22.048532, "o", "r"]
[22.200914, "o", "v"]
[22.272281, "o", "e"]
[22.384782, "o", "r"]
[22.584381, "o", "\""]
[24.224157, "o", "\r\nThe server\r\nemissary:~# "]
[24.97398, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;138H"]
[25.66414, "o", "e"]
[25.863716, "o", "c"]
[25.94348, "o", "h"]
[26.04007, "o", "o"]
[26.127871, "o", " "]
[26.512402, "o", "\""]
[26.808562, "o", "T"]
[26.992072, "o", "h"]
[27.079539, "o", "e"]
[27.464842, "o", " "]
[27.560029, "o", "c"]
[27.639923, "o", "l"]
[27.767737, "o", "i"]
[27.800173, "o", "e"]
[28.456016, "o", "n"]
[28.567718, "o", "t"]
[28.752508, "o", "\""]
[29.056597, "o", "\u001b[2;122HThe client\u001b[3;122Hroot@OpenWrt:~# "]
[29.878218, "o", "\u001b[?25l\u001b[1;121H\u001b[32m│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[39m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[3;13H"]
[34.220106, "o", "emissary api agent query\r\n"]
[34.239871, "o", "+----+-------+------------+--------+-------------+-----------+\r\n| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT |\r\n+----+-------+------------+--------+-------------+-----------+\r\n+----+-------+------------+--------+-------------+-----------+\r\n"]
[34.240119, "o", "emissary:~# "]
[41.285104, "o", "\u001b[?25l\u001b[37m\u001b[40m\u001b[82;1H\u001b[32mnumenor\u001b[37m0:ssh* \"numenor\" 17:57 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[8;13H"]
[41.430426, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[3;138H"]
[41.847638, "o", "u"]
[42.008691, "o", "c"]
[42.128767, "o", "i"]
[42.265178, "o", "\u001b[19Droot@OpenWrt:~# uci \u001b[1;81r\u001b[4;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[3;142H\u001b[K\u001b[1;82r\u001b[3;142H"]
[43.528431, "o", "s"]
[43.624275, "o", "e"]
[43.704262, "o", "t"]
[43.832626, "o", " "]
[44.064036, "o", "e"]
[44.184356, "o", "m"]
[44.344144, "o", "i"]
[44.488508, "o", "s"]
[44.671926, "o", "s"]
[44.856414, "o", "a"]
[45.008191, "o", "r"]
[45.152474, "o", "y"]
[46.496924, "o", "."]
[46.760587, "o", "a"]
[46.896795, "o", "g"]
[46.984154, "o", "e"]
[47.064542, "o", "n"]
[47.192499, "o", "t"]
[47.376814, "o", "."]
[47.520459, "o", "s"]
[47.616461, "o", "e"]
[47.696447, "o", "r"]
[47.856801, "o", "v"]
[47.927634, "o", "e"]
[48.056252, "o", "r"]
[48.720662, "o", "."]
[49.569159, "o", "\u001b[1;81r\u001b[4;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[3;167H\u001b[K\u001b[1;82r\u001b[3;167H"]
[49.768382, "o", "_"]
[50.023726, "o", "u"]
[50.142999, "o", "r"]
[50.223839, "o", "l"]
[50.520493, "o", "="]
[50.88052, "o", "\""]
[51.232583, "o", "h"]
[51.32012, "o", "t"]
[51.472428, "o", "t"]
[51.568167, "o", "p"]
[51.784203, "o", ":"]
[52.007861, "o", "/"]
[52.832643, "o", "/"]
[53.504824, "o", "1"]
[53.71259, "o", "9"]
[53.800503, "o", "2"]
[53.952258, "o", "."]
[54.056515, "o", "1"]
[54.760124, "o", "6"]
[54.95909, "o", "8"]
[55.199962, "o", "."]
[56.128917, "o", "3"]
[56.232664, "o", "0"]
[56.448551, "o", "."]
[56.648562, "o", "2"]
[56.839948, "o", "0"]
[56.968233, "o", "0"]
[57.184279, "o", ":"]
[58.167802, "o", "3"]
[58.416307, "o", "0"]
[58.559587, "o", "0"]
[58.695934, "o", "0"]
[58.88815, "o", "\""]
[60.416273, "o", "\u001b[4;122H"]
[60.418825, "o", "root@OpenWrt:~# "]
[65.007294, "o", "u"]
[65.15203, "o", "c"]
[65.247617, "o", "i"]
[65.376629, "o", " "]
[65.520236, "o", "c"]
[65.576313, "o", "o"]
[65.632476, "o", "m"]
[65.783985, "o", "m"]
[65.87259, "o", "i"]
[65.95938, "o", "t"]
[66.432359, "o", "\u001b[5;122H"]
[66.477194, "o", "root@OpenWrt:~# "]
[67.992659, "o", "r"]
[68.047986, "o", "e"]
[68.184009, "o", "l"]
[68.352416, "o", "o"]
[68.375924, "o", "a"]
[68.488309, "o", "d"]
[68.648621, "o", "_"]
[68.824006, "o", "c"]
[68.903873, "o", "o"]
[68.951758, "o", "n"]
[69.023743, "o", "f"]
[69.14403, "o", "i"]
[69.24805, "o", "g"]
[69.640712, "o", "\u001b[6;122H"]
[69.674411, "o", "root@OpenWrt:~# "]
[71.305363, "o", "l"]
[71.472546, "o", "o"]
[72.031131, "o", "g"]
[72.312714, "o", "r"]
[72.512058, "o", "e"]
[72.873856, "o", "\u001b[21Droot@OpenWrt:~# logread \u001b[1;81r\u001b[7;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[6;146H\u001b[K\u001b[1;82r\u001b[6;146H"]
[73.375291, "o", "f"]
[73.752486, "o", "\u001b[1;81r\u001b[7;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[6;146H\u001b[K\u001b[1;82r\u001b[6;146H"]
[73.959425, "o", "-"]
[74.055612, "o", "f"]
[74.519013, "o", "\u001b[7;122H"]
[76.806035, "o", "\u001b[?25l\u001b[1;121H\u001b[32m│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[39m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[8;13H"]
[78.441454, "o", "\remissary:~# emissary api agent query\u001b[1;81r\u001b[9;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[8;37H\u001b[84X\u001b[1;82r\u001b[8;37H"]
[79.408341, "o", "\r\n"]
[79.423951, "o", "+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\r\n----------+\r\n| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT \r\n |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\r\n----------+\r\n| 1 | | 23ZQ4yoK869AFHJ6ryA8EpnAz8ZESr... | 0 | 2023-06-23 15:57:32.068805967 ... | \"2023-06-23T15:57:31.807\r\n03548Z... |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\r\n----------+\r\n"]
[79.424215, "o", "emissary:~# "]
[83.713006, "o", "\r(reverse-i-search)'': \u001b[1;81r\u001b[20;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[19;23H\u001b[98X\u001b[1;82r\u001b[19;23H"]
[90.209796, "o", "\r(reverse-i-search)'e': emissary api agent query\u001b[1;81r\u001b[20;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[19;48H\u001b[73X\u001b[1;82r\u001b[19;24H"]
[90.457633, "o", "\r(reverse-i-search)'em': emissary api agent query\u001b[1;81r\u001b[20;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[19;49H\u001b[72X\u001b[1;82r\u001b[19;25H"]
[91.032749, "o", "\remissary:~# emissary api agent query\u001b[1;81r\u001b[20;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[19;37H\u001b[84X\u001b[13G^C\u001b[21;1Hemissary:~# \u001b[1;82r\u001b[21;13H"]
[91.568147, "o", "e"]
[91.688802, "o", "m"]
[91.792506, "o", "i"]
[91.88046, "o", "s"]
[92.048302, "o", "s"]
[92.169954, "o", "\remissary:~# emissary \u001b[1;81r\u001b[22;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[21;22H\u001b[99X\u001b[1;82r\u001b[21;22H"]
[93.128744, "o", "a"]
[93.280615, "o", "p"]
[93.391802, "o", "i"]
[93.7609, "o", "\u001b[1;81r\u001b[22;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[21;24H\u001b[97X\u001b[1;82r\u001b[21;24H"]
[94.07231, "o", "\u001b[1;81r\u001b[22;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[21;23H\u001b[98X\u001b[1;82r\u001b[21;23H"]
[94.728386, "o", "p"]
[94.871923, "o", "i"]
[95.014665, "o", " "]
[95.199348, "o", "a"]
[95.352379, "o", "g"]
[95.424111, "o", "e"]
[95.519963, "o", "n"]
[95.624473, "o", "t"]
[95.808593, "o", " "]
[95.975659, "o", "u"]
[96.072053, "o", "p"]
[96.119892, "o", "d"]
[96.160294, "o", "a"]
[96.255722, "o", "t"]
[96.3603, "o", "e"]
[99.497311, "o", " "]
[99.920521, "o", "-"]
[100.079886, "o", "-"]
[100.448167, "o", "a"]
[100.6005, "o", "g"]
[100.68773, "o", "e"]
[100.768361, "o", "n"]
[100.855628, "o", "t"]
[101.112387, "o", "-"]
[101.248498, "o", "i"]
[101.367919, "o", "d"]
[101.488491, "o", " "]
[102.008363, "o", "1"]
[102.616774, "o", " "]
[103.080221, "o", "-"]
[103.224243, "o", "-"]
[103.368202, "o", "s"]
[103.448563, "o", "t"]
[103.512568, "o", "a"]
[103.60873, "o", "t"]
[103.688521, "o", "u"]
[103.808492, "o", "s"]
[103.872428, "o", " "]
[104.120393, "o", "1"]
[104.449135, "o", "\r\n"]
[104.749948, "o", "+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\r\n----------+\r\n| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT \r\n |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\r\n----------+\r\n| 1 | | 23ZQ4yoK869AFHJ6ryA8EpnAz8ZESr... | 1 | 2023-06-23 15:57:32.068805967 ... | \"2023-06-23T15:58:05.165\r\n446799... |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\r\n----------+\r\n"]
[104.751768, "o", "emissary:~# "]
[109.395515, "o", "\u001b[?25l\u001b[37m\u001b[40m\u001b[82;1H\u001b[32mnumenor\u001b[37m0:ssh* \"numenor\" 17:58 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[32;13H"]
[117.160555, "o", "c"]
[117.248149, "o", "a"]
[117.360084, "o", "t"]
[117.656612, "o", " "]
[117.800299, "o", "c"]
[117.880754, "o", "o"]
[117.936245, "o", "n"]
[118.008473, "o", "f"]
[118.096709, "o", "\remissary:~# cat config/\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;24H\u001b[97X\u001b[1;82r\u001b[32;24H"]
[119.464482, "o", "m"]
[119.64143, "o", "y"]
[119.784378, "o", "\remissary:~# cat config/my-\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;27H\u001b[94X\u0007\u001b[1;82r\u001b[32;27H"]
[120.632281, "o", "u"]
[120.721236, "o", "\remissary:~# cat config/my-uci-spec.json \u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;41H\u001b[80X\u001b[1;82r\u001b[32;41H"]
[123.304407, "o", "|"]
[123.74422, "o", " "]
[124.128128, "o", "e"]
[124.263941, "o", "m"]
[124.424373, "o", "s"]
[124.680564, "o", "s"]
[124.882004, "o", "\u0007"]
[125.279809, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;46H\u001b[75X\u001b[1;82r\u001b[32;46H"]
[125.40824, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;45H\u001b[76X\u001b[1;82r\u001b[32;45H"]
[125.584136, "o", "i"]
[125.67197, "o", "s"]
[125.801892, "o", "\remissary:~# cat config/my-uci-spec.json | emissary \u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;52H\u001b[69X\u001b[1;82r\u001b[32;52H"]
[127.264396, "o", "a"]
[127.368578, "o", "p"]
[127.496614, "o", "i"]
[127.640492, "o", " "]
[127.784315, "o", "a"]
[127.967952, "o", "g"]
[128.080574, "o", "e"]
[128.192217, "o", "n"]
[128.336294, "o", "t"]
[129.383797, "o", " "]
[129.928473, "o", "s"]
[130.046847, "o", "p"]
[130.128637, "o", "e"]
[130.31167, "o", "c"]
[130.391636, "o", " "]
[130.504311, "o", "u"]
[130.599886, "o", "p"]
[130.664288, "o", "d"]
[130.704209, "o", "a"]
[130.800609, "o", "t"]
[130.904428, "o", "e"]
[130.944592, "o", " "]
[131.152072, "o", "-"]
[131.271984, "o", "a"]
[131.378654, "o", "\u001b[7;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.225 [INFO]\u001b[5C<./internal/agent/controller/pe\u001b[8;122Hrsistence/controller.go:58>\u001b[5C(*Controller).Reconcile\u001b[Cno changes detected, doing nothing\u001b[6C{\"controller\": \"persist\u001b[9;122Hence-controller\"}\u001b[32;76H"]
[131.809911, "o", "\u001b[10;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5C<./internal/agent/controller/pr\u001b[11;122Hoxy/controller.go:35>\u001b[3C(*Controller).Reconcile\u001b[Ccould not find proxy spec\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[12;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5C<./internal/agent/controller/op\u001b[13;122Henwrt/uci_controller.go:32>\u001b[5C(*UCIController).Reconcile\u001b[6Ccould not find uci spec, doing nothing\u001b[2C{\"controller\": \u001b[14;122H\"uci-controller\"}\u001b[15;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5C<./internal/agent/controller/ap\u001b[16;122Hp/controller.go:42>\u001b[5C(*Controller).Reconcile\u001b[Ccould not find app spec\u001b[C{\"controller\": \"app-controller\"}\u001b[17;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5C<./internal/agent/controller/op\u001b[18;122Henwrt/sysupgrade_controller.go:36>\u001b[6C(*SysUpgradeController).Reconcile\u001b[7Ccould not find sysupgrade spec, doing n\u001b"]
[131.810072, "o", "[19;122Hothing\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[32;76H"]
[131.86396, "o", " "]
[132.592293, "o", "1"]
[134.37625, "o", " "]
[134.672641, "o", "-"]
[134.831325, "o", "-"]
[135.512804, "o", "n"]
[135.680765, "o", "o"]
[135.895838, "o", "-"]
[136.088186, "o", "p"]
[136.183895, "o", "a"]
[136.264002, "o", "t"]
[136.688423, "o", "c"]
[136.800043, "o", "h"]
[137.368326, "o", " "]
[138.096691, "o", "-"]
[138.248192, "o", "-"]
[138.376434, "o", "p"]
[138.480395, "o", "s"]
[138.576492, "o", "e"]
[138.992883, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;94H\u001b[27X\u001b[1;82r\u001b[32;94H"]
[139.152606, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;93H\u001b[28X\u001b[1;82r\u001b[32;93H"]
[139.632082, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;92H\u001b[29X\u001b[1;82r\u001b[32;92H"]
[139.768562, "o", "s"]
[139.864029, "o", "p"]
[139.968671, "o", "e"]
[140.192028, "o", "c"]
[141.313515, "o", "-"]
[141.544495, "o", "d"]
[141.616185, "o", "a"]
[141.712432, "o", "t"]
[141.80823, "o", "a"]
[148.097053, "o", " "]
[149.008624, "o", "-"]
[149.217313, "o", " "]
[149.744995, "o", "-"]
[149.872177, "o", "-"]
[150.008948, "o", "p"]
[150.127181, "o", "s"]
[150.521487, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;107H\u001b[14X\u001b[1;82r\u001b[32;107H"]
[150.74489, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;106H\u001b[15X\u001b[1;82r\u001b[32;106H"]
[150.936482, "o", "s"]
[151.368788, "o", "p"]
[151.472664, "o", "e"]
[151.648574, "o", "c"]
[153.10513, "o", " "]
[153.497267, "o", "\u001b[1;81r\u001b[33;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[32;110H\u001b[11X\u001b[1;82r\u001b[32;110H"]
[153.728312, "o", "-"]
[153.928423, "o", "n"]
[154.032525, "o", "a"]
[154.13689, "o", "m"]
[154.256425, "o", "e"]
[154.383972, "o", " "]
[154.975936, "o", "u"]
[155.192467, "o", "c"]
[155.272635, "o", "i"]
[155.60074, "o", "."]
[157.335898, "o", "e\r\n"]
[157.432746, "o", "m"]
[157.55987, "o", "i"]
[157.688586, "o", "s"]
[157.848415, "o", "s"]
[157.904094, "o", "a"]
[158.064258, "o", "r"]
[158.168433, "o", "y"]
[158.448669, "o", "."]
[158.592486, "o", "c"]
[158.66391, "o", "a"]
[158.776459, "o", "d"]
[158.872514, "o", "o"]
[159.016117, "o", "l"]
[159.088205, "o", "e"]
[159.160836, "o", "s"]
[159.29661, "o", "."]
[159.384514, "o", "c"]
[159.520686, "o", "o"]
[159.5924, "o", "m"]
[160.217903, "o", "\r\n"]
[160.491787, "o", "+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n| ID | NAME | DATA | REVISION | CREATEDAT | UPD\r\nATEDAT |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n| 1 | uci.emissary.cadoles.com | {\"config\":{\"packages\":[{\"confi... | 0 | \"2023-06-23T15:59:00.937205005... | \"20\r\n23-06-23T15:59:00.937205005... |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n"]
[160.492898, "o", "emissary:~# "]
[167.752531, "o", "c"]
[167.824121, "o", "a"]
[167.936812, "o", "t"]
[168.120152, "o", " "]
[168.248404, "o", "c"]
[168.328154, "o", "o"]
[168.38465, "o", "n"]
[168.456121, "o", "f"]
[168.544836, "o", "\remissary:~# cat config/\u001b[1;81r\u001b[45;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[44;24H\u001b[97X\u001b[1;82r\u001b[44;24H"]
[169.398711, "o", "\u001b[?25l\u001b[37m\u001b[40m\u001b[82;1H\u001b[32mnumenor\u001b[37m0:ssh* \"numenor\" 17:59 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[44;24H"]
[170.048353, "o", "a"]
[170.143951, "o", "p"]
[170.31291, "o", "p"]
[170.50528, "o", "\remissary:~# cat config/app.emissary.cadoles.com.json \u001b[1;81r\u001b[45;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[44;54H\u001b[67X\u001b[1;82r\u001b[44;54H"]
[172.896918, "o", "|"]
[173.184616, "o", " "]
[173.512251, "o", "e"]
[173.632645, "o", "m"]
[173.992759, "o", "i"]
[174.080153, "o", "s"]
[174.248666, "o", "s"]
[174.354212, "o", "\remissary:~# cat config/app.emissary.cadoles.com.json | emissary \u001b[1;81r\u001b[45;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[44;65H\u001b[56X\u001b[1;82r\u001b[44;65H"]
[175.856833, "o", "a"]
[175.944762, "o", "p"]
[176.072667, "o", "i"]
[176.176415, "o", " "]
[176.280326, "o", "a"]
[176.416098, "o", "g"]
[176.504283, "o", "e"]
[176.600052, "o", "n"]
[177.056578, "o", "t"]
[177.160676, "o", " "]
[178.336251, "o", "s"]
[178.440892, "o", "p"]
[178.560014, "o", "e"]
[178.928922, "o", "c"]
[179.792395, "o", " "]
[180.78425, "o", "u"]
[180.896636, "o", "p"]
[180.944444, "o", "d"]
[181.000584, "o", "a"]
[181.120239, "o", "t"]
[181.184768, "o", "e"]
[181.240728, "o", " "]
[181.368838, "o", "-"]
[181.496538, "o", "a"]
[181.633077, "o", " "]
[181.992822, "o", "1"]
[182.272325, "o", " "]
[183.752904, "o", "-"]
[183.920789, "o", "-"]
[184.560267, "o", "n"]
[184.695618, "o", "o"]
[184.895732, "o", "-"]
[185.064886, "o", "p"]
[185.144271, "o", "a"]
[185.224775, "o", "t"]
[185.625037, "o", "c"]
[185.777507, "o", "h"]
[186.200872, "o", " "]
[186.824121, "o", "-"]
[186.952816, "o", "-"]
[187.112502, "o", "s"]
[187.232069, "o", "p"]
[187.992605, "o", "e"]
[188.17644, "o", "c"]
[188.384273, "o", "-"]
[188.488801, "o", "d"]
[188.616825, "o", "a"]
[188.656927, "o", "t"]
[188.784603, "o", "a"]
[191.372274, "o", "\u001b[20;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5C<./internal/agent/controller/pe\u001b[21;122Hrsistence/controller.go:58>\u001b[5C(*Controller).Reconcile\u001b[Cno changes detected, doing nothing\u001b[6C{\"controller\": \"persist\u001b[22;122Hence-controller\"}\u001b[44;114H"]
[191.624997, "o", " "]
[191.752374, "o", "\u001b[23;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5C<./internal/agent/controller/pr\u001b[24;122Hoxy/controller.go:35>\u001b[3C(*Controller).Reconcile\u001b[Ccould not find proxy spec\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[44;115H"]
[191.757907, "o", "\u001b[25;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5C<./internal/agent/controller/op\u001b[26;122Henwrt/uci_controller.go:40>\u001b[5C(*UCIController).Reconcile\u001b[6Cretrieved spec\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[27;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[44;115H"]
[191.758357, "o", "\u001b[28;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5C<./internal/agent/controller/op\u001b[29;122Henwrt/uci_controller.go:61>\u001b[5C(*UCIController).updateConfiguration\u001b[4Cimporting uci config\u001b[4C{\"controller\": \"uci-con\u001b[30;122Htroller\"}\u001b[44;115H"]
[191.936718, "o", "-"]
[192.119847, "o", " "]
[192.279354, "o", "\u001b[31;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5C<./internal/agent/controller/op\u001b[32;122Henwrt/uci_controller.go:55>\u001b[5C(*UCIController).Reconcile\u001b[6Cupdating current spec revision\u001b[2C{\"controller\": \"uci-con\u001b[33;122Htroller\", \"revision\": 0}\u001b[34;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5C<./internal/agent/controller/ap\u001b[35;122Hp/controller.go:42>\u001b[5C(*Controller).Reconcile\u001b[Ccould not find app spec\u001b[C{\"controller\": \"app-controller\"}\u001b[36;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5C<./internal/agent/controller/op\u001b[37;122Henwrt/sysupgrade_controller.go:36>\u001b[6C(*SysUpgradeController).Reconcile\u001b[7Ccould not find sysupgrade spec, doing n\u001b[38;122Hothing\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[44;117H"]
[192.617006, "o", "-"]
[192.744737, "o", "-"]
[193.360547, "o", "s"]
[193.464729, "o", "p\r\n"]
[193.482541, "o", "\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[45;1H"]
[193.53542, "o", "\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[43;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locall"]
[193.535452, "o", "y-known addresses for invalid\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[45;1H\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[56;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[57;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[58;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[59;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-know"]
[193.535471, "o", "n addresses for bind\u001b[45;1H\u001b[60;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[61;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[62;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[45;1H"]
[193.568717, "o", "e"]
[193.694113, "o", "\u001b[63;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[64;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[45;2H"]
[193.752914, "o", "c"]
[199.320776, "o", "-"]
[199.537004, "o", "n"]
[199.648409, "o", "a"]
[199.744294, "o", "m"]
[199.848727, "o", "e"]
[201.264275, "o", " "]
[201.440715, "o", "a"]
[201.576086, "o", "p"]
[201.72881, "o", "p"]
[202.04052, "o", "."]
[202.328931, "o", "e"]
[202.496948, "o", "m"]
[202.809086, "o", "i"]
[203.025228, "o", "s"]
[203.193087, "o", "s"]
[203.833397, "o", "a"]
[203.977048, "o", "r"]
[204.169049, "o", "y"]
[204.465105, "o", "."]
[204.608648, "o", "c"]
[204.657042, "o", "a"]
[204.809386, "o", "d"]
[204.90468, "o", "o"]
[205.056543, "o", "l"]
[205.104671, "o", "e"]
[205.192272, "o", "s"]
[205.328423, "o", "."]
[205.415944, "o", "c"]
[205.56821, "o", "o"]
[205.62499, "o", "m"]
[209.419737, "o", "\r\n"]
[209.738094, "o", "+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n| ID | NAME | DATA | REVISION | CREATEDAT | UPD\r\nATEDAT |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n| 2 | app.emissary.cadoles.com | {\"apps\":{\"app.arcad.edge.hextr... | 0 | \"2023-06-23T15:59:50.133065468... | \"20\r\n23-06-23T15:59:50.133065468... |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n"]
[209.739666, "o", "emissary:~# "]
[217.662358, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[16A"]
[226.097445, "o", "\n"]
[226.761446, "o", "\n"]
[227.264713, "o", "^C"]
[227.265531, "o", "root@ArcadAgent:~# "]
[227.464954, "o", "^C\u001b[68;122Hroot@ArcadAgent:~# "]
[229.40574, "o", "\u001b[?25l\u001b[37m\u001b[40m\u001b[82;1H\u001b[32mnumenor\u001b[37m0:ssh* \"numenor\" 18:00 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[68;141H"]
[230.560042, "o", "e"]
[230.744966, "o", "c"]
[230.857095, "o", "h"]
[230.952641, "o", "o"]
[231.056796, "o", " "]
[231.290282, "o", "$"]
[231.592817, "o", "H"]
[231.704742, "o", "O"]
[232.080914, "o", "\u001b[1;81r\u001b[69;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[68;148H\u001b[K\u001b[1;82r\u001b[68;148H"]
[232.224793, "o", "\u001b[1;81r\u001b[69;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[68;147H\u001b[K\u001b[1;82r\u001b[68;147H"]
[232.377174, "o", "\u001b[1;81r\u001b[69;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[68;146H\u001b[K\u001b[1;82r\u001b[68;146H"]
[232.537685, "o", "\u001b[1;81r\u001b[69;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[68;145H\u001b[K\u001b[1;82r\u001b[68;145H"]
[233.025066, "o", " "]
[233.152175, "o", "\""]
[233.472597, "o", "M"]
[233.632988, "o", "y"]
[233.728784, "o", " "]
[234.112825, "o", "h"]
[234.248615, "o", "o"]
[234.328623, "o", "s"]
[234.425096, "o", "t"]
[234.496488, "o", "n"]
[234.62482, "o", "a"]
[234.720164, "o", "m"]
[234.848289, "o", "e"]
[234.960521, "o", " "]
[235.128432, "o", "i"]
[235.191759, "o", "s"]
[235.287951, "o", " "]
[235.400033, "o", "n"]
[235.536368, "o", "o"]
[235.632548, "o", "w"]
[235.808347, "o", " "]
[236.496617, "o", "\""]
[236.993007, "o", "A"]
[237.936908, "o", "\u001b[1;81r\u001b[69;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[68;167H\u001b[K\u001b[1;82r\u001b[68;167H"]
[238.864878, "o", "A"]
[239.288996, "o", "r"]
[239.488633, "o", "c"]
[239.616511, "o", "a"]
[239.744604, "o", "d"]
[240.079979, "o", "e"]
[241.344966, "o", "A"]
[241.568869, "o", "g"]
[241.616463, "o", "e"]
[241.776587, "o", "n"]
[241.880659, "o", "t"]
[242.13686, "o", "\""]
[243.712726, "o", "\""]
[244.176404, "o", "\u001b[69;122HMy hostname is now ArcadeAgent\u001b[70;122Hroot@ArcadAgent:~# "]
[254.221043, "o", "netstat -tlnup"]
[255.105911, "o", "\u001b[71;122H"]
[255.12124, "o", "Active Internet connections (only servers)\u001b[72;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[73;122H"]
[255.121572, "o", "tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[74;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[75;122H"]
[255.121909, "o", "tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[76;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[77;122H"]
[255.122264, "o", "tcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[78;122H"]
[255.122781, "o", "tcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[79;122H"]
[255.123088, "o", "tcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[80;122H"]
[255.123334, "o", "tcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[81;122H"]
[255.123777, "o", "\u001b[?25l\u001b[1dThe client\u001b[K\u001b[2;122Hroot@OpenWrt:~# uci set emissary.agent.server_url=\"http://192.168.30.200:3000\"\u001b[K\u001b[3;122Hroot@OpenWrt:~# uci commit\u001b[K\u001b[4;122Hroot@OpenWrt:~# reload_config\u001b[K\u001b[5;122Hroot@OpenWrt:~# logread -f\u001b[K\u001b[6;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.225 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[7;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[8;122Hence-controller\"}\u001b[K\u001b[9;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[10;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[11;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[12;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, "]
[255.123796, "o", "doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[13;122H\"uci-controller\"}\u001b[K\u001b[14;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[15;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[16;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[17;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[18;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[19;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[20;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[21;122Hence-controller\"}\u001b[K\u001b[22;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-2"]
[255.123939, "o", "3 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[23;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[24;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[25;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[26;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[27;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[28;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[29;122Htroller\"}\u001b[K\u001b[30;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[31;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6C"]
[255.123955, "o", "updating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[32;122Htroller\", \"revision\": 0}\u001b[K\u001b[33;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[34;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[35;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[36;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[37;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1"]
[255.124085, "o", "]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[42;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addre"]
[255.124181, "o", "sses for lan\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[56;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[57;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[58;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[59;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[60;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts -"]
[255.124204, "o", " 4 addresses\u001b[K\u001b[61;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[62;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[63;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[64;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[67;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[68;122HMy hostname is now ArcadeAgent\u001b[K\u001b[69;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[70;122HActive Internet connections (only servers)\u001b[K\u001b[71;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[72;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[73;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[74;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[75;122Htcp 0 0 0"]
[255.124358, "o", ".0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[76;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[77;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[78;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[79;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[80;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h\u001b[?25l\u001b[1droot@OpenWrt:~# uci set emissary.agent.server_url=\"http://192.168.30.200:3000\"\u001b[K\u001b[2;122Hroot@OpenWrt:~# uci commit\u001b[K\u001b[3;122Hroot@OpenWrt:~# reload_config\u001b[K\u001b[4;122Hroot@OpenWrt:~# logread -f\u001b[K\u001b[5;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.225 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[6;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1"]
[255.124375, "o", "X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[7;122Hence-controller\"}\u001b[K\u001b[8;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[9;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[10;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[11;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[12;122H\"uci-controller\"}\u001b[K\u001b[13;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[14;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[15;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5"]
[255.124454, "o", "C<./internal/agent/controller/op\u001b[16;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[17;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[18;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[19;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[20;122Hence-controller\"}\u001b[K\u001b[21;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[22;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[23;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[24;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b"]
[255.124511, "o", "[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[25;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[26;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[27;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[28;122Htroller\"}\u001b[K\u001b[29;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[30;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[31;122Htroller\", \"revision\": 0}\u001b[K\u001b[32;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[33;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[34;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-"]
[255.124532, "o", "06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[35;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[36;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[41;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[44;122HFri Jun 23 "]
[255.124544, "o", "15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[54;"]
[255.124557, "o", "122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[56;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[57;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[58;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[59;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[60;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[61;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[62;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[63;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[66;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b"]
[255.124582, "o", "[K\u001b[67;122HMy hostname is now ArcadeAgent\u001b[K\u001b[68;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[69;122HActive Internet connections (only servers)\u001b[K\u001b[70;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[71;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[72;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[73;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[74;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[75;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[76;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[77;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[78;122Htcp 0 0 fe80::c0ff"]
[255.124709, "o", ":fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[79;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[80;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h\u001b[?25l\u001b[1droot@OpenWrt:~# reload_config\u001b[K\u001b[2;122Hroot@OpenWrt:~# logread -f\u001b[K\u001b[3;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.225 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[4;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[5;122Hence-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[7;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[8;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 "]
[255.1248, "o", "[INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[9;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[10;122H\"uci-controller\"}\u001b[K\u001b[11;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[12;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[13;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[14;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[15;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[16;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[17;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detecte"]
[255.12484, "o", "d, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[18;122Hence-controller\"}\u001b[K\u001b[19;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[20;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[21;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[22;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[23;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[24;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[25;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[26;122Htroller\"}\u001b[K\u001b[27;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: "]
[255.124879, "o", "2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[28;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[29;122Htroller\", \"revision\": 0}\u001b[K\u001b[30;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[31;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[32;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[33;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[34;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[37;"]
[255.124911, "o", "122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[39;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info"]
[255.124948, "o", " dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[56;122HFri Jun 23 15:59:34 20"]
[255.124985, "o", "23 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[57;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[58;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[59;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[60;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[61;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[64;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[65;122HMy hostname is now ArcadeAgent\u001b[K\u001b[66;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[67;122HActive Internet connections (only servers)\u001b[K\u001b[68;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[69;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[70;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 407"]
[255.12503, "o", "6/dnsmasq\u001b[K\u001b[71;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[72;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[73;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[74;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[75;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[76;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[77;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[78;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[79;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[80;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* "]
[255.125068, "o", " 4076/dnsmasq\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h"]
[255.125132, "o", "\u001b[?25l\u001b[1droot@OpenWrt:~# logread -f\u001b[K\u001b[2;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.225 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[3;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[4;122Hence-controller\"}\u001b[K\u001b[5;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[6;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[7;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[8;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[9;122H\"uci-controller\"}\u001b[K\u001b[10;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controll"]
[255.125171, "o", "er/ap\u001b[11;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[12;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[13;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[14;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[15;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[16;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[17;122Hence-controller\"}\u001b[K\u001b[18;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[19;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controll"]
[255.125209, "o", "er\"}\u001b[K\u001b[20;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[21;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[22;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[23;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[24;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[25;122Htroller\"}\u001b[K\u001b[26;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[27;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[28;122Htroller\", \"revision\": 0}\u001b[K\u001b[29;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b["]
[255.125246, "o", "5X\u001b[5C<./internal/agent/controller/ap\u001b[30;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[31;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[32;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[33;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[38;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfi"]
[255.125283, "o", "le\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserv"]
[255.125325, "o", "er 192.168.5.53#53\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[56;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[57;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[58;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hos"]
[255.125362, "o", "ts - 4 addresses\u001b[K\u001b[59;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[60;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[63;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[64;122HMy hostname is now ArcadeAgent\u001b[K\u001b[65;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[66;122HActive Internet connections (only servers)\u001b[K\u001b[67;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[68;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[69;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[70;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[71;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[72;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[73;122Htcp "]
[255.125396, "o", " 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[74;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[75;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[76;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[77;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[78;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[79;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[80;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h"]
[255.125507, "o", "\u001b[?25l\u001b[1dFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.225 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[2;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[3;122Hence-controller\"}\u001b[K\u001b[4;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[5;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[7;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[8;122H\"uci-controller\"}\u001b[K\u001b[9;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[10;122Hp/controller.go:42>\u001b[5X\u001b"]
[255.12555, "o", "[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[11;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[12;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[13;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[14;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[15;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[16;122Hence-controller\"}\u001b[K\u001b[17;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[18;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[19;122HFri Jun 23 15:59:32 20"]
[255.125593, "o", "23 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[20;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[21;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[22;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[23;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[24;122Htroller\"}\u001b[K\u001b[25;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[26;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[27;122Htroller\", \"revision\": 0}\u001b[K\u001b[28;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b"]
[255.125628, "o", "[29;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[30;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[31;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[32;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[37;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023"]
[255.125669, "o", " daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[48;122HFri Jun "]
[255.125704, "o", "23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[56;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[57;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[58;122HFri Jun 23"]
[255.125736, "o", " 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[59;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[62;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[63;122HMy hostname is now ArcadeAgent\u001b[K\u001b[64;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[65;122HActive Internet connections (only servers)\u001b[K\u001b[66;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[67;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[68;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[69;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[70;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[71;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[72;122Htcp 0 0 :::8084 "]
[255.125767, "o", " :::* LISTEN 3471/emissary\u001b[K\u001b[73;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[74;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[75;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[76;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[77;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[78;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[79;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[80;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25hroot@ArcadAgent:~# "]
[258.944464, "o", "e"]
[259.128951, "o", "c"]
[259.168813, "o", "h"]
[259.240703, "o", "o"]
[259.312742, "o", " "]
[259.456279, "o", "\""]
[259.753944, "o", "N"]
[259.880553, "o", "e"]
[260.039821, "o", "w"]
[260.176748, "o", " "]
[260.40835, "o", "a"]
[260.513141, "o", "p"]
[260.664885, "o", "p"]
[260.784994, "o", "l"]
[260.864747, "o", "i"]
[260.967853, "o", "c"]
[261.05623, "o", "a"]
[261.15203, "o", "t"]
[261.208696, "o", "i"]
[261.264736, "o", "o"]
[261.359858, "o", "n"]
[261.520099, "o", "s"]
[261.632929, "o", " "]
[261.832751, "o", "a"]
[262.000749, "o", "r"]
[262.072634, "o", "e"]
[262.200499, "o", " "]
[262.408182, "o", "i"]
[262.495155, "o", "n"]
[262.608733, "o", "s"]
[262.664374, "o", "t"]
[262.736198, "o", "a"]
[262.85664, "o", "l"]
[263.016309, "o", "l"]
[263.088305, "o", "e"]
[263.271612, "o", "d"]
[265.064967, "o", "\""]
[265.641216, "o", "\u001b[?25l\u001b[1;122Hence-controller\"}\u001b[K\u001b[2;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[3;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[4;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[5;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[6;122H\"uci-controller\"}\u001b[K\u001b[7;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[8;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[9;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[10;122Henwrt/sysupgrade_controller."]
[265.641253, "o", "go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[11;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[12;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[13;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[14;122Hence-controller\"}\u001b[K\u001b[15;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[16;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[17;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[18;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[19;122H: \"uci.emissary.ca"]
[265.641268, "o", "doles.com\", \"revision\": 0}\u001b[K\u001b[20;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[21;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[22;122Htroller\"}\u001b[K\u001b[23;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[24;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[25;122Htroller\", \"revision\": 0}\u001b[K\u001b[26;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[27;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[28;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[29;"]
[265.641281, "o", "122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[30;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[35;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addres"]
[265.641294, "o", "ses for onion\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only local"]
[265.641306, "o", "ly-known addresses for localhost\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[56;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[57;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[60;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[61;122HMy hostname is now ArcadeAgent\u001b[K\u001b[62;122Hroot@ArcadAgent:"]
[265.641334, "o", "~# netstat -tlnup\u001b[K\u001b[63;122HActive Internet connections (only servers)\u001b[K\u001b[64;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[65;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[66;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[67;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[68;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[69;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[70;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[71;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[72;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[73"]
[265.64135, "o", ";122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[74;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[75;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[76;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[77;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[78;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[79;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[80;122HNew applications are installed\u001b[K\u001b[81;122Hroot@ArcadAgent:~# \u001b[K\u001b[?12l\u001b[?25h"]
[268.262913, "o", "\u001b[?25l\u001b[1;121H\u001b[32m│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[39m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[56;13H"]
[269.081217, "o", "v"]
[269.153163, "o", "i"]
[269.265339, "o", " "]
[269.81128, "o", "c"]
[269.872513, "o", "o"]
[269.95588, "o", "n"]
[270.065954, "o", "\remissary:~# vi config/\u001b[1;81r\u001b[57;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[56;23H\u001b[98X\u001b[1;82r\u001b[56;23H"]
[270.313035, "o", "m"]
[270.456767, "o", "y"]
[270.559559, "o", "\remissary:~# vi config/my-\u001b[1;81r\u001b[57;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[56;26H\u001b[95X\u0007\u001b[1;82r\u001b[56;26H"]
[271.297045, "o", "c"]
[271.521003, "o", "\u0007"]
[272.081294, "o", "\u001b[1;81r\u001b[57;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[56;26H\u001b[95X\u001b[1;82r\u001b[56;26H"]
[272.273395, "o", "\remissary:~# vi config/my-\u001b[1;81r\u001b[57;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[56;26H\u001b[95X\u0007\u001b[1;82r\u001b[56;26H"]
[272.729045, "o", "\r\nmy-agent-config.json my-uci-spec.json\r\nemissary:~# vi config/my-\u001b[1;81r\u001b[59;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[58;26H\u001b[95X\u001b[1;82r\u001b[58;26H"]
[273.545161, "o", "u"]
[273.625572, "o", "\remissary:~# vi config/my-uci-spec.json \u001b[1;81r\u001b[59;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[58;40H\u001b[81X\u001b[1;82r\u001b[58;40H"]
[274.186674, "o", "\r\n"]
[274.189049, "o", "\u001b[?25l\u001b[1;120H\u001b[1K\u001b[H{\u001b[2;120H\u001b[1K\u001b[2G\u001b[1K\u001b[C\"config\": {\u001b[3;120H\u001b[1K\u001b[4G\u001b[1K\u001b[C\"packages\": [\u001b[4;120H\u001b[1K\u001b[6G\u001b[1K\u001b[C{\u001b[5;120H\u001b[1K\u001b[8G\u001b[1K\u001b[C\"name\": \"dhcp\",\u001b[6;120H\u001b[1K\u001b[8G\u001b[1K\u001b[C\"configs\": [\u001b[7;120H\u001b[1K\u001b[10G\u001b[1K\u001b[C{\u001b[8;120H\u001b[1K\u001b[12G\u001b[1K\u001b[C\"name\": \"dnsmasq\",\u001b[9;120H\u001b[1K\u001b[12G\u001b[1K\u001b[C\"options\": [\u001b[10;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[11;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[12;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"domainneeded\",\u001b[13;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[14;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[15;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[16;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[17;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"boguspriv\",\u001b[18;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[19;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[20;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[21;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[22;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"filterwin2k\",\u001b[23;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"0\"\u001b[24;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[25;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[26;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[27;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"localise_queries\",\u001b[28;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[29;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[30;120H\u001b[1"]
[274.189076, "o", "K\u001b[14G\u001b[1K\u001b[C{\u001b[31;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[32;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"rebind_localhost\",\u001b[33;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[34;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[35;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[36;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[37;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"local\",\u001b[38;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"/lan/\"\u001b[39;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[40;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[41;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[42;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"domain\",\u001b[43;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"lan\"\u001b[44;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[45;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[46;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[47;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"expandhosts\",\u001b[48;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[49;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[50;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[51;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[52;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"nonegcache\",\u001b[53;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"0\"\u001b[54;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[55;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[56;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[57;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"authoritative\",\u001b[58;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C"]
[274.189089, "o", "\"value\": \"1\"\u001b[59;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[60;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[61;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[62;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"readethers\",\u001b[63;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[64;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[65;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[66;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[67;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"leasefile\",\u001b[68;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"/tmp/dhcp.leases\"\u001b[69;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[70;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[71;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[72;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"resolvfile\",\u001b[73;16H\u001b[1K\u001b[C\"value\": \"/tmp/resolv.conf.d/resolv.conf.auto\"\u001b[58X\u001b[74;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[75;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[76;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"type\": \"option\",\u001b[77;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"name\": \"nonwildcard\",\u001b[78;120H\u001b[1K\u001b[16G\u001b[1K\u001b[C\"value\": \"1\"\u001b[79;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C},\u001b[80;120H\u001b[1K\u001b[14G\u001b[1K\u001b[C{\u001b[81;120H\u001b[1K\r- config/my-uci-spec.json 1/1574 0%\u001b[?12l\u001b[?25h\u001b[H"]
[276.0343, "o", "\u001b[81d/\u001b[119X\u0007"]
[277.681058, "o", "A"]
[277.977808, "o", "r"]
[278.176983, "o", "c"]
[278.304404, "o", "a"]
[278.417316, "o", "d"]
[278.912726, "o", "A"]
[279.096756, "o", "g"]
[279.345984, "o", "\u001b[H \"value\": \"30\"\u001b[2;3H }\u001b[3;5H ] \u001b[4;7H },\u001b[5;9H { \u001b[6;9H \"name\": \"login\",\u001b[7;11H \"options\": [\u001b[8;13H { \u001b[9;13H \"type\": \"option\",\u001b[10;15H \"name\": \"username\",\u001b[11;18Hvalue\": \"root\" \u001b[12;15H}, \u001b[13;15H{ \u001b[14;15H \"type\": \"option\",\u001b[15;15H \"name\": \"password\",\u001b[16;18Hvalue\": \"$p$root\"\u001b[17;15H}, \u001b[18;15H{ \u001b[19;15H \"type\": \"list\",\u001b[20;15H \"name\": \"read\",\u001b[21;18Hvalue\": \"*\" \u001b[22;15H}, \u001b[23;15H{ \u001b[24;15H \"type\": \"list\",\u001b[25;15H \"name\": \"write\",\u001b[26;18Hvalue\": \"*\" \u001b[27;15H} \u001b[28;13H] \u001b[29;11H} \u001b[30;9H] \u001b[31;7H}, \u001b[32;7H{ \u001b[33;9H\"name\": \"system\", \u001b[34;9H\"configs\": [\u001b[35;11H{ \u001b[36;13H\"name\": \"system\", \u001b[37;13H\"options\": [ \u001b[38;15H{ \u001b[39;15H \"type\": \"option\",\u001b[40;15H \"name\": \"hostname\",\u001b[41;18Hvalu"]
[279.34602, "o", "e\": \"ArcadAgent\"\u001b[42;15H}, \u001b[43;15H{ \u001b[44;15H \"type\": \"option\",\u001b[45;15H \"name\": \"timezone\",\u001b[46;18Hvalue\": \"UTC\" \u001b[47;15H}, \u001b[48;15H{ \u001b[49;15H \"type\": \"option\",\u001b[50;15H \"name\": \"ttylogin\",\u001b[51;18Hvalue\": \"0\" \u001b[52;15H}, \u001b[53;15H{ \u001b[54;15H \"type\": \"option\",\u001b[55;15H \"name\": \"log_size\",\u001b[56;18Hvalue\": \"64\" \u001b[57;15H}, \u001b[58;15H{ \u001b[59;15H \"type\": \"option\",\u001b[60;15H \"name\": \"urandom_seed\",\u001b[61;18Hvalue\": \"0\" \u001b[62;15H} \u001b[63;13H] \u001b[64;11H}, \u001b[65;11H{ \u001b[66;13H\"name\": \"timeserver\u001b[67;13H\"section\": \"ntp\", \u001b[68;13H\"options\": [ \u001b[69;15H{ \u001b[70;15H \"type\": \"option\",\u001b[71;18Hname\": \"enabled\",\u001b[72;18Hvalue\": \"1\" \u001b[73;15H}, \u001b[74;15H{ \u001b[75;15H \"type\": \"option\",\u001b[76;18Hname\": \"enable_server\",\u001b[77;18Hvalue\": \"0\" \u001b[78;15H}, \u001b[79;15H{ \u001b[80;15H \"type"]
[279.346032, "o", "\": \"list\",\r\n- config/my-uci-spec.json 1146/1574 72%\u001b[81X\u001b[41;27H"]
[281.659897, "o", "\u001b[81;1HI config/my-uci-spec.json 1146/1574 72%\u001b[81X\u0007\u001b[41;27H"]
[282.121181, "o", "NArcadAgent\"\u001b[11D"]
[282.305551, "o", "eArcadAgent\"\u001b[11D"]
[282.450581, "o", "wArcadAgent\"\u001b[11D"]
[283.555238, "o", "\u001b[81;1H:\u001b[119X"]
[283.624391, "o", "w"]
[283.792746, "o", "q"]
[284.154207, "o", "\u001b[116C\u001b[1K\r"]
[284.154458, "o", "\u001b[?25l\u001b[1;120H\u001b[1K\u001b[Hemissary:~# echo \"The server\"\u001b[2;120H\u001b[1K\rThe server\u001b[3;120H\u001b[1K\remissary:~# emissary api agent query\r\n+----+-------+------------+--------+-------------+-----------+\u001b[58X\r\n| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT |\u001b[58X\r\n+----+-------+------------+--------+-------------+-----------+\u001b[58X\r\n+----+-------+------------+--------+-------------+-----------+\u001b[58X\u001b[8;120H\u001b[1K\remissary:~# emissary api agent query\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\u001b[10;120H\u001b[1K\r----------+\r\n| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT \u001b[12;120H\u001b[1K\r |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\u001b[14;120H\u001b[1K\r----------+\r\n| 1 | | 23ZQ4yoK869AFHJ6ryA8EpnAz8ZESr... | 0 | 2023-06-23 15:57:32.068805967 ... | \"2023-06-23T15:57:31.807\u001b[16;120H\u001b[1K\r"]
[284.15451, "o", "03548Z... |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\u001b[18;120H\u001b[1K\r----------+\u001b[19;120H\u001b[1K\remissary:~# ^Cissary api agent query\u001b[20;120H\u001b[1K\r\nemissary:~# emissary api agent update --agent-id 1 --status 1\u001b[59X\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\u001b[23;120H\u001b[1K\r----------+\r\n| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT \u001b[25;120H\u001b[1K\r |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\u001b[27;120H\u001b[1K\r----------+\r\n| 1 | | 23ZQ4yoK869AFHJ6ryA8EpnAz8ZESr... | 1 | 2023-06-23 15:57:32.068805967 ... | \"2023-06-23T15:58:05.165\u001b[29;120H\u001b[1K\r446799... |\r\n+----+-------+-----------------------------------+--------+-----------------------------------+-------------------------\u001b[31;120H\u001b[1K\r----------+"]
[284.154608, "o", "\r\nemissary:~# cat config/my-uci-spec.json | emissary api agent spec update -a 1 --no-patch --spec-data - --spec-name uci.e\u001b[33;120H\u001b[1K\rmissary.cadoles.com\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\u001b[35;120H\u001b[1K\r-------------------------------+\r\n| ID | NAME | DATA | REVISION | CREATEDAT | UPD\u001b[37;120H\u001b[1K\rATEDAT |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\u001b[39;120H\u001b[1K\r-------------------------------+\r\n| 1 | uci.emissary.cadoles.com | {\"config\":{\"packages\":[{\"confi... | 0 | \"2023-06-23T15:59:00.937205005... | \"20\u001b[41;120H\u001b[1K\r23-06-23T15:59:00.937205005... |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\u001b[43;120H\u001b[1K\r-------------------------------+\r\nemissary:~# cat config/app."]
[284.154621, "o", "emissary.cadoles.com.json | emissary api agent spec update -a 1 --no-patch --spec-data - --sp\u001b[45;120H\u001b[1K\rec-name app.emissary.cadoles.com\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\u001b[47;120H\u001b[1K\r-------------------------------+\r\n| ID | NAME | DATA | REVISION | CREATEDAT | UPD\u001b[49;120H\u001b[1K\rATEDAT |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\u001b[51;120H\u001b[1K\r-------------------------------+\r\n| 2 | app.emissary.cadoles.com | {\"apps\":{\"app.arcad.edge.hextr... | 0 | \"2023-06-23T15:59:50.133065468... | \"20\u001b[53;120H\u001b[1K\r23-06-23T15:59:50.133065468... |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\u001b[55;120H\u001b[1K\r-------------------------------+\u001b[56;120H\u001b[1K\remissary:~# vi config/my-\u001b[57;1"]
[284.154766, "o", "20H\u001b[1K\rmy-agent-config.json my-uci-spec.json\u001b[58;120H\u001b[1K\remissary:~# vi config/my-uci-spec.json \u001b[59;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[?12l\u001b[?25h\u001b[59;1Hemissary:~# "]
[285.288747, "o", "\remissary:~# vi config/my-uci-spec.json \u001b[1;81r\u001b[60;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[59;40H\u001b[81X\u001b[1;82r\u001b[59;40H"]
[285.546285, "o", "\remissary:~# cat config/app.emissary.cadoles.com.json | emissary api agent spec update -a 1 --no-patch --spec-data - --sp\r\nec-name app.emissary.cadoles.com\u001b[1;81r\u001b[61;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[60;33H\u001b[88X\u001b[1;82r\u001b[60;33H"]
[285.833525, "o", "\u001b[59;1Hemissary:~# cat config/my-uci-spec.json | emissary api agent spec update -a 1 --no-patch --spec-data - --spec-name uci.e\r\nmissary.cadoles.com\u001b[1;81r\u001b[61;120H\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\n\u001b[1K\u001b[60;20H\u001b[101X\u001b[1;82r\u001b[60;20H"]
[289.415637, "o", "\u001b[?25l\u001b[37m\u001b[40m\u001b[82;1H\u001b[32mnumenor\u001b[37m0:ssh* \"numenor\" 18:01 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[60;20H"]
[289.826581, "o", "\r\n"]
[290.081445, "o", "+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n| ID | NAME | DATA | REVISION | CREATEDAT | UPD\r\nATEDAT |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n| 1 | uci.emissary.cadoles.com | {\"config\":{\"packages\":[{\"confi... | 1 | \"2023-06-23T15:59:00.937205005... | \"20\r\n23-06-23T16:01:10.546999379... |\r\n+----+--------------------------+-----------------------------------+----------+-----------------------------------+----\r\n-------------------------------+\r\n"]
[290.081594, "o", "emissary:~# "]
[291.718595, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[19C"]
[295.169644, "o", "l"]
[295.352434, "o", "o"]
[295.752737, "o", "g"]
[296.048604, "o", "r"]
[296.505008, "o", "e"]
[296.633205, "o", "\u001b[24Droot@ArcadAgent:~# logread \u001b[1;81r\u001b[81;149H\u001b[K\u001b[1;82r\u001b[81;149H"]
[297.256572, "o", "-"]
[297.368874, "o", "f"]
[297.489328, "o", "\u001b[?25l\u001b[1;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[2;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[3;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[4;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[5;122H\"uci-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[7;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[8;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[9;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeCon"]
[297.489364, "o", "troller).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[10;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[11;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[12;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[13;122Hence-controller\"}\u001b[K\u001b[14;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[15;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[16;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[17;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[18;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K"]
[297.48938, "o", "\u001b[19;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[20;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[21;122Htroller\"}\u001b[K\u001b[22;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[23;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[24;122Htroller\", \"revision\": 0}\u001b[K\u001b[25;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[26;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[27;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[28;122Henwrt/sysupgrade_controll"]
[297.489393, "o", "er.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[29;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[34;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[38;122HFri "]
[297.489523, "o", "Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localh"]
[297.489551, "o", "ost\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[55;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[56;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[59;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[60;122HMy hostname is now ArcadeAgent\u001b[K\u001b[61;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[62;122H"]
[297.489566, "o", "Active Internet connections (only servers)\u001b[K\u001b[63;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[64;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[65;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[66;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[67;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[68;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[69;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[70;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[71;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[72;122Htcp 0 0 :::2"]
[297.489579, "o", "2 :::* LISTEN 2087/dropbear\u001b[K\u001b[73;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[74;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[75;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[76;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[77;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[78;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[79;122HNew applications are installed\u001b[K\u001b[80;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h"]
[309.145484, "o", "\u001b[?25l\u001b[1doxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[2;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[3;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[4;122H\"uci-controller\"}\u001b[K\u001b[5;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[6;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[7;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[8;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[9;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[10;"]
[309.145522, "o", "122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[11;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[12;122Hence-controller\"}\u001b[K\u001b[13;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[14;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[15;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[16;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[17;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[18;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[19"]
[309.145539, "o", ";122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[20;122Htroller\"}\u001b[K\u001b[21;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[22;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[23;122Htroller\", \"revision\": 0}\u001b[K\u001b[24;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[25;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[26;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[27;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[28;122Hothing\u001b[2X\u001b[2C{\"controller\": "]
[309.145694, "o", "\"sysupgrade-controller\"}\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[33;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemo"]
[309.145726, "o", "n.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[48;122HFri Jun 23 15:5"]
[309.145743, "o", "9:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[54;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[55;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[58;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[59;122HMy hostname is now ArcadeAgent\u001b[K\u001b[60;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[61;122HActive Internet connections (only servers)\u001b[K\u001b[62;122HProto Recv-Q Send-Q Local Address Foreign Address State P"]
[309.145863, "o", "ID/Program name \u001b[K\u001b[63;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[64;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[65;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[66;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[67;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[68;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[69;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[70;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[71;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[72;122Htcp 0 0 :::80 :::* "]
[309.145928, "o", " LISTEN 1511/uhttpd\u001b[K\u001b[73;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[74;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[75;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[76;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[77;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[78;122HNew applications are installed\u001b[K\u001b[79;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[80;122H\u001b[K\n\u001b[K\u001b[?12l\u001b[?25h"]
[309.544826, "o", "^Croot@ArcadAgent:~# "]
[310.177471, "o", "\u001b[?25l\u001b[1;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[2;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[3;122H\"uci-controller\"}\u001b[K\u001b[4;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[5;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[7;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[8;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[9;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[10;122"]
[310.17751, "o", "Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[11;122Hence-controller\"}\u001b[K\u001b[12;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[13;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[14;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[15;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[16;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[17;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[18;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-co"]
[310.177526, "o", "n\u001b[19;122Htroller\"}\u001b[K\u001b[20;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[21;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[22;122Htroller\", \"revision\": 0}\u001b[K\u001b[23;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[24;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[25;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[26;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[27;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[29;122HFri Jun "]
[310.17769, "o", "23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[32;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only"]
[310.177716, "o", " locally-known addresses for invalid\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsma"]
[310.177724, "o", "sq[1]: using only locally-known addresses for bind\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[53;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[54;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[57;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[58;122HMy hostname is now ArcadeAgent\u001b[K\u001b[59;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[60;122HActive Internet connections (only servers)\u001b[K\u001b[61;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[62;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[63;122"]
[310.177733, "o", "Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[64;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[65;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[66;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[67;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[68;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[69;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[70;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[71;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[72;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076"]
[310.17788, "o", "/dnsmasq\u001b[K\u001b[73;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[74;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[75;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[76;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[77;122HNew applications are installed\u001b[K\u001b[78;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[79;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[81;122Hroot@ArcadAgent:~# \u001b[K\u001b[?12l\u001b[?25h"]
[310.36104, "o", "\u001b[?25l\u001b[1;122Henwrt/uci_controller.go:32>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Ccould not find uci spec, doing nothing\u001b[2X\u001b[2C{\"controller\": \u001b[2;122H\"uci-controller\"}\u001b[K\u001b[3;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[4;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[5;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[6;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[7;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[8;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[9;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist"]
[310.361085, "o", "\u001b[10;122Hence-controller\"}\u001b[K\u001b[11;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[12;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[13;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[14;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[15;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[16;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[17;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[18;122Htroller\"}\u001b[K\u001b[19;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./intern"]
[310.361098, "o", "al/agent/controller/op\u001b[20;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[21;122Htroller\", \"revision\": 0}\u001b[K\u001b[22;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[23;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[24;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[25;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[26;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 daemon.info dnsmas"]
[310.361108, "o", "q[1]: DNS service limited to local subnets\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[31;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses"]
[310.361117, "o", " for bind\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-k"]
[310.361342, "o", "nown addresses for lan\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[51;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[52;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[53;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[56;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[57;122HMy hostname is now ArcadeAgent\u001b[K\u001b[58;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[59;122HActive Internet connections (only servers)\u001b[K\u001b[60;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[61;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[62;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[63;122Htcp 0 0 0.0.0."]
[310.361378, "o", "0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[64;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[65;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[66;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[67;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[68;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[69;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[70;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[71;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[72;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[73;122Hudp "]
[310.361389, "o", " 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[74;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[75;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[76;122HNew applications are installed\u001b[K\u001b[77;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[78;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[80;122Hroot@ArcadAgent:~# \u001b[K\u001b[81;122Hroot@ArcadAgent:~# \u001b[K\u001b[?12l\u001b[?25h"]
[311.633197, "o", "h"]
[311.768577, "o", "o"]
[311.87281, "o", "s"]
[311.969677, "o", "t"]
[312.081036, "o", "n"]
[312.201739, "o", "\u0007"]
[312.784528, "o", "a"]
[312.929515, "o", "m"]
[313.0326, "o", "e"]
[313.594965, "o", "\u001b[?25l\u001b[1;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.657 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[2;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[3;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[4;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[5;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[7;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[8;122Hence-controller\"}\u001b[K\u001b[9;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[10;122"]
[313.595005, "o", "Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[11;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[12;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[13;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[14;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[15;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[16;122Htroller\"}\u001b[K\u001b[17;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[18;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[19;12"]
[313.595021, "o", "2Htroller\", \"revision\": 0}\u001b[K\u001b[20;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[21;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[22;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[23;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[24;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN"]
[313.595034, "o", " DHCP\u001b[29;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq"]
[313.595047, "o", "[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq"]
[313.595225, "o", "[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[50;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[51;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[54;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[55;122HMy hostname is now ArcadeAgent\u001b[K\u001b[56;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[57;122HActive Internet connections (only servers)\u001b[K\u001b[58;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[59;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[60;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[61;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[62;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhtt"]
[313.595259, "o", "pd\u001b[K\u001b[63;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[64;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[65;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[66;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[67;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[68;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[69;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[70;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[71;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[72;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* "]
[313.595275, "o", " 4076/dnsmasq\u001b[K\u001b[73;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[74;122HNew applications are installed\u001b[K\u001b[75;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[76;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[78;122Hroot@ArcadAgent:~# \u001b[K\u001b[79;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[80;122H-ash: hostname: not found\u001b[K\u001b[81;122Hroot@ArcadAgent:~# \u001b[K\u001b[?12l\u001b[?25h"]
[315.528948, "o", "\u001b[19Droot@ArcadAgent:~# hostname\u001b[1;81r\u001b[81;149H\u001b[K\u001b[1;82r\u001b[81;149H"]
[315.823738, "o", "\u001b[27Droot@ArcadAgent:~# logread -f\u001b[1;81r\u001b[81;151H\u001b[K\u001b[1;82r\u001b[81;151H"]
[316.249269, "o", "\u001b[?25l\u001b[1;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[2;122HFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[3;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[4;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[5;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[6;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[7;122Hence-controller\"}\u001b[K\u001b[8;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[9;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b"]
[316.249309, "o", "[10;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[11;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[12;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[13;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[14;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[15;122Htroller\"}\u001b[K\u001b[16;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[17;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[18;122Htroller\", \"revision\": 0}\u001b[K\u001b[19;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<."]
[316.249324, "o", "/internal/agent/controller/ap\u001b[20;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[21;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[22;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[23;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[24;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[28;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[2"]
[316.249473, "o", "9;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.1"]
[316.249544, "o", "68.5.53#53\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 a"]
[316.249653, "o", "ddresses\u001b[K\u001b[49;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[50;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[53;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[54;122HMy hostname is now ArcadeAgent\u001b[K\u001b[55;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[56;122HActive Internet connections (only servers)\u001b[K\u001b[57;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[58;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[59;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[60;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[61;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[62;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[63;122Htcp 0"]
[316.249767, "o", " 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[64;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[65;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[66;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[67;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[68;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[69;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[70;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[71;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[72;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[73;122HNew applications are installed\u001b"]
[316.249826, "o", "[K\u001b[74;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[75;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[77;122Hroot@ArcadAgent:~# \u001b[K\u001b[78;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[79;122H-ash: hostname: not found\u001b[K\u001b[80;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h"]
[337.313431, "o", "\u001b[?25l\u001b[1dFri Jun 23 15:58:32 2023 daemon.info emissary[3471]: 2023-06-23 15:58:32.658 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[2;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[3;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[4;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[5;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[6;122Hence-controller\"}\u001b[K\u001b[7;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[8;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[9;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[10;"]
[337.313792, "o", "122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[11;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[12;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[13;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[14;122Htroller\"}\u001b[K\u001b[15;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[16;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[17;122Htroller\", \"revision\": 0}\u001b[K\u001b[18;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[19;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controll"]
[337.313947, "o", "er\": \"app-controller\"}\u001b[K\u001b[20;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[21;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[22;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[23;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[24;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[27;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[29;122HFri Jun 23 15:59:34 202"]
[337.313974, "o", "3 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[39;122HFri Jun 2"]
[337.313991, "o", "3 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[48;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[49;122H\u001b[K\n\u001b[K\n^C"]
[337.314052, "o", "root@ArcadAgent:~# ^C\u001b[K\u001b[52;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[53;122HMy hostname is now ArcadeAgent\u001b[K\u001b[54;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[55;122HActive Internet connections (only servers)\u001b[K\u001b[56;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[57;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[58;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[59;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[60;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[61;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[62;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[63;122Htcp 0 0 ::1:53 "]
[337.314069, "o", " :::* LISTEN 4076/dnsmasq\u001b[K\u001b[64;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[65;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[66;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[67;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[68;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[69;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[70;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[71;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[72;122HNew applications are installed\u001b[K\u001b[73;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[74;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[76;122Hroot@ArcadAgent:~# \u001b[K\u001b[77;122Hroot@ArcadAgent"]
[337.314081, "o", ":~# hostname\u001b[K\u001b[78;122H-ash: hostname: not found\u001b[K\u001b[79;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[80;122H\u001b[K\n\u001b[K\u001b[?12l\u001b[?25h"]
[337.569106, "o", "\u001b[?25l\u001b[1denwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[2;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[3;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[4;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[5;122Hence-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[7;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[8;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[9;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"sp"]
[337.569144, "o", "ec\"\u001b[10;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[11;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[12;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[13;122Htroller\"}\u001b[K\u001b[14;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[15;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[16;122Htroller\", \"revision\": 0}\u001b[K\u001b[17;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[18;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[19;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./int"]
[337.569158, "o", "ernal/agent/controller/op\u001b[20;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[21;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[22;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[23;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[24;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[26;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: u"]
[337.569169, "o", "sing only locally-known addresses for onion\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.inf"]
[337.569181, "o", "o dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[47;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[48;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[51;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[52;122HMy hostname is now ArcadeAge"]
[337.569193, "o", "nt\u001b[K\u001b[53;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[54;122HActive Internet connections (only servers)\u001b[K\u001b[55;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[56;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[57;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[58;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[59;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[60;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[61;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[62;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[63;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* "]
[337.569381, "o", "LISTEN 4076/dnsmasq\u001b[K\u001b[64;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[65;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[66;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[67;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[68;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[69;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[70;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[71;122HNew applications are installed\u001b[K\u001b[72;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[73;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[75;122Hroot@ArcadAgent:~# \u001b[K\u001b[76;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[77;122H-ash: hostname: not found\u001b[K\u001b[78;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[79;122H\u001b[K\n\u001b[K\n\u001b[K\u001b[?12l\u001b[?25h"]
[337.738842, "o", "\u001b[?25l\u001b[1dothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[2;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[3;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[4;122Hence-controller\"}\u001b[K\u001b[5;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[6;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[7;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[8;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[9;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[10;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23"]
[337.738882, "o", " 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[11;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[12;122Htroller\"}\u001b[K\u001b[13;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[14;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[15;122Htroller\", \"revision\": 0}\u001b[K\u001b[16;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[17;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[18;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[19;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find"]
[337.738896, "o", " sysupgrade spec, doing n\u001b[20;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[21;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[22;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[23;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[24;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[25;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known ad"]
[337.738909, "o", "dresses for localhost\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using on"]
[337.73892, "o", "ly locally-known addresses for local\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[46;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[47;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[50;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[51;122HMy hostname is now ArcadeAgent\u001b[K\u001b[52;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[53;122HActive Internet connections (only servers)\u001b[K\u001b[54;122HProto Recv-Q Send-"]
[337.738933, "o", "Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[55;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[56;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[57;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[58;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[59;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[60;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[61;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[62;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[63;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K"]
[337.738946, "o", "\u001b[64;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[65;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[66;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[67;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[68;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[69;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[70;122HNew applications are installed\u001b[K\u001b[71;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[72;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[74;122Hroot@ArcadAgent:~# \u001b[K\u001b[75;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[76;122H-ash: hostname: not found\u001b[K\u001b[77;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[78;122H\u001b[K\n\u001b[K\n\u001b[K\n\u001b[K\u001b[?12l\u001b[?25h"]
[342.433133, "o", "^C"]
[342.433766, "o", "root@NewArcadAgent:~# "]
[343.272942, "o", "\u001b[?25l\u001b[1;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.218 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pe\u001b[2;122Hrsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[3;122Hence-controller\"}\u001b[K\u001b[4;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[5;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[6;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[7;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[8;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[9;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b["]
[343.272981, "o", "10;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[11;122Htroller\"}\u001b[K\u001b[12;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[13;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[14;122Htroller\", \"revision\": 0}\u001b[K\u001b[15;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[16;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[17;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[18;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[19;122Hothing\u001b[2X\u001b[2C{\"controller\""]
[343.273006, "o", ": \"sysupgrade-controller\"}\u001b[K\u001b[20;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[21;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[22;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[23;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[24;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 dae"]
[343.273163, "o", "mon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[39;122HFri Jun 23 15"]
[343.2732, "o", ":59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[45;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[46;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[49;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[50;122HMy hostname is now ArcadeAgent\u001b[K\u001b[51;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[52;122HActive Internet connections (only servers)\u001b[K\u001b[53;122HProto Recv-Q Send-Q Local Address Foreign Address State "]
[343.273211, "o", " PID/Program name \u001b[K\u001b[54;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[55;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[56;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[57;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[58;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[59;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[60;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[61;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[62;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[63;122Htcp 0 0 :::80 :::* "]
[343.273309, "o", " LISTEN 1511/uhttpd\u001b[K\u001b[64;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[65;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[66;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[67;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[68;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[69;122HNew applications are installed\u001b[K\u001b[70;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[71;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[73;122Hroot@ArcadAgent:~# \u001b[K\u001b[74;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[75;122H-ash: hostname: not found\u001b[K\u001b[76;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[77;122H\u001b[K\n\u001b[K\n\u001b[K\n^Croot@NewArcadAgent:~# \u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h"]
[343.273698, "o", "\u001b[?25l\u001b[1drsistence/controller.go:58>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Cno changes detected, doing nothing\u001b[6X\u001b[6C{\"controller\": \"persist\u001b[2;122Hence-controller\"}\u001b[K\u001b[3;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[4;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[5;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[6;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[7;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[8;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[9;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-c"]
[343.273726, "o", "on\u001b[10;122Htroller\"}\u001b[K\u001b[11;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[12;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[13;122Htroller\", \"revision\": 0}\u001b[K\u001b[14;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[15;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[16;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[17;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[18;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[19;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[20;122HFri Jun"]
[343.273741, "o", " 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[21;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: DNS service limited to local subnets\u001b[K\u001b[22;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[23;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[24;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using onl"]
[343.273755, "o", "y locally-known addresses for invalid\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsm"]
[343.27388, "o", "asq[1]: using only locally-known addresses for bind\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[44;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[45;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[48;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[49;122HMy hostname is now ArcadeAgent\u001b[K\u001b[50;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[51;122HActive Internet connections (only servers)\u001b[K\u001b[52;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[53;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[54;12"]
[343.27391, "o", "2Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[55;122Htcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[56;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[57;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[58;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[59;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[60;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[61;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[62;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[63;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076"]
[343.273926, "o", "/dnsmasq\u001b[K\u001b[64;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[65;122Hudp 0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[66;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[67;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[68;122HNew applications are installed\u001b[K\u001b[69;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[70;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[72;122Hroot@ArcadAgent:~# \u001b[K\u001b[73;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[74;122H-ash: hostname: not found\u001b[K\u001b[75;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[76;122H\u001b[K\n\u001b[K\n\u001b[K\n^Croot@NewArcadAgent:~# \u001b[K\u001b[80;122HConnection to 192.168.10.230 closed.\u001b[K\u001b[81;122H\u001b[K\u001b[?12l\u001b[?25h"]
[343.274131, "o", " \u001b[81;122H"]
[343.41012, "o", "\u001b[1;81r\u001b[81;122H\u001b[K\u001b[36mtmux \u001b[39m\u001b[1mpcaseiro@numenor:~/code/cadoles/emissary\u001b(B\u001b[m (pts/27 \u001b[4m-zsh 5.9\u001b(B\u001b[m UltimaThule) \u001b[1m18:02:04 \u001b(B\u001b[m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[32mmaster\u001b[35m|\u001b[33m+1\u001b[39m…\u001b[1;82r\u001b[81;162H"]
[343.410399, "o", "\u001b[?25l\u001b[1;122Hence-controller\"}\u001b[K\u001b[2;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.598 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/pr\u001b[3;122Hoxy/controller.go:35>\u001b[3X\u001b[3C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find proxy spec\u001b[7X\u001b[7C{\"controller\": \"proxy-controller\"}\u001b[K\u001b[4;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.606 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[5;122Henwrt/uci_controller.go:40>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cretrieved spec\u001b[2X\u001b[2C{\"controller\": \"uci-controller\", \"spec\"\u001b[6;122H: \"uci.emissary.cadoles.com\", \"revision\": 0}\u001b[K\u001b[7;122HFri Jun 23 15:59:32 2023 daemon.info emissary[3471]: 2023-06-23 15:59:32.607 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[8;122Henwrt/uci_controller.go:61>\u001b[5X\u001b[5C(*UCIController).updateConfiguration\u001b[4X\u001b[4Cimporting uci config\u001b[4X\u001b[4C{\"controller\": \"uci-con\u001b[9;122Htroller\"}\u001b[K\u001b[10;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/"]
[343.410474, "o", "agent/controller/op\u001b[11;122Henwrt/uci_controller.go:55>\u001b[5X\u001b[5C(*UCIController).Reconcile\u001b[6X\u001b[6Cupdating current spec revision\u001b[2X\u001b[2C{\"controller\": \"uci-con\u001b[12;122Htroller\", \"revision\": 0}\u001b[K\u001b[13;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/ap\u001b[14;122Hp/controller.go:42>\u001b[5X\u001b[5C(*Controller).Reconcile\u001b[1X\u001b[Ccould not find app spec\u001b[1X\u001b[C{\"controller\": \"app-controller\"}\u001b[K\u001b[15;122HFri Jun 23 15:59:33 2023 daemon.info emissary[3471]: 2023-06-23 15:59:33.128 [INFO]\u001b[5X\u001b[5C<./internal/agent/controller/op\u001b[16;122Henwrt/sysupgrade_controller.go:36>\u001b[6X\u001b[6C(*SysUpgradeController).Reconcile\u001b[7X\u001b[7Ccould not find sysupgrade spec, doing n\u001b[17;122Hothing\u001b[2X\u001b[2C{\"controller\": \"sysupgrade-controller\"}\u001b[K\u001b[18;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: exiting on receipt of SIGTERM\u001b[K\u001b[19;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: started, version 2.86 cachesize 150\u001b[K\u001b[20;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1"]
[343.410598, "o", "]: DNS service limited to local subnets\u001b[K\u001b[21;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: compile time options: IPv6 GNU-getopt no-DBus UBus no-i18n no-IDN DHCP\u001b[22;122H no-DHCPv6 no-Lua TFTP no-conntrack no-ipset no-auth no-cryptohash no-DNSSEC no-ID loop-detect inotify dumpfile\u001b[K\u001b[23;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: UBus support enabled: connected to system bus\u001b[K\u001b[24;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[25;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[26;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[27;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[28;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[29;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses fo"]
[343.41063, "o", "r bind\u001b[K\u001b[30;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for lan\u001b[K\u001b[31;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: reading /tmp/resolv.conf.d/resolv.conf.auto\u001b[K\u001b[32;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using nameserver 192.168.5.53#53\u001b[K\u001b[33;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for test\u001b[K\u001b[34;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for onion\u001b[K\u001b[35;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for localhost\u001b[K\u001b[36;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for local\u001b[K\u001b[37;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for invalid\u001b[K\u001b[38;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-known addresses for bind\u001b[K\u001b[39;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: using only locally-know"]
[343.410642, "o", "n addresses for lan\u001b[K\u001b[40;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[41;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[42;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /etc/hosts - 4 addresses\u001b[K\u001b[43;122HFri Jun 23 15:59:34 2023 daemon.info dnsmasq[1]: read /tmp/hosts/dhcp.cfg01411c - 0 addresses\u001b[K\u001b[44;122H\u001b[K\n\u001b[K\n^Croot@ArcadAgent:~# ^C\u001b[K\u001b[47;122Hroot@ArcadAgent:~# echo \"My hostname is now \"ArcadeAgent\"\"\u001b[K\u001b[48;122HMy hostname is now ArcadeAgent\u001b[K\u001b[49;122Hroot@ArcadAgent:~# netstat -tlnup\u001b[K\u001b[50;122HActive Internet connections (only servers)\u001b[K\u001b[51;122HProto Recv-Q Send-Q Local Address Foreign Address State PID/Program name \u001b[K\u001b[52;122Htcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[53;122Htcp 0 0 192.168.10.230:53 0.0.0.0:* LISTEN 4076/dnsmasq\u001b[K\u001b[54;122Htcp 0 0 0.0.0.0:2"]
[343.410773, "o", "2 0.0.0.0:* LISTEN 2087/dropbear\u001b[K\u001b[55;122Htcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1511/uhttpd\u001b[K\u001b[56;122Htcp 0 0 :::8083 :::* LISTEN 3471/emissary\u001b[K\u001b[57;122Htcp 0 0 :::8084 :::* LISTEN 3471/emissary\u001b[K\u001b[58;122Htcp 0 0 ::1:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[59;122Htcp 0 0 fe80::c0ff:fea8:a08:53 :::* LISTEN 4076/dnsmasq\u001b[K\u001b[60;122Htcp 0 0 :::22 :::* LISTEN 2087/dropbear\u001b[K\u001b[61;122Htcp 0 0 :::80 :::* LISTEN 1511/uhttpd\u001b[K\u001b[62;122Hudp 0 0 127.0.0.1:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[63;122Hudp 0 0 192.168.10.230:53 0.0.0.0:* 4076/dnsmasq\u001b[K\u001b[64;122Hudp "]
[343.410797, "o", "0 0 ::1:53 :::* 4076/dnsmasq\u001b[K\u001b[65;122Hudp 0 0 fe80::c0ff:fea8:a08:53 :::* 4076/dnsmasq\u001b[K\u001b[66;122Hroot@ArcadAgent:~# echo \"New applications are installed\"\u001b[K\u001b[67;122HNew applications are installed\u001b[K\u001b[68;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[69;122H\u001b[K\n^Croot@ArcadAgent:~# \u001b[K\u001b[71;122Hroot@ArcadAgent:~# \u001b[K\u001b[72;122Hroot@ArcadAgent:~# hostname\u001b[K\u001b[73;122H-ash: hostname: not found\u001b[K\u001b[74;122Hroot@ArcadAgent:~# logread -f\u001b[K\u001b[75;122H\u001b[K\n\u001b[K\n\u001b[K\n^Croot@NewArcadAgent:~# \u001b[K\u001b[79;122HConnection to 192.168.10.230 closed.\u001b[K\u001b[36m\u001b[80;122Htmux \u001b[39m\u001b[1mpcaseiro@numenor:~/code/cadoles/emissary\u001b(B\u001b[m (pts/27 \u001b[4m-zsh 5.9\u001b(B\u001b[m UltimaThule) \u001b[1m18:02:04 \u001b(B\u001b[m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[32mmaster\u001b[35m|\u001b[33m+1\u001b[39m…3\u001b[35m]\u001b[39m\u001b[K\u001b[7m\u001b[81;122H!431 Z2 ?0 L2\u001b(B\u001b[m \u001b[1m~/code/cadoles/emissary →\u001b(B\u001b[m \u001b[73X\u001b[73C 100%\u001b[K\u001b[?12l\u001b[?25h\u001b[78D\u001b[?2004h"]
[344.264836, "o", "\u001b[?25l\u001b[1;121H│\u001b[2;121H│\u001b[3;121H│\u001b[4;121H│\u001b[5;121H│\u001b[6;121H│\u001b[7;121H│\u001b[8;121H│\u001b[9;121H│\u001b[10;121H│\u001b[11;121H│\u001b[12;121H│\u001b[13;121H│\u001b[14;121H│\u001b[15;121H│\u001b[16;121H│\u001b[17;121H│\u001b[18;121H│\u001b[19;121H│\u001b[20;121H│\u001b[21;121H│\u001b[22;121H│\u001b[23;121H│\u001b[24;121H│\u001b[25;121H│\u001b[26;121H│\u001b[27;121H│\u001b[28;121H│\u001b[29;121H│\u001b[30;121H│\u001b[31;121H│\u001b[32;121H│\u001b[33;121H│\u001b[34;121H│\u001b[35;121H│\u001b[36;121H│\u001b[37;121H│\u001b[38;121H│\u001b[39;121H│\u001b[40;121H│\u001b[41;121H│\u001b[42;121H\u001b[32m│\u001b[43;121H│\u001b[44;121H│\u001b[45;121H│\u001b[46;121H│\u001b[47;121H│\u001b[48;121H│\u001b[49;121H│\u001b[50;121H│\u001b[51;121H│\u001b[52;121H│\u001b[53;121H│\u001b[54;121H│\u001b[55;121H│\u001b[56;121H│\u001b[57;121H│\u001b[58;121H│\u001b[59;121H│\u001b[60;121H│\u001b[61;121H│\u001b[62;121H│\u001b[63;121H│\u001b[64;121H│\u001b[65;121H│\u001b[66;121H│\u001b[67;121H│\u001b[68;121H│\u001b[69;121H│\u001b[70;121H│\u001b[71;121H│\u001b[72;121H│\u001b[73;121H│\u001b[74;121H│\u001b[75;121H│\u001b[76;121H│\u001b[77;121H│\u001b[78;121H│\u001b[79;121H│\u001b[80;121H│\u001b[81;121H│\u001b(B\u001b[m\u001b[37m\u001b[40m\r\n\u001b[32mnumenor\u001b[37m0:zsh* "]
[344.264873, "o", " \"numenor\" 18:02 23-juin-23\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[81;162H"]
[345.862252, "o", "\u001b[1;82r\u001b(B\u001b[m\u001b[?1l\u001b>\u001b[H\u001b[2J\u001b[?2004l\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?7727l\u001b[?1004l"]
[345.86257, "o", "[detached (from session 5)]\r\n"]
[345.863083, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
[345.918704, "o", "\u001b]0;cadoles/emissary\u0007"]
[346.005274, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[m\u001b[1mpcaseiro@numenor\u001b[0m\u001b[1m:~/code/cadoles/emissary\u001b[0m (pts/25 \u001b[4m/bin/zsh 5.9\u001b[24m UltimaThule) \u001b[1m18:02:06 \u001b[0m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[39m\u001b[32mmaster\u001b[39m\u001b[35m|\u001b[39m\u001b[32m\u001b[39m\u001b[0m\u001b[31m\u001b[39m\u001b[0m\u001b[33m+1\u001b[39m\u001b[0m…3\u001b[32m\u001b[39m\u001b[0m\u001b[33m\u001b[39m\u001b[0m\u001b[35m]\u001b[39m\r\n\u001b[7m!430 Z2 ?0 L3\u001b[27m \u001b[1m~/code/cadoles/emissary →\u001b[0m \u001b[K\u001b[194C 100%\u001b[199D"]
[346.005414, "o", "\u001b[?1h\u001b=\u001b[?2004h"]
[348.232652, "o", "\u001b[1m\u001b[31mf\u001b[0m\u001b[39m"]
[348.487255, "o", "\b\u001b[0m\u001b[32mf\u001b[32mg\u001b[39m"]
[348.655951, "o", "\u001b[?1l\u001b>\u001b[?2004l\u001b[K\r\r\n"]
[348.656509, "o", "\u001b]0;fg\u0007"]
[348.656541, "o", "fg: no current job\r\n\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"]
[348.774308, "o", "\u001b]0;cadoles/emissary\u0007"]
[348.878027, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[m\u001b[1mpcaseiro@numenor\u001b[0m\u001b[1m:~/code/cadoles/emissary\u001b[0m (pts/25 \u001b[4m/bin/zsh 5.9\u001b[24m UltimaThule) \u001b[1m18:02:09 \u001b[0m\u001b[35m(\u001b[39mgit\u001b[35m)\u001b[39m \u001b[35m[\u001b[39m\u001b[32mmaster\u001b[39m\u001b[35m|\u001b[39m\u001b[32m\u001b[39m\u001b[0m\u001b[31m\u001b[39m\u001b[0m\u001b[33m+1\u001b[39m\u001b[0m…3\u001b[32m\u001b[39m\u001b[0m\u001b[33m\u001b[39m\u001b[0m\u001b[35m]\u001b[39m\r\n\u001b[7m!431 Z3 \u001b[31m?1\u001b[m\u001b[7m L3\u001b[27m \u001b[1m~/code/cadoles/emissary →\u001b[0m \u001b[K\u001b[192C:( 100%\u001b[199D\u001b[?1h\u001b=\u001b[?2004h"]
[350.165425, "o", "\u001b[?2004l\u001b[K\r\r\n"]

View File

@ -7,6 +7,7 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/command/agent"
"forge.cadoles.com/Cadoles/emissary/internal/command/api"
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/format"
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/spec"
)

View File

@ -1,20 +1,22 @@
# Documentation
- (FR) - [Introduction](./fr/introduction.md)
## Tutorials
- (FR) - [Premiers pas](./tutorials/fr/first-steps.md)
- (FR) - [Déployer un serveur mandataire inverse sur un agent](./tutorials/fr/deploy-reverse-proxy.md)
- (FR) - [Déployer une configuration UCI personnalisée sur un agent](./tutorials/fr/deploy-uci-configuration.md)
## References
### API
### Specifications
[See `misc/rest/server.rest`](../misc/rest/server.rest)
### Spécifications
- [Schéma `app.emissary.cadoles.com`](../internal/spec/app/schema.json)
- [Schéma `app.emissary.cadoles.com`](../internal/agent/controller/app/spec/schema.json)
- [Schéma `proxy.emissary.cadoles.com`](../internal/spec/proxy/schema.json)
- [Schéma `mdns.emissary.cadoles.com`](../internal/agent/controller/mdns/spec/schema.json)
- [Schéma `uci.emissary.cadoles.com`](../internal/spec/uci/schema.json)
- [Schéma `gateway.emissary.cadoles.com`](../internal/spec/gateway/schema.json)
- [Schéma `sysupgrade.openwrt.emissary.cadoles.com`](../internal/agent/controller/openwrt/spec/sysupgrade/schema.json)
### Configuration

30
doc/fr/introduction.md Normal file
View File

@ -0,0 +1,30 @@
# Introduction
"Emissary" est un programme entrant dans la catégorie des outils de gestion et déploiement de configuration.
En utilisant un agent déployé sur chaque système cible, il permet aux administrateurs système de centraliser le contrôle et la supervision de la configuration. Grâce à ses fonctionnalités avancées, il est capable de faire converger la configuration d'une machine vers un modèle précis défini par une ou plusieurs spécifications centralisées sur un serveur de pilotage dédié.
Le principal atout d'"Emissary" réside dans sa capacité à activer des "contrôleurs" spécifiques pour chaque aspect de la configuration système. Ces contrôleurs sont des modules intelligents qui agissent comme des agents spécialisés, veillant à ce que les paramètres de configuration soient correctement appliqués et respectent les spécifications définies.
Grâce à cette approche modulaire, "Emissary" peut gérer diverses facettes de la configuration, telles que les paramètres réseau, les règles de sécurité, les options de performance et bien plus encore. Chaque contrôleur est conçu pour répondre à des besoins spécifiques, offrant ainsi une flexibilité et une granularité optimales dans la gestion de la configuration.
Certains contrôleurs permettent également l'exécution de services spécialisés comme des serveurs mandataires inverses ou des applications web autonomes.
L'utilisation d'un serveur de pilotage centralisé permet à "Emissary" de stocker et de mettre à jour les spécifications de configuration de manière cohérente. Les administrateurs peuvent définir des modèles de configuration précis, les affiner au fil du temps et les appliquer en un seul clic sur l'ensemble du parc de machines gérées. Cela garantit une uniformité et une conformité accrues, tout en facilitant la maintenance et les mises à jour à grande échelle.
À l'heure actuelle, Emissary est conçu pour cibler spécifiquement le système d'exploitation OpenWRT. L'activation des "contrôleurs" spécifiques à cet OS permet de converger la configuration de la machine OpenWRT vers un modèle correspondant aux spécifications centralisées sur le serveur de pilotage. Ces spécifications peuvent inclure des paramètres réseau, des configurations de sécurité, des règles de pare-feu, des options de routage, des services système, et bien d'autres éléments spécifiques à OpenWRT.
## Vue d'ensemble de l'architecture
![](./resources/overview.svg)
## Contrôleurs
Voici la liste des contrôleurs implémentés à ce jour:
- **Contrôleur UCI** - Permet de modifier les données [UCI](https://openwrt.org/docs/guide-user/base-system/uci) (**U**nified **C**onfiguration **S**ystem) d'un système OpenWRT et ainsi configurer les services systèmes, les règles pare-feu, la configuration des NICs, etc sur celui-ci.
- **Contrôleur SysUpgrade** - Permet de mettre à jour un système OpenWRT via l'outil [`sysupgrade`](https://openwrt.org/docs/guide-user/installation/generic.sysupgrade).
- **Contrôleur Proxy** - Permet de déployer des services de type passerelle mandataire inverse ("reverse proxy") sur la machine cible.
- **Contrôleur mDNS** - Permet d'annoncer des services via mDNS sur les différents réseaux de la machine cible.
- **Contrôleur App** - Permet de déployer des applications web "embarquées" (s'exécutant localement et non dépendantes d'une connectivité internet) sur la machine cible. Voir le projet ["Edge App"](https://forge.cadoles.com/arcad/edge).

View File

@ -0,0 +1,59 @@
@startuml
top to bottom direction
skinparam linetype ortho
node PilotNode as "Pilot Node" {
database DataStore as "Data Store"
component EmissaryServer as "Emissary Server" {
component SpecificationRegistry as "Specification Registry" {
component UCISpecification as "UCI Spec"
component MDNSSpecification as "mDNS Spec"
component AppSpecification as "App Spec"
component ProxySpecification as "Proxy Spec"
component SysUpgradeSpecification as "SysUpgrade Spec"
}
component HTTPHandler as "HTTP Handler"
HTTPHandler .down.> SpecificationRegistry: validates agents data with
HTTPHandler .right.> DataStore: saves agent data in
}
}
node OperatorNode as "Operator Node" {
component EmissaryClient as "Emissary Client"
EmissaryClient -left-> HTTPHandler: administrates
}
node OpenWRTNode as "OpenWRT Node" {
component EmissaryAgent as "Emissary Agent" {
component StateManager as "State Manager"
StateManager --up-> HTTPHandler: fetches agent ^*specs from
component UCIController as "UCI Controller"
UCIController .up.> StateManager: reconciles with
component SysUpgradeController as "SysUpgrade Controller"
SysUpgradeController .up.> StateManager: reconciles with
component ProxyController as "Proxy Controller"
ProxyController .up.> StateManager: reconciles with
component MDNSController as "mDNS Controller"
MDNSController .up.> StateManager: reconciles with
component AppController as "App Controller"
AppController .up.> StateManager: reconciles with
}
}

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" height="643px" preserveAspectRatio="none" style="width:1713px;height:643px;background:#FFFFFF;" version="1.1" viewBox="0 0 1713 643" width="1713px" zoomAndPan="magnify"><defs/><g><!--MD5=[d09f24f3d7c03358bd8c02f81fe1cb3f]
cluster PilotNode--><g id="cluster_PilotNode"><polygon fill="none" points="16,16,26,6,685,6,685,511,675,521,16,521,16,16" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="675" x2="685" y1="16" y2="6"/><line style="stroke:#181818;stroke-width:1.0;" x1="16" x2="675" y1="16" y2="16"/><line style="stroke:#181818;stroke-width:1.0;" x1="675" x2="675" y1="16" y2="521"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="73" x="310" y="33.9659">Pilot Node</text></g><!--MD5=[9c6b5fd9fe3a3a3c784efc27685ccdf9]
cluster EmissaryServer--><g id="cluster_EmissaryServer"><rect fill="none" height="440" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:1.0;" width="523" x="138" y="57"/><rect fill="none" height="10" style="stroke:#181818;stroke-width:1.0;" width="15" x="641" y="62"/><rect fill="none" height="2" style="stroke:#181818;stroke-width:1.0;" width="4" x="639" y="64"/><rect fill="none" height="2" style="stroke:#181818;stroke-width:1.0;" width="4" x="639" y="68"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="110" x="344.5" y="84.9659">Emissary Server</text></g><!--MD5=[5f6297313bdca82dad0981382bb4d88a]
cluster SpecificationRegistry--><g id="cluster_SpecificationRegistry"><rect fill="none" height="273" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:1.0;" width="459" x="170" y="192"/><rect fill="none" height="10" style="stroke:#181818;stroke-width:1.0;" width="15" x="609" y="197"/><rect fill="none" height="2" style="stroke:#181818;stroke-width:1.0;" width="4" x="607" y="199"/><rect fill="none" height="2" style="stroke:#181818;stroke-width:1.0;" width="4" x="607" y="203"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="149" x="325" y="219.9659">Specification Registry</text></g><!--MD5=[b562d696a455f482404b155c6a8fbfca]
cluster OperatorNode--><g id="cluster_OperatorNode"><polygon fill="none" points="709,62,719,52,889,52,889,150,879,160,709,160,709,62" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="879" x2="889" y1="62" y2="52"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="879" y1="62" y2="62"/><line style="stroke:#181818;stroke-width:1.0;" x1="879" x2="879" y1="62" y2="160"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="104" x="743" y="79.9659">Operator Node</text></g><!--MD5=[68861f6d3d90d2f41bc4d4a2796fc73e]
cluster OpenWRTNode--><g id="cluster_OpenWRTNode"><polygon fill="none" points="709,313,719,303,1696,303,1696,616,1686,626,709,626,709,313" style="stroke:#181818;stroke-width:1.0;"/><line style="stroke:#181818;stroke-width:1.0;" x1="1686" x2="1696" y1="313" y2="303"/><line style="stroke:#181818;stroke-width:1.0;" x1="709" x2="1686" y1="313" y2="313"/><line style="stroke:#181818;stroke-width:1.0;" x1="1686" x2="1686" y1="313" y2="626"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="109" x="1144" y="330.9659">OpenWRT Node</text></g><!--MD5=[6e6320f5227e3e26302b14a131b17aa5]
cluster EmissaryAgent--><g id="cluster_EmissaryAgent"><rect fill="none" height="248" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:1.0;" width="939" x="733" y="354"/><rect fill="none" height="10" style="stroke:#181818;stroke-width:1.0;" width="15" x="1652" y="359"/><rect fill="none" height="2" style="stroke:#181818;stroke-width:1.0;" width="4" x="1650" y="361"/><rect fill="none" height="2" style="stroke:#181818;stroke-width:1.0;" width="4" x="1650" y="365"/><text fill="#000000" font-family="sans-serif" font-size="14" font-weight="bold" lengthAdjust="spacing" textLength="108" x="1148.5" y="381.9659">Emissary Agent</text></g><!--MD5=[45eee4c5a57edb1e2ac175c76a239d17]
entity DataStore--><g id="elem_DataStore"><path d="M32,105.5 C32,95.5 77,95.5 77,95.5 C77,95.5 122,95.5 122,105.5 L122,133.5679 C122,143.5679 77,143.5679 77,143.5679 C77,143.5679 32,143.5679 32,133.5679 L32,105.5 " fill="#F1F1F1" style="stroke:#181818;stroke-width:0.5;"/><path d="M32,105.5 C32,115.5 77,115.5 77,115.5 C77,115.5 122,115.5 122,105.5 " fill="none" style="stroke:#181818;stroke-width:0.5;"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="70" x="42" y="134.4659">Data Store</text></g><!--MD5=[7d2b259075cd0e421afb7965bd22532b]
entity HTTPHandler--><g id="elem_HTTPHandler"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="132" x="335" y="95"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="447" y="100"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="445" y="102"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="445" y="106"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="92" x="350" y="129.9659">HTTP Handler</text></g><!--MD5=[d74c349cfc963885f78088443cb132a3]
entity UCISpecification--><g id="elem_UCISpecification"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="100" x="213" y="238"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="293" y="243"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="291" y="245"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="291" y="249"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="60" x="228" y="272.9659">UCI Spec</text></g><!--MD5=[631d6ad5bad1f198f42ccf56fafe0582]
entity MDNSSpecification--><g id="elem_MDNSSpecification"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="118" x="348" y="238"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="446" y="243"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="444" y="245"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="444" y="249"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="78" x="363" y="272.9659">mDNS Spec</text></g><!--MD5=[f8753067470155b04e2f3a693924c320]
entity AppSpecification--><g id="elem_AppSpecification"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="103" x="501.5" y="238"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="584.5" y="243"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="582.5" y="245"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="582.5" y="249"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="63" x="516.5" y="272.9659">App Spec</text></g><!--MD5=[fd240f711946cd5d0dcadb1ea2ed786c]
entity ProxySpecification--><g id="elem_ProxySpecification"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="112" x="213" y="392"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="305" y="397"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="303" y="399"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="303" y="403"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="72" x="228" y="426.9659">Proxy Spec</text></g><!--MD5=[74aafaf76d366e174271de99960a7b8d]
entity SysUpgradeSpecification--><g id="elem_SysUpgradeSpecification"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="157" x="360.5" y="392"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="497.5" y="397"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="495.5" y="399"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="495.5" y="403"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="117" x="375.5" y="426.9659">SysUpgrade Spec</text></g><!--MD5=[584b4e495bc4cb9e5d46ff66335fc219]
entity EmissaryClient--><g id="elem_EmissaryClient"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="143" x="725.5" y="95"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="848.5" y="100"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="846.5" y="102"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="846.5" y="106"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="103" x="740.5" y="129.9659">Emissary Client</text></g><!--MD5=[cbe48146c9698f81ea53c2c6f51c8eda]
entity StateManager--><g id="elem_StateManager"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="139" x="1048.5" y="392"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="1167.5" y="397"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1165.5" y="399"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1165.5" y="403"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="99" x="1063.5" y="426.9659">State Manager</text></g><!--MD5=[27f8877b35bcf78d2c9b0e363caea569]
entity UCIController--><g id="elem_UCIController"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="135" x="749.5" y="537"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="864.5" y="542"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="862.5" y="544"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="862.5" y="548"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="95" x="764.5" y="571.9659">UCI Controller</text></g><!--MD5=[f5a45e51cb66ff1d3b5626d0df038fee]
entity SysUpgradeController--><g id="elem_SysUpgradeController"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="192" x="920" y="537"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="1092" y="542"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1090" y="544"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1090" y="548"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="152" x="935" y="571.9659">SysUpgrade Controller</text></g><!--MD5=[ed1f476319cb2bbabd1b988180210f61]
entity ProxyController--><g id="elem_ProxyController"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="147" x="1147.5" y="537"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="1274.5" y="542"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1272.5" y="544"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1272.5" y="548"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="107" x="1162.5" y="571.9659">Proxy Controller</text></g><!--MD5=[dcaaaabc13b59746f8f74cc6285a228b]
entity MDNSController--><g id="elem_MDNSController"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="153" x="1329.5" y="537"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="1462.5" y="542"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1460.5" y="544"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1460.5" y="548"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="113" x="1344.5" y="571.9659">mDNS Controller</text></g><!--MD5=[f7cab0dbd7f354492deaa54be612571f]
entity AppController--><g id="elem_AppController"><rect fill="#F1F1F1" height="49.0679" rx="2.5" ry="2.5" style="stroke:#181818;stroke-width:0.5;" width="138" x="1518" y="537"/><rect fill="#F1F1F1" height="10" style="stroke:#181818;stroke-width:0.5;" width="15" x="1636" y="542"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1634" y="544"/><rect fill="#F1F1F1" height="2" style="stroke:#181818;stroke-width:0.5;" width="4" x="1634" y="548"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacing" textLength="98" x="1533" y="571.9659">App Controller</text></g><!--MD5=[8c3501b26c9c3ea39952224ab3fba557]
link HTTPHandler to SpecificationRegistry--><g id="link_HTTPHandler_SpecificationRegistry"><path d="M334.7,128 C268.96,128 178,128 178,128 C178,128 178,158.5475 178,190.5263 C178,190.7761 178,191.026 178,191.276 " fill="none" id="HTTPHandler-to-SpecificationRegistry" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="178,191.276,182,182.276,178,186.276,174,182.276,178,191.276" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="156" x="151.03" y="142.897">validates agents data with</text></g><!--MD5=[1442fca2dc2f53bf9ae23d9e844c6c8b]
link HTTPHandler to DataStore--><g id="link_HTTPHandler_DataStore"><path d="M334.65,112 C334.65,112 128.41,112 128.41,112 " fill="none" id="HTTPHandler-to-DataStore" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="123.41,112,132.41,116,128.41,112,132.41,108,123.41,112" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="115" x="203.28" y="126.897">saves agent data in</text></g><!--MD5=[04b946759b53ef2d0699bda61eed296c]
reverse link HTTPHandler to EmissaryClient--><g id="link_HTTPHandler_EmissaryClient"><path d="M473.28,112 C473.28,112 725.14,112 725.14,112 " fill="none" id="HTTPHandler-backto-EmissaryClient" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="468.28,112,477.28,116,473.28,112,477.28,108,468.28,112" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="82" x="516.21" y="107.897">administrates</text></g><!--MD5=[0dd7156c6052ea784bc88dfca61e007b]
reverse link HTTPHandler to StateManager--><g id="link_HTTPHandler_StateManager"><path d="M473.28,128 C473.28,128 665,128 665,128 C665,128 665,409 665,409 C665,409 921.14,409 1048.21,409 " fill="none" id="HTTPHandler-backto-StateManager" style="stroke:#181818;stroke-width:1.0;"/><polygon fill="#181818" points="468.28,128,477.28,132,473.28,128,477.28,124,468.28,128" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="163" x="501" y="360.137">fetches agent ^*specs from</text></g><!--MD5=[beea302d68a5d9dc6027ab4e0b987cea]
reverse link StateManager to UCIController--><g id="link_StateManager_UCIController"><path d="M1042.15,425 C1042.15,425 876.5,425 876.5,425 C876.5,425 876.5,497.45 876.5,536.78 " fill="none" id="StateManager-backto-UCIController" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="1047.15,425,1038.15,421,1042.15,425,1038.15,429,1047.15,425" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="814.43" y="420.897">reconciles with</text></g><!--MD5=[8cf138a1950decb1251fc88353171770]
reverse link StateManager to SysUpgradeController--><g id="link_StateManager_SysUpgradeController"><path d="M1080.25,447.43 C1080.25,447.43 1080.25,536.9 1080.25,536.9 " fill="none" id="StateManager-backto-SysUpgradeController" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="1080.25,442.43,1076.25,451.43,1080.25,447.43,1084.25,451.43,1080.25,442.43" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="991.25" y="488.057">reconciles with</text></g><!--MD5=[8dba0e44c0268b5c6a2c1c6565c41b8b]
reverse link StateManager to ProxyController--><g id="link_StateManager_ProxyController"><path d="M1167.5,447.43 C1167.5,447.43 1167.5,536.9 1167.5,536.9 " fill="none" id="StateManager-backto-ProxyController" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="1167.5,442.43,1163.5,451.43,1167.5,447.43,1171.5,451.43,1167.5,442.43" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="1078.5" y="507.057">reconciles with</text></g><!--MD5=[94df0ade1dc92be8853ce902c4f83dad]
reverse link StateManager to MDNSController--><g id="link_StateManager_MDNSController"><path d="M1193.72,425 C1193.72,425 1406,425 1406,425 C1406,425 1406,497.45 1406,536.78 " fill="none" id="StateManager-backto-MDNSController" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="1188.72,425,1197.72,429,1193.72,425,1197.72,421,1188.72,425" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="1266.75" y="420.897">reconciles with</text></g><!--MD5=[e74434bc519cba41fdddc7c857699717]
reverse link StateManager to AppController--><g id="link_StateManager_AppController"><path d="M1193.96,409 C1193.96,409 1587,409 1587,409 C1587,409 1587,493.45 1587,536.66 " fill="none" id="StateManager-backto-AppController" style="stroke:#181818;stroke-width:1.0;stroke-dasharray:7.0,7.0;"/><polygon fill="#181818" points="1188.96,409,1197.96,413,1193.96,409,1197.96,405,1188.96,409" style="stroke:#181818;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacing" textLength="88" x="1365.31" y="404.897">reconciles with</text></g><!--MD5=[6fc50b732d8962c26a79ff20e99a40e3]
@startuml
top to bottom direction
skinparam linetype ortho
node PilotNode as "Pilot Node" {
database DataStore as "Data Store"
component EmissaryServer as "Emissary Server" {
component SpecificationRegistry as "Specification Registry" {
component UCISpecification as "UCI Spec"
component MDNSSpecification as "mDNS Spec"
component AppSpecification as "App Spec"
component ProxySpecification as "Proxy Spec"
component SysUpgradeSpecification as "SysUpgrade Spec"
}
component HTTPHandler as "HTTP Handler"
HTTPHandler .down.> SpecificationRegistry: validates agents data with
HTTPHandler .right.> DataStore: saves agent data in
}
}
node OperatorNode as "Operator Node" {
component EmissaryClient as "Emissary Client"
EmissaryClient -left-> HTTPHandler: administrates
}
node OpenWRTNode as "OpenWRT Node" {
component EmissaryAgent as "Emissary Agent" {
component StateManager as "State Manager"
StateManager - -up-> HTTPHandler: fetches agent ^*specs from
component UCIController as "UCI Controller"
UCIController .up.> StateManager: reconciles with
component SysUpgradeController as "SysUpgrade Controller"
SysUpgradeController .up.> StateManager: reconciles with
component ProxyController as "Proxy Controller"
ProxyController .up.> StateManager: reconciles with
component MDNSController as "mDNS Controller"
MDNSController .up.> StateManager: reconciles with
component AppController as "App Controller"
AppController .up.> StateManager: reconciles with
}
}
@end
PlantUML version 1.2022.7(Mon Aug 22 19:01:30 CEST 2022)
(GPL source distribution)
Java Runtime: OpenJDK Runtime Environment
JVM: OpenJDK 64-Bit Server VM
Default Encoding: UTF-8
Language: fr
Country: FR
--></g></svg>

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,3 @@
# Déployer un serveur mandataire inverse sur un agent
> TODO

View File

@ -0,0 +1,130 @@
# Déployer une configuration UCI personnalisée sur un agent
Via la spécification [`uci.emissary.cadoles.com`](../../../internal/spec/uci/schema.json) il est possible de configurer un agent avec un système OpenWRT. Dans ce tutoriel nous verrons:
- Comment exporter une configuration UCI existante au format attendu par Emissary;
- Comment modifier la spécification d'un agent Emissary pour mettre à jour sa configuration via le serveur de pilotage.
## Étapes
### Identifier l'empreinte de votre agent
1. Sur la machine agent, utiliser la commande intégrée pour récupérer l'empreinte ("thumbprint") identifiant l'agent:
```
emissary agent show-thumbprint
```
**Noter la valeur retournée. Elle sera utilisée dans les étapes suivantes.**
### Exporter la configuration UCI de votre agent au format Emissary
1. Se connecter en SSH sur votre agent Emissary:
```
ssh root@<agent_ip>
```
2. Sur la machine agent, utiliser la commande intégrée pour exporter la configuration UCI de votre agent au format Emissary:
```
uci export | emissary agent openwrt uci transform > my-agent-config.json
```
> **Astuce**
>
> Par défaut, l'outil [LuCi](https://openwrt.org/fr/doc/howto/luci.essentials) est disponible sur votre agent. Vous pouvez y accéder via l'URL `http://<agent_ip>/`.
>
> Vous pouvez utiliser LuCi pour modifier la configuration de l'agent (par exemple, configurer le WiFi, créer des règles réseaux, etc) avant d'exporter la configuration.
>
> De cette manière, il est possible de répliquer celle ci sur plusieurs agents via Emissary !
3. Transférer le fichier `my-agent-config.json` sur la machine hébergeant votre serveur de pilotage Emissary.
### Transformer la configuration en spécification
#### Prérequis
- [`jq`](https://stedolan.github.io/jq/)
- [`sponge`](https://linux.die.net/man/1/sponge) (paquet `moreutils` sur Ubuntu)
#### Étapes
1. Sur la machine hébergeant le serveur de pilotage Emissary, utiliser l'outil `jq` pour créer un objet JSON correspondant au schéma attendu par la spécification [`uci.emissary.cadoles.com`](../../../internal/spec/uci/schema.json):
```bash
# Créer la structure de base de la spécification UCI
cat >> my-uci-spec.json <<EOF
{
"config": null,
"postImportCommands": [
{ "command": "uci", "args": ["commit"] },
{ "command": "reload_config", "args": [] }
]
}
EOF
# Injecter la configuration récupérée de notre agent dans la spécification
cat my-uci-spec.json | jq --slurpfile config my-agent-config.json '.config = $config[0]' | sponge my-uci-spec.json
```
Notre spécification est prête à être assignée à notre agent !
### Assigner la spécification à l'agent
1. Sur la machine hébergeant le serveur de pilotage Emissary, retrouver l'identifiant associé à l'agent:
```bash
# Déclarer une variable contenant l'empreinte de l'agent précédemment trouvée
AGENT_THUMBPRINT="<empreinte agent>"
# Récupérer l'identifiant de l'agent
AGENT_ID=$(emissary api agent query -f json | jq -r --arg thumbprint "$AGENT_THUMBPRINT" '.[] | select(.thumbprint == $thumbprint) | .id')
```
2. Assigner la spécification à l'agent UCI:
```bash
cat my-uci-spec.json | emissary api agent spec update -a ${AGENT_ID} --no-patch --spec-data - --spec-name uci.emissary.cadoles.com
```
**Bravo, vous avez déployé des spécifications UCI sur votre agent !**
### Exemple: modifier le `hostname` de votre agent
En intervenant directement sur notre spécification, il est possible de modifier la configuration et appliquer ces changements à notre agent.
1. Sur la machine hébergeant le serveur de pilotage, faire:
```bash
# On créait une variable avec le nouveau hostname de notre agent
MY_NEW_AGENT_HOSTNAME="MyEmissaryAgent"
# On utilise jq afin de modifier la valeur de configuration dans notre spécification UCI
cat my-uci-spec.json | jq --arg hostname "$MY_NEW_AGENT_HOSTNAME" '( .config.packages[] | select(.name == "system") | .configs[].options[] | select(.name == "hostname").value ) |= $hostname' | sponge my-uci-spec.json
```
> **Astuce**
>
> En utilisant la commande `grep -C 10 hostname my-uci-spec.json`, on peut voir que la valeur de configuration `hostname` a bien été mise à jour dans notre spécification.
2. Mettre à jour la configuration de l'agent:
```bash
cat my-uci-spec.json | emissary api agent spec update -a ${AGENT_ID} --no-patch --spec-data - --spec-name uci.emissary.cadoles.com
```
3. Sur l'agent, après quelques secondes (par défaut, la fréquence de mise à jour est de 1 fois par minute) l'agent devrait avoir son `hostname` mis à jour:
```
uci show system.@system[].hostname
```
Un message de ce type devrait s'afficher:
```
system.cfg01e48a.hostname='MyEmissaryAgent'
```
La modification devrait être également visible dans le prompt du shell de l'agent.

View File

@ -1 +1,158 @@
# Premiers pas
# Premiers pas
## Prérequis
- Pour le serveur, une machine [Ubuntu 22.04](https://ubuntu.com/download/server)
- Pour l'agent, un [RaspberryPi version 3](https://openwrt.org/toh/raspberry_pi_foundation/raspberry_pi)
## Étapes
### Préparer votre RaspberryPi
1. Sur la page des ["versions"](https://forge.cadoles.com/arcad/emissary-firmware/releases) des firmwares du projet Emissary, télécharger la dernière version disponibles correspondant à votre système cible, dans le cas présent `openwrt-<openwrt_version>-emissary-<emissary_firmware_version>-bcm27xx-bcm2710-rpi-3-ext4-factory.img.gz`
2. Brancher votre carte SD dans le lecteur, flasher celle ci avec le firmware:
```bash
# Chemin vers le fichier de firmware précédemment téléchargé
FIRMWARE_FILE="openwrt-<openwrt_version>-emissary-<emissary_firmware_version>-bcm27xx-bcm2710-rpi-3-ext4-factory.img.gz"
SDCARD_DEVICE=/dev/sdX # Chemin vers le "device" correspondant à votre carte SD
# Décompresser le firmware
gzip -d "${FIRMWARE_FILE}"
# Flash la carte SD
sudo dd if="${FIRMWARE_FILE%.gz}" of="${SDCARD_DEVICE}" bs=2M conv=fsync
# Attendre la fin des écritures
sudo sync
```
3. Placer votre carte SD dans votre RaspberryPi, le connecter à votre réseau en Ethernet puis l'allumer.
4. Scanner votre réseau pour trouver l'adresse IP de votre Raspberry Pi. Par exemple, avec l'outil `nmap`:
```bash
sudo nmap -sP 192.168.0.* # À modifier par le préfixe correspondant à votre réseau local
```
Une entrée équivalente à la suivante devrait être affichée:
```bash
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-25 19:29 CEST
Nmap scan report for 192.168.0.24
Host is up (0.0034s latency).
MAC Address: B8:27:EB:E5:7B:55 (Raspberry Pi Foundation)
[...]
```
5. Se connecter en SSH sur votre RaspberryPi et définir un mot de passe pour le compte administrateur:
```bash
ssh root@<ip>
passwd
```
### Installer le serveur Emissary
1. Sur la machine Ubuntu 22.04, télécharger les paquets Emissary sur la page ["Versions"](https://forge.cadoles.com/arcad/emissary/releases) du projet. Dans le cas présent, choisir le paquet Debian `emissary-server_<emissary_version>_linux_<arch>.deb` où `<arch>` correspond à l'architecture CPU de votre machine.
2. Installer le paquet télécharger via `dpkg`:
```
sudo dpkg -i emissary-server_<emissary_version>_linux_<arch>.deb
```
3. Appliquer les migrations sur la base de données:
```shell
sudo emissary --workdir /usr/share/emissary --config /etc/emissary/server.yml server database migrate
```
4. Redémarrer le service:
```shell
sudo systemctl restart emissary-server
```
5. Créer un jeton d'administration:
```shell
sudo emissary --workdir /usr/share/emissary --config /etc/emissary/server.yml server auth create-token --role writer --subject $(whoami) > .emissary-token
```
6. Vérifier l'authentification sur l'API:
```shell
emissary api agent query
```
Une réponse équivalente à la suivante devrait s'afficher:
```shell
+----+-------+------------+--------+-------------+-----------+
| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT |
+----+-------+------------+--------+-------------+-----------+
+----+-------+------------+--------+-------------+-----------+
```
### Appairer l'agent avec votre serveur
1. Sur le RaspberryPi, exécuter la commande suivante:
```shell
uci set emissary.agent.server_url='http://<server_ip>:3000'
uci commit emissary
reload_config
```
2. Via la commande `logread`, vérifier que l'agent arrive à se connecter avec le serveur:
```shell
logread -f
```
Un message de ce type devrait s'afficher:
```
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.611 [INFO] <./internal/agent/controller/persistence/controller.go:58> (*Controller).Reconcile no changes detected, doing nothing {"controller": "persistence-controller"}
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.675 [ERROR] <./internal/agent/controller/spec/controller.go:43>(*Controller).reconcileAgent unexpected agent status {"controller": "spec-controller", "agentID": 1, "status": 0}
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.676 [INFO] <./internal/agent/controller/openwrt/uci_controller.go:32> (*UCIController).Reconcile could not find uci spec, doing nothing {"controller": "uci-controller"}
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.677 [INFO] <./internal/agent/controller/app/controller.go:43> (*Controller).Reconcile could not find app spec {"controller": "app-controller"}
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.678 [INFO] <./internal/agent/controller/proxy/controller.go:35>(*Controller).Reconcile could not find proxy spec {"controller": "proxy-controller"}
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.680 [INFO] <./internal/agent/controller/mdns/controller.go:38>(*Controller).Reconcile could not find mdns spec {"controller": "mdns-controller"}
Thu May 25 18:48:51 2023 daemon.info emissary[2202]: 2023-05-25 18:48:51.680 [INFO] <./internal/agent/controller/openwrt/sysupgrade_controller.go:36> (*SysUpgradeController).Reconcile could not find sysupgrade spec, doing nothing {"controller": "sysupgrade-controller"}
```
3. Sur le serveur, vérifier que l'agent a pu s'enregistrer:
```shell
emissary api agent query
```
Un message de ce type devrait s'afficher:
```
+----+-------+-----------------------------------+--------+-----------------------------------+-----------------------------------+
| ID | LABEL | THUMBPRINT | STATUS | CONTACTEDAT | UPDATEDAT |
+----+-------+-----------------------------------+--------+-----------------------------------+-----------------------------------+
| 1 | | 21CnUATcboKCaheb2uczWCuoxTZtnp... | 0 | 2023-05-25 18:49:51.652680196 ... | "2023-05-25T18:49:51.589225817... |
+----+-------+-----------------------------------+--------+-----------------------------------+-----------------------------------+
```
Noter l'identifiant associé à l'agent.
4. Mettre à jour le statut de l'agent afin qu'il soit en capacité à récupérer ses spécifications:
```
emissary api agent update --agent-id <agent_id> --status 1
```
**Bravo, vous avez appairé votre premier agent et son serveur Emissary !**
## Aller plus loin
- [Déployer une configuration UCI personnalisée sur un agent](./deploy-uci-configuration.md)
- [Déployer un serveur mandataire inverse sur votre agent](./deploy-reverse-proxy.md)

22
go.mod
View File

@ -3,9 +3,11 @@ module forge.cadoles.com/Cadoles/emissary
go 1.19
require (
forge.cadoles.com/arcad/edge v0.0.0-20230328183829-d8ce2901d2ab
forge.cadoles.com/arcad/edge v0.0.0-20230426135323-17808d14c978
github.com/Masterminds/sprig/v3 v3.2.3
github.com/alecthomas/participle/v2 v2.0.0-beta.5
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
github.com/brutella/dnssd v1.2.6
github.com/btcsuite/btcd/btcutil v1.1.3
github.com/davecgh/go-spew v1.1.1
github.com/denisbrodbeck/machineid v1.0.1
@ -23,7 +25,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/qri-io/jsonschema v0.2.1
github.com/urfave/cli/v2 v2.24.4
gitlab.com/wpetit/goweb v0.0.0-20230227162855-a1f09bafccb3
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.21.0
)
@ -31,7 +33,7 @@ require (
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/antonmedv/expr v1.12.7 // indirect
github.com/barnybug/go-cast v0.0.0-20201201064555-a87ccbc26692 // indirect
github.com/dop251/goja_nodejs v0.0.0-20230320130059-dcf93ba651dd // indirect
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
@ -43,14 +45,14 @@ require (
github.com/huandu/xstrings v1.3.3 // indirect
github.com/igm/sockjs-go/v3 v3.0.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/miekg/dns v1.1.51 // indirect
github.com/miekg/dns v1.1.53 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/oklog/ulid/v2 v2.1.0 // indirect
github.com/orcaman/concurrent-map v1.0.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/net v0.9.0 // indirect
google.golang.org/genproto v0.0.0-20220728213248-dd149ef739b9 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
@ -95,12 +97,12 @@ require (
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.6.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/term v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect

43
go.sum
View File

@ -54,12 +54,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
forge.cadoles.com/arcad/edge v0.0.0-20230322170544-cf8a3f8ac077 h1:vsYcNHZevZrs0VeOTasvJoqvPynb8OvH+MMpIUvNT6Q=
forge.cadoles.com/arcad/edge v0.0.0-20230322170544-cf8a3f8ac077/go.mod h1:ONd6vyQ0IM0vHi1i+bmZBRc1Fd0BoXMuDdY/+0sZefw=
forge.cadoles.com/arcad/edge v0.0.0-20230328081549-e09de0b0a4f4 h1:ZBBOOKqCEt6F9/Ikkwc2xwYDr7JpLybvxtoRJwXt7Gw=
forge.cadoles.com/arcad/edge v0.0.0-20230328081549-e09de0b0a4f4/go.mod h1:ONd6vyQ0IM0vHi1i+bmZBRc1Fd0BoXMuDdY/+0sZefw=
forge.cadoles.com/arcad/edge v0.0.0-20230328183829-d8ce2901d2ab h1:xOtzLAYOUcKd/VBx/PzL2riC0zNuQ/cxxf5r3AmEvJE=
forge.cadoles.com/arcad/edge v0.0.0-20230328183829-d8ce2901d2ab/go.mod h1:ONd6vyQ0IM0vHi1i+bmZBRc1Fd0BoXMuDdY/+0sZefw=
forge.cadoles.com/arcad/edge v0.0.0-20230426135323-17808d14c978 h1:fekSRSb8gYcVx8C0B9K6B7+KiFHVixIwvPUkxcnRFp4=
forge.cadoles.com/arcad/edge v0.0.0-20230426135323-17808d14c978/go.mod h1:uv3wBa+UbcEUb7IiJCj1T96Xo3cmx1BwNxbBYRZhln8=
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
@ -153,6 +149,8 @@ github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antonmedv/expr v1.12.7 h1:jfV/l/+dHWAadLwAtESXNxXdfbK9bE4+FNMHYCMntwk=
github.com/antonmedv/expr v1.12.7/go.mod h1:FPC8iWArxls7axbVLsW+kpg1mz29A1b2M6jt+hZfDkU=
github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64/go.mod h1:2qMFB56yOP3KzkB3PbYZ4AlUFg3a88F67TIx5lB/WwY=
github.com/apache/arrow/go/arrow v0.0.0-20211013220434-5962184e7a30/go.mod h1:Q7yQnSMnLvcXlZ8RV+jwz/6y1rQTqbX6C82SndT52Zs=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@ -205,6 +203,8 @@ github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/brutella/dnssd v1.2.6 h1:/0P13JkHLRzeLQkWRPEn4hJCr4T3NfknIFw3aNPIC34=
github.com/brutella/dnssd v1.2.6/go.mod h1:JoW2sJUrmVIef25G6lrLj7HS6Xdwh6q8WUIvMkkBYXs=
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M=
@ -982,8 +982,9 @@ github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88J
github.com/miekg/dns v0.0.0-20161006100029-fc4e1e2843d8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.51 h1:0+Xg7vObnhrz/4ZCZcZh7zPXlmU0aveS2HDBd0m0qSo=
github.com/miekg/dns v1.1.51/go.mod h1:2Z9d3CP1LQWihRZUf29mQ19yDThaI4DAYzte2CaQW5c=
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw=
github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@ -1311,8 +1312,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
gitlab.com/wpetit/goweb v0.0.0-20230227162855-a1f09bafccb3 h1:ddXRTeqEr7LcHQEtkd6gogZOh9tI1Y6Gappr0a1oa2I=
gitlab.com/wpetit/goweb v0.0.0-20230227162855-a1f09bafccb3/go.mod h1:3sus4zjoUv1GB7eDLL60QaPkUnXJCWBpjvbe0jWifeY=
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b h1:nkvOl8TCj/mErADnwFFynjxBtC+hHsrESw6rw56JGmg=
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b/go.mod h1:3sus4zjoUv1GB7eDLL60QaPkUnXJCWBpjvbe0jWifeY=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
@ -1450,9 +1451,9 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20161013035702-8b4af36cd21a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1517,6 +1518,7 @@ golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@ -1528,8 +1530,9 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -1693,8 +1696,9 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -1703,8 +1707,9 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1718,8 +1723,9 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1807,10 +1813,11 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -6,8 +6,8 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata"
"forge.cadoles.com/Cadoles/emissary/internal/auth/agent"
"forge.cadoles.com/Cadoles/emissary/internal/client"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/api"
"gitlab.com/wpetit/goweb/logger"
@ -44,8 +44,6 @@ func (a *Agent) Run(ctx context.Context) error {
if err := a.registerAgent(ctx, client, state); err != nil {
logger.Error(ctx, "could not register agent", logger.E(errors.WithStack(err)))
return
}
logger.Debug(ctx, "state before reconciliation", logger.F("state", state))
@ -81,7 +79,7 @@ func (a *Agent) Reconcile(ctx context.Context, state *State) error {
)
if err := ctrl.Reconcile(ctrlCtx, state); err != nil {
return errors.WithStack(err)
logger.Error(ctx, "could not reconcile", logger.E(errors.WithStack(err)))
}
}

View File

@ -3,7 +3,7 @@ package agent
import (
"context"
"forge.cadoles.com/Cadoles/emissary/internal/client"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
)

View File

@ -3,13 +3,11 @@ package app
import (
"bytes"
"context"
"database/sql"
"net"
"path/filepath"
"sync"
"text/template"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bus"
@ -17,17 +15,33 @@ import (
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
"forge.cadoles.com/arcad/edge/pkg/module"
appModule "forge.cadoles.com/arcad/edge/pkg/module/app"
"forge.cadoles.com/arcad/edge/pkg/module/auth"
"forge.cadoles.com/arcad/edge/pkg/module/blob"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
"forge.cadoles.com/arcad/edge/pkg/module/net"
fetchModule "forge.cadoles.com/arcad/edge/pkg/module/fetch"
netModule "forge.cadoles.com/arcad/edge/pkg/module/net"
shareModule "forge.cadoles.com/arcad/edge/pkg/module/share"
shareSqlite "forge.cadoles.com/arcad/edge/pkg/module/share/sqlite"
"forge.cadoles.com/arcad/edge/pkg/storage"
"forge.cadoles.com/arcad/edge/pkg/storage/sqlite"
"github.com/Masterminds/sprig/v3"
"github.com/dop251/goja"
"github.com/go-chi/chi/v5"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
type Dependencies struct {
Bus bus.Bus
DocumentStore storage.DocumentStore
BlobStore storage.BlobStore
KeySet jwk.Set
AppRepository appModule.Repository
AppID app.ID
ShareRepository shareModule.Repository
}
const defaultSQLiteParams = "?_pragma=foreign_keys(1)&_pragma=busy_timeout=60000"
func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs *spec.Spec) ([]edgeHTTP.HandlerOptionFunc, error) {
dataDir, err := c.ensureAppDataDir(ctx, appKey)
if err != nil {
@ -35,30 +49,51 @@ func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs
}
dbFile := filepath.Join(dataDir, appKey+".sqlite")
db, err := sqlite.Open(dbFile)
db, err := sqlite.Open(dbFile + defaultSQLiteParams)
if err != nil {
return nil, errors.Wrapf(err, "could not open database file '%s'", dbFile)
}
shareDBFile := filepath.Join(dataDir, "shared.sqlite")
shareDB, err := sqlite.Open(shareDBFile + defaultSQLiteParams)
if err != nil {
return nil, errors.Wrapf(err, "could not open database file '%s'", shareDBFile)
}
keySet, err := getAuthKeySet(specs.Config)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve auth key set")
}
bundles := make([]string, 0, len(specs.Apps))
for appKey, app := range specs.Apps {
path := c.getAppBundlePath(appKey, app.Format)
bundles = append(bundles, path)
mounts := make([]func(r chi.Router), 0)
authMount, err := getAuthMount(specs.Config.Auth, keySet)
if err != nil {
return nil, errors.WithStack(err)
}
getAppURL := createGetAppURL(specs)
if authMount != nil {
mounts = append(mounts, authMount)
}
bus := memory.NewBus()
modules := getAppModules(bus, db, specs, keySet, getAppURL, bundles)
mounts = append(mounts, appModule.Mount(c.appRepository))
deps := Dependencies{
Bus: memory.NewBus(),
DocumentStore: sqlite.NewDocumentStoreWithDB(db),
BlobStore: sqlite.NewBlobStoreWithDB(db),
KeySet: keySet,
AppRepository: c.appRepository,
AppID: app.ID(appKey),
ShareRepository: shareSqlite.NewRepositoryWithDB(shareDB),
}
modules := c.getAppModules(deps)
options := []edgeHTTP.HandlerOptionFunc{
edgeHTTP.WithBus(bus),
edgeHTTP.WithBus(deps.Bus),
edgeHTTP.WithServerModules(modules...),
edgeHTTP.WithHTTPMounts(mounts...),
}
return options, nil
@ -106,85 +141,150 @@ func getAuthKeySet(config *spec.Config) (jwk.Set, error) {
return keySet, nil
}
func createGetAppURL(specs *spec.Spec) GetURLFunc {
var (
compileOnce sync.Once
urlTemplate *template.Template
err error
)
func createResolveAppURL(specs *spec.Spec) (ResolveAppURLFunc, error) {
rawIfaceMappings := make(map[string]string, 0)
if specs.Config != nil && specs.Config.AppURLResolving != nil && specs.Config.AppURLResolving.IfaceMappings != nil {
rawIfaceMappings = specs.Config.AppURLResolving.IfaceMappings
}
return func(ctx context.Context, manifest *app.Manifest) (string, error) {
ifaceMappings := make(map[string]*template.Template, len(rawIfaceMappings))
for iface, rawTemplate := range rawIfaceMappings {
tmpl, err := template.New("").Funcs(sprig.TxtFuncMap()).Parse(rawTemplate)
if err != nil {
return nil, errors.Wrapf(err, "could not parse iface '%s' template", iface)
}
ifaceMappings[iface] = tmpl
}
defaultRawTemplate := `http://{{ .DeviceIP }}:{{ .AppPort }}`
if specs.Config != nil && specs.Config.AppURLResolving != nil && specs.Config.AppURLResolving.DefaultURLTemplate != "" {
defaultRawTemplate = specs.Config.AppURLResolving.DefaultURLTemplate
}
defaultTemplate, err := template.New("").Funcs(sprig.TxtFuncMap()).Parse(defaultRawTemplate)
if err != nil {
return nil, errors.WithStack(err)
}
return func(ctx context.Context, manifest *app.Manifest, from string) (string, error) {
var (
urlTemplate *template.Template
deviceIP net.IP
)
fromIP := net.ParseIP(from)
if fromIP != nil {
LOOP:
for ifaceName, ifaceTmpl := range ifaceMappings {
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
logger.Error(
ctx, "could not find interface",
logger.E(errors.WithStack(err)), logger.F("iface", ifaceName),
)
continue
}
addresses, err := iface.Addrs()
if err != nil {
logger.Error(
ctx, "could not list interface addresses",
logger.E(errors.WithStack(err)),
logger.F("iface", iface.Name),
)
continue
}
for _, addr := range addresses {
ifaIP, network, err := net.ParseCIDR(addr.String())
if err != nil {
logger.Error(
ctx, "could not parse interface ip",
logger.E(errors.WithStack(err)),
logger.F("iface", iface.Name),
)
continue
}
if !network.Contains(fromIP) {
continue
}
deviceIP = ifaIP
urlTemplate = ifaceTmpl
break LOOP
}
}
}
if urlTemplate == nil {
urlTemplate = defaultTemplate
}
if deviceIP == nil {
deviceIP = net.ParseIP("127.0.0.1")
}
var appEntry *spec.AppEntry
for appID, entry := range specs.Apps {
if manifest.ID != app.ID(appID) {
continue
}
appEntry = &entry
break
}
if appEntry == nil {
return "", errors.Errorf("could not find app '%s' in specs", manifest.ID)
}
_, port, err := net.SplitHostPort(appEntry.Address)
if err != nil {
return "", errors.WithStack(err)
}
var appURLTemplate string
if specs.Config == nil || specs.Config.AppURLTemplate == "" {
appURLTemplate = `http://{{ last ( splitList "." ( toString .Manifest.ID ) ) }}.local`
} else {
appURLTemplate = specs.Config.AppURLTemplate
}
compileOnce.Do(func() {
urlTemplate, err = template.New("").Funcs(sprig.TxtFuncMap()).Parse(appURLTemplate)
})
var buf bytes.Buffer
data := struct {
Manifest *app.Manifest
Specs *spec.Spec
DeviceIP string
AppPort string
}{
Manifest: manifest,
Specs: specs,
DeviceIP: deviceIP.String(),
AppPort: port,
}
var buf bytes.Buffer
if err := urlTemplate.Execute(&buf, data); err != nil {
return "", errors.WithStack(err)
}
return buf.String(), nil
}
}, nil
}
func getAppModules(bus bus.Bus, db *sql.DB, spec *appSpec.Spec, keySet jwk.Set, getAppURL GetURLFunc, bundles []string) []app.ServerModuleFactory {
ds := sqlite.NewDocumentStoreWithDB(db)
bs := sqlite.NewBlobStoreWithDB(db)
func (c *Controller) getAppModules(deps Dependencies) []app.ServerModuleFactory {
return []app.ServerModuleFactory{
module.ContextModuleFactory(),
module.ConsoleModuleFactory(),
cast.CastModuleFactory(),
module.LifecycleModuleFactory(),
net.ModuleFactory(bus),
module.RPCModuleFactory(bus),
module.StoreModuleFactory(ds),
blob.ModuleFactory(bus, bs),
module.Extends(
auth.ModuleFactory(
auth.WithJWT(func() (jwk.Set, error) {
return keySet, nil
}),
),
func(o *goja.Object) {
if err := o.Set("CLAIM_TENANT", "arcad_tenant"); err != nil {
panic(errors.New("could not set 'CLAIM_TENANT' property"))
}
if err := o.Set("CLAIM_ENTRYPOINT", "arcad_entrypoint"); err != nil {
panic(errors.New("could not set 'CLAIM_ENTRYPOINT' property"))
}
if err := o.Set("CLAIM_ROLE", "arcad_role"); err != nil {
panic(errors.New("could not set 'CLAIM_ROLE' property"))
}
if err := o.Set("CLAIM_PREFERRED_USERNAME", "preferred_username"); err != nil {
panic(errors.New("could not set 'CLAIM_PREFERRED_USERNAME' property"))
}
},
),
appModule.ModuleFactory(NewAppRepository(getAppURL, bundles...)),
netModule.ModuleFactory(deps.Bus),
module.RPCModuleFactory(deps.Bus),
module.StoreModuleFactory(deps.DocumentStore),
blob.ModuleFactory(deps.Bus, deps.BlobStore),
authModuleFactory(deps.KeySet),
appModule.ModuleFactory(deps.AppRepository),
fetchModule.ModuleFactory(deps.Bus),
shareModule.ModuleFactory(deps.AppID, deps.ShareRepository),
}
}

View File

@ -0,0 +1,73 @@
package app
import (
"context"
"testing"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/arcad/edge/pkg/app"
"github.com/pkg/errors"
)
func TestCreateResolveAppURL(t *testing.T) {
specs := &spec.Spec{
Apps: map[string]spec.AppEntry{
"app.arcad.test": {
Address: ":8080",
},
"app.arcad.foo": {
Address: ":8081",
},
"app.arcad.bar": {
Address: ":8082",
},
},
Config: &spec.Config{
AppURLResolving: &spec.AppURLResolving{
IfaceMappings: map[string]string{
"lo": "http://{{ .DeviceIP }}:{{ .AppPort }}",
"does-not-exists": "http://{{ .DeviceIP }}:{{ .AppPort }}",
},
DefaultURLTemplate: `http://{{ last ( splitList "." ( toString .Manifest.ID ) ) }}.arcad.local`,
},
},
}
resolveAppURL, err := createResolveAppURL(specs)
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
manifest := &app.Manifest{
ID: "app.arcad.test",
}
ctx := context.Background()
url, err := resolveAppURL(ctx, manifest, "127.0.0.2")
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
if e, g := "http://127.0.0.1:8080", url; e != g {
t.Errorf("url: expected '%s', got '%s", e, g)
}
url, err = resolveAppURL(ctx, manifest, "")
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
if e, g := "http://test.arcad.local", url; e != g {
t.Errorf("url: expected '%s', got '%s", e, g)
}
url, err = resolveAppURL(ctx, manifest, "192.168.0.100")
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
if e, g := "http://test.arcad.local", url; e != g {
t.Errorf("url: expected '%s', got '%s", e, g)
}
}

View File

@ -2,6 +2,8 @@ package app
import (
"context"
"sort"
"sync"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bundle"
@ -10,15 +12,19 @@ import (
"gitlab.com/wpetit/goweb/logger"
)
type GetURLFunc func(context.Context, *app.Manifest) (string, error)
type ResolveAppURLFunc func(context.Context, *app.Manifest, string) (string, error)
type AppRepository struct {
getURL GetURLFunc
bundles []string
resolveAppURL ResolveAppURLFunc
bundles []string
mutex sync.RWMutex
}
// Get implements app.Repository
func (r *AppRepository) Get(ctx context.Context, id app.ID) (*app.Manifest, error) {
r.mutex.RLock()
defer r.mutex.RUnlock()
manifest, err := r.findManifest(ctx, id)
if err != nil {
return nil, errors.WithStack(err)
@ -28,13 +34,16 @@ func (r *AppRepository) Get(ctx context.Context, id app.ID) (*app.Manifest, erro
}
// GetURL implements app.Repository
func (r *AppRepository) GetURL(ctx context.Context, id app.ID) (string, error) {
func (r *AppRepository) GetURL(ctx context.Context, id app.ID, from string) (string, error) {
r.mutex.RLock()
defer r.mutex.RUnlock()
manifest, err := r.findManifest(ctx, id)
if err != nil {
return "", errors.WithStack(err)
}
url, err := r.getURL(ctx, manifest)
url, err := r.resolveAppURL(ctx, manifest, from)
if err != nil {
return "", errors.WithStack(err)
}
@ -44,6 +53,9 @@ func (r *AppRepository) GetURL(ctx context.Context, id app.ID) (string, error) {
// List implements app.Repository
func (r *AppRepository) List(ctx context.Context) ([]*app.Manifest, error) {
r.mutex.RLock()
defer r.mutex.RUnlock()
manifests := make([]*app.Manifest, 0)
for _, path := range r.bundles {
@ -66,9 +78,19 @@ func (r *AppRepository) List(ctx context.Context) ([]*app.Manifest, error) {
manifests = append(manifests, manifest)
}
sort.Sort(ByID(manifests))
return manifests, nil
}
func (r *AppRepository) Update(resolveAppURL ResolveAppURLFunc, bundles []string) {
r.mutex.Lock()
defer r.mutex.Unlock()
r.resolveAppURL = resolveAppURL
r.bundles = bundles
}
func (r *AppRepository) findManifest(ctx context.Context, id app.ID) (*app.Manifest, error) {
for _, path := range r.bundles {
bundleCtx := logger.With(ctx, logger.F("path", path))
@ -97,8 +119,19 @@ func (r *AppRepository) findManifest(ctx context.Context, id app.ID) (*app.Manif
return nil, errors.WithStack(appModule.ErrNotFound)
}
func NewAppRepository(getURL GetURLFunc, bundles ...string) *AppRepository {
return &AppRepository{getURL, bundles}
func NewAppRepository() *AppRepository {
return &AppRepository{
resolveAppURL: func(ctx context.Context, m *app.Manifest, from string) (string, error) {
return "", errors.New("unavailable")
},
bundles: []string{},
}
}
var _ appModule.Repository = &AppRepository{}
type ByID []*app.Manifest
func (a ByID) Len() int { return len(a) }
func (a ByID) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByID) Less(i, j int) bool { return a[i].ID > a[j].ID }

View File

@ -0,0 +1,93 @@
package app
import (
"time"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/module"
"forge.cadoles.com/arcad/edge/pkg/module/auth"
authModule "forge.cadoles.com/arcad/edge/pkg/module/auth"
authHTTP "forge.cadoles.com/arcad/edge/pkg/module/auth/http"
"github.com/dop251/goja"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/pkg/errors"
)
const (
RoleVisitor string = "visitor"
RoleUser string = "user"
RoleSuperuser string = "superuser"
RoleAdmin string = "admin"
RoleSuperadmin string = "superadmin"
)
func authModuleFactory(keySet jwk.Set) app.ServerModuleFactory {
return module.Extends(
authModule.ModuleFactory(
authModule.WithJWT(func() (jwk.Set, error) {
return keySet, nil
}),
),
func(o *goja.Object) {
if err := o.Set("ROLE_VISITOR", RoleVisitor); err != nil {
panic(errors.New("could not set 'ROLE_VISITOR' property"))
}
if err := o.Set("ROLE_USER", RoleUser); err != nil {
panic(errors.New("could not set 'ROLE_USER' property"))
}
if err := o.Set("ROLE_SUPERUSER", RoleSuperuser); err != nil {
panic(errors.New("could not set 'ROLE_SUPERUSER' property"))
}
if err := o.Set("ROLE_ADMIN", RoleAdmin); err != nil {
panic(errors.New("could not set 'ROLE_ADMIN' property"))
}
if err := o.Set("ROLE_SUPERADMIN", RoleSuperadmin); err != nil {
panic(errors.New("could not set 'ROLE_SUPERADMIN' property"))
}
},
)
}
func getAuthMount(auth *spec.Auth, keySet jwk.Set) (auth.MountFunc, error) {
switch {
case auth.Local != nil:
var rawKey any = auth.Local.Key
if strKey, ok := rawKey.(string); ok {
rawKey = []byte(strKey)
}
key, err := jwk.FromRaw(rawKey)
if err != nil {
return nil, errors.WithStack(err)
}
cookieDuration := defaultCookieDuration
if auth.Local.CookieDuration != "" {
cookieDuration, err = time.ParseDuration(auth.Local.CookieDuration)
if err != nil {
return nil, errors.WithStack(err)
}
}
return authModule.Mount(
authHTTP.NewLocalHandler(
jwa.HS256, key,
authHTTP.WithRoutePrefix("/auth"),
authHTTP.WithAccounts(auth.Local.Accounts...),
authHTTP.WithCookieOptions(getCookieDomain, cookieDuration),
),
authModule.WithJWT(func() (jwk.Set, error) {
return keySet, nil
}),
), nil
default:
return nil, nil
}
}

View File

@ -9,6 +9,7 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bundle"
"github.com/mitchellh/hashstructure/v2"
"github.com/pkg/errors"
@ -16,15 +17,16 @@ import (
)
type serverEntry struct {
SpecHash uint64
Server *Server
AppDefHash uint64
Server *Server
}
type Controller struct {
client *http.Client
downloadDir string
dataDir string
servers map[string]*serverEntry
client *http.Client
downloadDir string
dataDir string
servers map[string]*serverEntry
appRepository *AppRepository
}
// Name implements node.Controller.
@ -95,7 +97,16 @@ func (c *Controller) updateApps(ctx context.Context, specs *spec.Spec) {
}
}
// (Re)start apps
if err := c.updateAppRepository(ctx, specs); err != nil {
logger.Error(
ctx, "could not update app repository",
logger.E(errors.WithStack(err)),
)
return
}
// (Re)start apps if necessary
for appKey := range specs.Apps {
appCtx := logger.With(ctx, logger.F("appKey", appKey))
@ -106,10 +117,35 @@ func (c *Controller) updateApps(ctx context.Context, specs *spec.Spec) {
}
}
func (c *Controller) updateAppRepository(ctx context.Context, specs *spec.Spec) error {
bundles := make([]string, 0, len(specs.Apps))
for appKey, app := range specs.Apps {
path := c.getAppBundlePath(appKey, app.Format)
bundles = append(bundles, path)
}
resolveAppURL, err := createResolveAppURL(specs)
if err != nil {
return errors.WithStack(err)
}
c.appRepository.Update(resolveAppURL, bundles)
return nil
}
func (c *Controller) updateApp(ctx context.Context, specs *spec.Spec, appKey string) (err error) {
appEntry := specs.Apps[appKey]
newAppSpecHash, err := hashstructure.Hash(appEntry, hashstructure.FormatV2, nil)
appDef := struct {
App spec.AppEntry
Config *spec.Config
}{
App: appEntry,
Config: specs.Config,
}
newAppDefHash, err := hashstructure.Hash(appDef, hashstructure.FormatV2, nil)
if err != nil {
return errors.WithStack(err)
}
@ -136,36 +172,50 @@ func (c *Controller) updateApp(ctx context.Context, specs *spec.Spec, appKey str
server = nil
}
if server == nil {
newServerEntry := func() (*serverEntry, error) {
options, err := c.getHandlerOptions(ctx, appKey, specs)
if err != nil {
return errors.Wrap(err, "could not create handler options")
}
var auth *spec.Auth
if specs.Config != nil {
auth = specs.Config.Auth
return nil, errors.Wrap(err, "could not create handler options")
}
server = &serverEntry{
Server: NewServer(bundle, auth, options...),
SpecHash: 0,
Server: NewServer(bundle, specs.Config, options...),
AppDefHash: 0,
}
c.servers[appKey] = server
return server, nil
}
specChanged := newAppSpecHash != server.SpecHash
if server == nil {
serverEntry, err := newServerEntry()
if err != nil {
return errors.WithStack(err)
}
if server.Server.Running() && !specChanged {
c.servers[appKey] = serverEntry
}
defChanged := newAppDefHash != server.AppDefHash
if server.Server.Running() && !defChanged {
return nil
}
if specChanged && server.SpecHash != 0 {
if defChanged && server.AppDefHash != 0 {
logger.Info(
ctx, "restarting app",
logger.F("address", appEntry.Address),
)
if err := server.Server.Stop(); err != nil {
return errors.WithStack(err)
}
serverEntry, err := newServerEntry()
if err != nil {
return errors.WithStack(err)
}
c.servers[appKey] = serverEntry
} else {
logger.Info(
ctx, "starting app",
@ -179,7 +229,7 @@ func (c *Controller) updateApp(ctx context.Context, specs *spec.Spec, appKey str
return errors.Wrap(err, "could not start app")
}
server.SpecHash = newAppSpecHash
server.AppDefHash = newAppDefHash
return nil
}
@ -227,7 +277,21 @@ func (c *Controller) ensureAppBundle(ctx context.Context, appID string, spec spe
return nil, "", errors.WithStack(err)
}
return bdle, "", nil
manifest, err := app.LoadManifest(bdle)
if err != nil {
return nil, "", errors.WithStack(err)
}
valid, err := validateManifest(manifest)
if err != nil {
return nil, "", errors.WithStack(err)
}
if !valid {
return nil, "", errors.New("bundle's manifest is invalid")
}
return bdle, spec.SHA256Sum, nil
}
func (c *Controller) downloadFile(url string, sha256sum string, dest string) error {
@ -294,10 +358,11 @@ func NewController(funcs ...OptionFunc) *Controller {
}
return &Controller{
client: opts.Client,
downloadDir: opts.DownloadDir,
dataDir: opts.DataDir,
servers: make(map[string]*serverEntry),
client: opts.Client,
downloadDir: opts.DownloadDir,
dataDir: opts.DataDir,
servers: make(map[string]*serverEntry),
appRepository: NewAppRepository(),
}
}

View File

@ -0,0 +1,19 @@
package app
import (
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/app/metadata"
"github.com/pkg/errors"
)
func validateManifest(manifest *app.Manifest) (bool, error) {
valid, err := manifest.Validate(
metadata.WithMinimumRoleValidator(RoleVisitor, RoleUser, RoleSuperuser, RoleAdmin, RoleSuperadmin),
metadata.WithNamedPathsValidator(metadata.NamedPathAdmin, metadata.NamedPathIcon),
)
if err != nil {
return false, errors.WithStack(err)
}
return valid, nil
}

View File

@ -2,21 +2,21 @@ package app
import (
"context"
"net"
"net/http"
"strings"
"sync"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/Cadoles/emissary/internal/proxy/wildcard"
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
authHTTP "forge.cadoles.com/arcad/edge/pkg/module/auth/http"
"gitlab.com/wpetit/goweb/logger"
"forge.cadoles.com/arcad/edge/pkg/bundle"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/pkg/errors"
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/passwd"
@ -29,27 +29,37 @@ type Server struct {
handlerOptions []edgeHTTP.HandlerOptionFunc
server *http.Server
serverMutex sync.RWMutex
auth *appSpec.Auth
config *appSpec.Config
}
func (s *Server) Start(ctx context.Context, addr string) (err error) {
if s.server != nil {
if s.Running() {
if err := s.Stop(); err != nil {
return errors.WithStack(err)
}
}
s.serverMutex.Lock()
defer s.serverMutex.Unlock()
router := chi.NewRouter()
router.Use(middleware.RealIP)
router.Use(middleware.Logger)
router.Use(middleware.Compress(5))
handler := edgeHTTP.NewHandler(s.handlerOptions...)
if err := handler.Load(s.bundle); err != nil {
return errors.Wrap(err, "could not load app bundle")
}
if err := s.configureAuth(router, s.auth); err != nil {
return errors.WithStack(err)
if s.config != nil {
if s.config.UnexpectedHostRedirect != nil {
router.Use(unexpectedHostRedirect(
s.config.UnexpectedHostRedirect.HostTarget,
s.config.UnexpectedHostRedirect.AcceptedHostPatterns...,
))
}
}
router.Handle("/*", handler)
@ -83,9 +93,7 @@ func (s *Server) Start(ctx context.Context, addr string) (err error) {
}
}()
s.serverMutex.Lock()
s.server = server
s.serverMutex.Unlock()
return nil
}
@ -98,63 +106,84 @@ func (s *Server) Running() bool {
}
func (s *Server) Stop() error {
if !s.Running() {
return nil
}
s.serverMutex.Lock()
defer s.serverMutex.Unlock()
if s.server == nil {
return nil
}
defer func() {
s.serverMutex.Lock()
s.server = nil
s.serverMutex.Unlock()
}()
if err := s.server.Close(); err != nil {
panic(errors.WithStack(err))
s.server = nil
return errors.WithStack(err)
}
s.server = nil
return nil
}
func (s *Server) configureAuth(router chi.Router, auth *spec.Auth) error {
if auth == nil {
return nil
}
switch {
case auth.Local != nil:
var rawKey any = s.auth.Local.Key
if strKey, ok := rawKey.(string); ok {
rawKey = []byte(strKey)
}
key, err := jwk.FromRaw(rawKey)
if err != nil {
return errors.WithStack(err)
}
cookieDuration := defaultCookieDuration
if s.auth.Local.CookieDuration != "" {
cookieDuration, err = time.ParseDuration(s.auth.Local.CookieDuration)
if err != nil {
return errors.WithStack(err)
}
}
router.Handle("/auth/*", authHTTP.NewLocalHandler(
jwa.HS256, key,
authHTTP.WithRoutePrefix("/auth"),
authHTTP.WithAccounts(s.auth.Local.Accounts...),
authHTTP.WithCookieOptions(s.auth.Local.CookieDomain, cookieDuration),
))
}
return nil
}
func NewServer(bundle bundle.Bundle, auth *appSpec.Auth, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
func NewServer(bundle bundle.Bundle, config *spec.Config, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
return &Server{
bundle: bundle,
auth: auth,
config: config,
handlerOptions: handlerOptions,
}
}
func getCookieDomain(r *http.Request) (string, error) {
host, _, err := net.SplitHostPort(r.Host)
if err != nil {
host = r.Host
}
// If host is an IP address
if ip := net.ParseIP(host); ip != nil {
return "", nil
}
// If host is an domain, return top level domain
domainParts := strings.Split(host, ".")
if len(domainParts) >= 2 {
topLevelDomain := strings.Join(domainParts[len(domainParts)-2:], ".")
return topLevelDomain, nil
}
// By default, return host
return host, nil
}
func unexpectedHostRedirect(hostTarget string, acceptedHostPatterns ...string) func(http.Handler) http.Handler {
return func(h http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
host, port, err := net.SplitHostPort(r.Host)
if err != nil {
host = r.Host
}
matched := wildcard.MatchAny(host, acceptedHostPatterns...)
if !matched {
url := r.URL
url.Host = hostTarget
if port != "" {
url.Host += ":" + port
}
http.Redirect(w, r, url.String(), http.StatusTemporaryRedirect)
return
}
h.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
}

View File

@ -38,57 +38,94 @@
}
}
},
"auth": {
"config": {
"type": "object",
"properties": {
"local": {
"appUrlResolving": {
"type": "object",
"properties": {
"key": {
"type": ["object", "string"]
},
"accounts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"algo": {
"type": "string"
},
"claims": {
"type": "object"
}
},
"required": [
"username",
"password",
"algo"
]
"ifaceMappings": {
"type": "object",
"patternProperties": {
".*": {
"type": "string"
}
}
},
"cookieDomain": {
"type": "string"
},
"cookieDuration": {
"defaultUrlTemplate": {
"type": "string"
}
},
"required": [
"key"
]
"required": ["defaultUrlTemplate"],
"additionalProperties": false
},
"unexpectedHostRedirect": {
"type": "object",
"properties": {
"acceptedHostPatterns": {
"type": "array",
"items": {
"type": "string"
}
},
"hostTarget": {
"type": "string"
}
},
"required": ["acceptedHostPatterns", "hostTarget"],
"additionalProperties": false
},
"auth": {
"type": "object",
"properties": {
"local": {
"type": "object",
"properties": {
"key": {
"type": ["object", "string"]
},
"accounts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"algo": {
"type": "string"
},
"claims": {
"type": "object"
}
},
"required": [
"username",
"password",
"algo"
]
}
},
"cookieDomain": {
"type": "string"
},
"cookieDuration": {
"type": "string"
}
},
"required": [
"key"
],
"additionalProperties": false
}
},
"additionalProperties": false
}
}
},
"config": {
"appUrlTemplate": {
"type": "string"
}
},
"additionalProperties": false
}
},
"required": [

View File

@ -32,8 +32,19 @@ type LocalAuth struct {
}
type Config struct {
Auth *Auth `json:"auth"`
AppURLTemplate string `json:"appUrlTemplate"`
Auth *Auth `json:"auth"`
UnexpectedHostRedirect *UnexpectedHostRedirect `json:"unexpectedHostRedirect"`
AppURLResolving *AppURLResolving `json:"appUrlResolving"`
}
type UnexpectedHostRedirect struct {
AcceptedHostPatterns []string `json:"acceptedHostPatterns"`
HostTarget string `json:"hostTarget"`
}
type AppURLResolving struct {
IfaceMappings map[string]string `json:"ifaceMappings"`
DefaultURLTemplate string `json:"defaultUrlTemplate"`
}
func (s *Spec) SpecName() spec.Name {

View File

@ -9,32 +9,44 @@
"format": "zip"
}
},
"auth": {
"local": {
"key": {
"d": "YOre0WZefGfUGFvDg42oL5Oad5Zsb1N_hqPyLVM5ajpTZzcHpB3wT6In9tFO_VshB6lxVtPA9ckPkpMTFY7ygt1Yomc1HkoOKRtmIaqdr4VgNQifU-4yiLiJkSbdYSeMV-KkkN8mGR1keJpJeS34W1X0W6CkU2nw7F5VueBCJfWJA0funRfuWdI68MTUgT9kRZFp-SfvptvRL6jVYHV_5hqxzHCvgEdBSF6QKwx4M6P6QBMt7ft6uMLmFx9abKFw2V51hX3PkxiSepVB3w5CYg4HtS3AHX6bILL4m0R2pdTIkap7i3tkH_xAOuKWt8D6JhadI8X1rEAwXmCS5KrRgQ",
"dp": "U0HfvBC6hk-SCpuotGIv3vbHCVt1aF3SHK0y32EYCOe8e_9G6YCEILfcvEJ5fiOCc2kvx6TasHQu4qj1uWRKenZlK1sJ6KDybGCkZL1D3jYnbeLZYBuWBL__YbZiST3ewbxzj_EDMWiZ8sUltahza_1weSgg8auSzTHS2LJBHIE",
"dq": "hVom4ScDxgqhCsQNVpZlN7M3v0tgWjl_gTOHjOyzKCHQJeC0QmJJaMKkQZPWJ8jjLqy7VwVpqC2nZU7QDuX1Cq5eJDQcXi9XtaAfIBico9WcYDre6mDyhL588YHpekyRke8HnZ810iesr0G3gU1h0QvZVVuW-pXTJOXhZTt6nFc",
"e": "AQAB",
"kty": "RSA",
"n": "vPnpkE3-HfNgJSru_K40LstkjiG2Bq_Tt-m0d_yUBBSbirFxF3qH4EXi7WrtZdeDahg2iV2BvpbVVj9GlmGo9OLol6jc7AP2yvZrkbABiiJhCbuPdkYbNpx6B7Itl8RT_bUSYAMZhmux5lpsn4weQ01fzjICi1rA-bIJpOfotdOjP4_lol-LxGZOGJQv9kndP8bgmssJb3Y_2s4gPtkmXySLrhpr5So-_6dVksyuBD9aLcnsMLDbywusjEMCdhqzQbvOjryomnmEXwyz_Ewb5HFK2PfgFtoHkdjqDz-mrEs3tw5g4TdYhCftzJxgbyNAEq4aEiOQrAncYyrXlotP_w",
"p": "8TNMF0WUe7CEeNVUTsuEcBAAXRguNtpvVifIjlwzFRGOYVGIpKuHsqQPKlZL07I9gPr9LifQnyQus3oEmTOrVs6LB9sfbukbg43ZRKoGVM40JYF5Xjs7R3mEZhgU0WaYOVe3iLtBGMfXNWFwlbfQP-zEb-dPCBX1jWT3LdgNBcE",
"q": "yJJLNc9w6O4y2icME8k99FugV9E7ObwUxF3v5JN3y1cmAT0h2njyE3iAGqaDZwcY1_jGCisjwoqX6i5E8xqhxX3Gcy3J7SmUAf8fhY8wU3zv9DK7skg2IdvanDb8Y1OM6GchbYZAOVPEg2IvVio8zI-Ih3DDwDk8Df0ufzoHRb8",
"qi": "zOE-4R3cjPesm3MX-4PdwmsaF9QZLUVRUvvHJ08pKs6kAXP18hzjctAoOjhQDxlTYqNYNePfKzKwost3OJoPgRIc9w9qwUCK1gNOS4Z_xozCIaXgMddNFhkoAfZ4JaKjNCiinzjGfqG99Lf-yzmmREuuhRv7SdS3ST4VQjiJQew"
},
"accounts": [
{
"username": "foo",
"algo": "plain",
"password": "bar",
"claims": {
"arcad_role": "user",
"arcad_tenant": "dev.cli",
"preferred_username": "Foo",
"sub": "foo"
"config": {
"auth": {
"local": {
"key": {
"d": "YOre0WZefGfUGFvDg42oL5Oad5Zsb1N_hqPyLVM5ajpTZzcHpB3wT6In9tFO_VshB6lxVtPA9ckPkpMTFY7ygt1Yomc1HkoOKRtmIaqdr4VgNQifU-4yiLiJkSbdYSeMV-KkkN8mGR1keJpJeS34W1X0W6CkU2nw7F5VueBCJfWJA0funRfuWdI68MTUgT9kRZFp-SfvptvRL6jVYHV_5hqxzHCvgEdBSF6QKwx4M6P6QBMt7ft6uMLmFx9abKFw2V51hX3PkxiSepVB3w5CYg4HtS3AHX6bILL4m0R2pdTIkap7i3tkH_xAOuKWt8D6JhadI8X1rEAwXmCS5KrRgQ",
"dp": "U0HfvBC6hk-SCpuotGIv3vbHCVt1aF3SHK0y32EYCOe8e_9G6YCEILfcvEJ5fiOCc2kvx6TasHQu4qj1uWRKenZlK1sJ6KDybGCkZL1D3jYnbeLZYBuWBL__YbZiST3ewbxzj_EDMWiZ8sUltahza_1weSgg8auSzTHS2LJBHIE",
"dq": "hVom4ScDxgqhCsQNVpZlN7M3v0tgWjl_gTOHjOyzKCHQJeC0QmJJaMKkQZPWJ8jjLqy7VwVpqC2nZU7QDuX1Cq5eJDQcXi9XtaAfIBico9WcYDre6mDyhL588YHpekyRke8HnZ810iesr0G3gU1h0QvZVVuW-pXTJOXhZTt6nFc",
"e": "AQAB",
"kty": "RSA",
"n": "vPnpkE3-HfNgJSru_K40LstkjiG2Bq_Tt-m0d_yUBBSbirFxF3qH4EXi7WrtZdeDahg2iV2BvpbVVj9GlmGo9OLol6jc7AP2yvZrkbABiiJhCbuPdkYbNpx6B7Itl8RT_bUSYAMZhmux5lpsn4weQ01fzjICi1rA-bIJpOfotdOjP4_lol-LxGZOGJQv9kndP8bgmssJb3Y_2s4gPtkmXySLrhpr5So-_6dVksyuBD9aLcnsMLDbywusjEMCdhqzQbvOjryomnmEXwyz_Ewb5HFK2PfgFtoHkdjqDz-mrEs3tw5g4TdYhCftzJxgbyNAEq4aEiOQrAncYyrXlotP_w",
"p": "8TNMF0WUe7CEeNVUTsuEcBAAXRguNtpvVifIjlwzFRGOYVGIpKuHsqQPKlZL07I9gPr9LifQnyQus3oEmTOrVs6LB9sfbukbg43ZRKoGVM40JYF5Xjs7R3mEZhgU0WaYOVe3iLtBGMfXNWFwlbfQP-zEb-dPCBX1jWT3LdgNBcE",
"q": "yJJLNc9w6O4y2icME8k99FugV9E7ObwUxF3v5JN3y1cmAT0h2njyE3iAGqaDZwcY1_jGCisjwoqX6i5E8xqhxX3Gcy3J7SmUAf8fhY8wU3zv9DK7skg2IdvanDb8Y1OM6GchbYZAOVPEg2IvVio8zI-Ih3DDwDk8Df0ufzoHRb8",
"qi": "zOE-4R3cjPesm3MX-4PdwmsaF9QZLUVRUvvHJ08pKs6kAXP18hzjctAoOjhQDxlTYqNYNePfKzKwost3OJoPgRIc9w9qwUCK1gNOS4Z_xozCIaXgMddNFhkoAfZ4JaKjNCiinzjGfqG99Lf-yzmmREuuhRv7SdS3ST4VQjiJQew"
},
"accounts": [
{
"username": "foo",
"algo": "plain",
"password": "bar",
"claims": {
"arcad_role": "user",
"arcad_tenant": "dev.cli",
"preferred_username": "Foo",
"sub": "foo"
}
}
}
]
]
}
},
"unexpectedHostRedirect": {
"acceptedHostPatterns": ["arcad.local", "*.arcad.local", "arcad-*.local", "*.*.*.*"],
"hostTarget": "arcad.local"
},
"appUrlResolving": {
"ifaceMappings": {
"eth0": "http://{{ .DeviceIP }}:{{ .AppHost }}"
},
"defaultUrlTemplate": "http://{{ last ( splitList \".\" ( toString .Manifest.ID ) ) }}.arcad.local"
}
}
},

View File

@ -0,0 +1,181 @@
package mdns
import (
"context"
"net"
"sync"
"forge.cadoles.com/Cadoles/emissary/internal/agent"
mdns "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/mdns/spec"
"github.com/brutella/dnssd"
"github.com/mitchellh/hashstructure/v2"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
const (
DefaultDomain = "local"
)
type Controller struct {
serviceDefHash uint64
cancel context.CancelFunc
responder dnssd.Responder
mutex sync.RWMutex
}
// Name implements node.Controller.
func (c *Controller) Name() string {
return "mdns-controller"
}
// Reconcile implements node.Controller.
func (c *Controller) Reconcile(ctx context.Context, state *agent.State) error {
mdnsSpec := mdns.NewSpec()
if err := state.GetSpec(mdns.Name, mdnsSpec); err != nil {
if errors.Is(err, agent.ErrSpecNotFound) {
logger.Info(ctx, "could not find mdns spec")
c.stopResponder(ctx)
return nil
}
return errors.WithStack(err)
}
logger.Info(ctx, "retrieved spec", logger.F("spec", mdnsSpec.SpecName()), logger.F("revision", mdnsSpec.SpecRevision()))
if err := c.updateResponder(ctx, mdnsSpec); err != nil {
return errors.Wrap(err, "could not update responder")
}
return nil
}
func (c *Controller) stopResponder(ctx context.Context) {
c.mutex.Lock()
defer c.mutex.Unlock()
if c.responder == nil {
return
}
c.cancel()
c.responder = nil
c.cancel = nil
}
func (c *Controller) updateResponder(ctx context.Context, spec *mdns.Spec) error {
serviceDef := struct {
Services map[string]mdns.Service
}{
Services: spec.Services,
}
newServerDefHash, err := hashstructure.Hash(serviceDef, hashstructure.FormatV2, nil)
if err != nil {
return errors.WithStack(err)
}
c.mutex.RLock()
if newServerDefHash == c.serviceDefHash && c.responder != nil {
c.mutex.RUnlock()
return nil
}
c.mutex.RUnlock()
c.stopResponder(ctx)
defaultIfaces, err := c.getDefaultIfaces()
if err != nil {
return errors.WithStack(err)
}
services := make([]dnssd.Service, 0, len(spec.Services))
for name, service := range spec.Services {
domain := service.Domain
if domain == "" {
domain = DefaultDomain
}
ifaces := service.Ifaces
if len(ifaces) == 0 {
ifaces = defaultIfaces
}
config := dnssd.Config{
Name: name,
Type: service.Type,
Domain: domain,
Host: service.Host,
Ifaces: ifaces,
Port: service.Port,
}
service, err := dnssd.NewService(config)
if err != nil {
logger.Error(ctx, "could not create mdns service", logger.E(errors.WithStack(err)))
continue
}
services = append(services, service)
}
responder, err := dnssd.NewResponder()
if err != nil {
return errors.WithStack(err)
}
for _, service := range services {
if _, err := responder.Add(service); err != nil {
logger.Error(ctx, "could not add mdns service", logger.E(errors.WithStack(err)))
continue
}
}
ctx, cancel := context.WithCancel(context.Background())
c.responder = responder
c.cancel = cancel
c.serviceDefHash = newServerDefHash
go func() {
defer c.stopResponder(ctx)
if err := responder.Respond(ctx); err != nil && !errors.Is(err, context.Canceled) {
logger.Error(ctx, "could not respond to mdns queries", logger.E(errors.WithStack(err)))
}
}()
return nil
}
func (c *Controller) getDefaultIfaces() ([]string, error) {
ifaces, err := net.Interfaces()
if err != nil {
return nil, errors.WithStack(err)
}
ifaceNames := make([]string, len(ifaces))
for idx, ifa := range ifaces {
ifaceNames[idx] = ifa.Name
}
return ifaceNames, nil
}
func NewController() *Controller {
return &Controller{
cancel: nil,
responder: nil,
serviceDefHash: 0,
}
}
var _ agent.Controller = &Controller{}

View File

@ -0,0 +1,17 @@
package spec
import (
_ "embed"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
)
//go:embed schema.json
var schema []byte
func init() {
if err := spec.Register(Name, schema); err != nil {
panic(errors.WithStack(err))
}
}

View File

@ -0,0 +1,47 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://mdns.edge.emissary.cadoles.com/spec.json",
"title": "MDNSSpec",
"description": "Emissary 'MDNS' specification",
"type": "object",
"properties": {
"services": {
"type": "object",
"patternProperties": {
".*": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"domain": {
"type": "string"
},
"host": {
"type": "string"
},
"ifaces": {
"type": "array",
"items": {
"type": "string"
}
},
"port": {
"type": "number"
}
},
"required": [
"type",
"host",
"port"
],
"additionalProperties": false
}
}
}
},
"required": [
"services"
],
"additionalProperties": false
}

View File

@ -0,0 +1,42 @@
package spec
import (
"forge.cadoles.com/Cadoles/emissary/internal/spec"
)
const Name spec.Name = "mdns.emissary.cadoles.com"
type Spec struct {
Revision int `json:"revision"`
Services map[string]Service `json:"services"`
}
type Service struct {
Type string `json:"type"`
Domain string `json:"domain"`
Host string `json:"host"`
Ifaces []string `json:"ifaces"`
Port int `json:"port"`
}
func (s *Spec) SpecName() spec.Name {
return Name
}
func (s *Spec) SpecRevision() int {
return s.Revision
}
func (s *Spec) SpecData() map[string]any {
return map[string]any{
"services": s.Services,
}
}
func NewSpec() *Spec {
return &Spec{
Revision: -1,
}
}
var _ spec.Spec = &Spec{}

View File

@ -0,0 +1,15 @@
{
"name": "mdns.emissary.cadoles.com",
"data": {
"services": {
"My Website": {
"type": "_http._tcp",
"domain": "local",
"host": "mywebsite",
"ifaces": ["lo", "eth0"],
"port": 80
}
}
},
"revision": 0
}

View File

@ -0,0 +1,65 @@
package spec
import (
"context"
"encoding/json"
"io/ioutil"
"testing"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
)
type validatorTestCase struct {
Name string
Source string
ShouldFail bool
}
var validatorTestCases = []validatorTestCase{
{
Name: "SpecOK",
Source: "testdata/spec-ok.json",
ShouldFail: false,
},
}
func TestValidator(t *testing.T) {
t.Parallel()
validator := spec.NewValidator()
if err := validator.Register(Name, schema); err != nil {
t.Fatalf("+%v", errors.WithStack(err))
}
for _, tc := range validatorTestCases {
func(tc validatorTestCase) {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()
rawSpec, err := ioutil.ReadFile(tc.Source)
if err != nil {
t.Fatalf("+%v", errors.WithStack(err))
}
var spec spec.RawSpec
if err := json.Unmarshal(rawSpec, &spec); err != nil {
t.Fatalf("+%v", errors.WithStack(err))
}
ctx := context.Background()
err = validator.Validate(ctx, &spec)
if !tc.ShouldFail && err != nil {
t.Errorf("+%v", errors.WithStack(err))
}
if tc.ShouldFail && err == nil {
t.Error("validation should have failed")
}
})
}(tc)
}
}

View File

@ -4,8 +4,8 @@ import (
"context"
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/client"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)

View File

@ -4,7 +4,7 @@ import (
"time"
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata"
"forge.cadoles.com/Cadoles/emissary/internal/client"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
)
type Options struct {

View File

@ -4,23 +4,24 @@ import (
"context"
"net/http"
"strings"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/auth"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"github.com/lestrrat-go/jwx/v2/jws"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
const DefaultAcceptableSkew = 5 * time.Minute
type Authenticator struct {
repo datastore.AgentRepository
repo datastore.AgentRepository
acceptableSkew time.Duration
}
// Authenticate implements auth.Authenticator.
func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth.User, error) {
ctx = logger.With(r.Context(), logger.F("remoteAddr", r.RemoteAddr))
authorization := r.Header.Get("Authorization")
if authorization == "" {
return nil, errors.WithStack(auth.ErrUnauthenticated)
@ -71,11 +72,19 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
[]byte(rawToken),
jwt.WithKeySet(agent.KeySet.Set, jws.WithRequireKid(false)),
jwt.WithValidate(true),
jwt.WithAcceptableSkew(a.acceptableSkew),
)
if err != nil {
return nil, errors.WithStack(err)
}
contactedAt := time.Now()
agent, err = a.repo.Update(ctx, agent.ID, datastore.WithAgentUpdateContactedAt(contactedAt))
if err != nil {
return nil, errors.WithStack(err)
}
user := &User{
agent: agent,
}
@ -83,9 +92,10 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
return user, nil
}
func NewAuthenticator(repo datastore.AgentRepository) *Authenticator {
func NewAuthenticator(repo datastore.AgentRepository, acceptableSkew time.Duration) *Authenticator {
return &Authenticator{
repo: repo,
repo: repo,
acceptableSkew: acceptableSkew,
}
}

View File

@ -18,7 +18,7 @@ func GenerateToken(key jwk.Key, thumbprint string) (string, error) {
return "", errors.WithStack(err)
}
now := time.Now()
now := time.Now().UTC()
if err := token.Set(jwt.NotBeforeKey, now); err != nil {
return "", errors.WithStack(err)

View File

@ -4,22 +4,29 @@ import (
"context"
"net/http"
"strings"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/auth"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
const DefaultAcceptableSkew = 5 * time.Minute
type (
GetKeySet func(context.Context) (jwk.Set, error)
GetTokenRole func(context.Context, jwt.Token) (string, error)
)
type Authenticator struct {
keys jwk.Set
issuer string
getKeySet GetKeySet
getTokenRole GetTokenRole
acceptableSkew time.Duration
}
// Authenticate implements auth.Authenticator.
func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth.User, error) {
ctx = logger.With(r.Context(), logger.F("remoteAddr", r.RemoteAddr))
authorization := r.Header.Get("Authorization")
if authorization == "" {
return nil, errors.WithStack(auth.ErrUnauthenticated)
@ -30,37 +37,38 @@ func (a *Authenticator) Authenticate(ctx context.Context, r *http.Request) (auth
return nil, errors.WithStack(auth.ErrUnauthenticated)
}
token, err := parseToken(ctx, a.keys, a.issuer, rawToken)
keys, err := a.getKeySet(ctx)
if err != nil {
return nil, errors.WithStack(err)
}
rawRole, exists := token.Get(keyRole)
if !exists {
return nil, errors.New("could not find 'thumbprint' claim")
token, err := parseToken(ctx, keys, rawToken, a.acceptableSkew)
if err != nil {
return nil, errors.WithStack(err)
}
role, ok := rawRole.(string)
if !ok {
return nil, errors.Errorf("unexpected '%s' claim value: '%v'", keyRole, rawRole)
rawRole, err := a.getTokenRole(ctx, token)
if err != nil {
return nil, errors.WithStack(err)
}
if !isValidRole(role) {
return nil, errors.Errorf("invalid role '%s'", role)
if !isValidRole(rawRole) {
return nil, errors.Errorf("invalid role '%s'", rawRole)
}
user := &User{
subject: token.Subject(),
role: Role(role),
role: Role(rawRole),
}
return user, nil
}
func NewAuthenticator(keys jwk.Set, issuer string) *Authenticator {
func NewAuthenticator(getKeySet GetKeySet, getTokenRole GetTokenRole, acceptableSkew time.Duration) *Authenticator {
return &Authenticator{
keys: keys,
issuer: issuer,
getTokenRole: getTokenRole,
getKeySet: getKeySet,
acceptableSkew: acceptableSkew,
}
}

View File

@ -11,14 +11,13 @@ import (
"github.com/pkg/errors"
)
const keyRole = "role"
func parseToken(ctx context.Context, keys jwk.Set, issuer string, rawToken string) (jwt.Token, error) {
func parseToken(ctx context.Context, keys jwk.Set, rawToken string, acceptableSkew time.Duration) (jwt.Token, error) {
token, err := jwt.Parse(
[]byte(rawToken),
jwt.WithKeySet(keys, jws.WithRequireKid(false)),
jwt.WithIssuer(issuer),
jwt.WithValidate(true),
jwt.WithAcceptableSkew(acceptableSkew),
jwt.WithContext(ctx),
)
if err != nil {
return nil, errors.WithStack(err)
@ -27,22 +26,20 @@ func parseToken(ctx context.Context, keys jwk.Set, issuer string, rawToken strin
return token, nil
}
func GenerateToken(ctx context.Context, key jwk.Key, issuer, subject string, role Role) (string, error) {
const DefaultRoleKey string = "role"
func GenerateToken(ctx context.Context, key jwk.Key, subject string, role Role) (string, error) {
token := jwt.New()
if err := token.Set(jwt.SubjectKey, subject); err != nil {
return "", errors.WithStack(err)
}
if err := token.Set(jwt.IssuerKey, issuer); err != nil {
if err := token.Set(DefaultRoleKey, role); err != nil {
return "", errors.WithStack(err)
}
if err := token.Set(keyRole, role); err != nil {
return "", errors.WithStack(err)
}
now := time.Now()
now := time.Now().UTC()
if err := token.Set(jwt.NotBeforeKey, now); err != nil {
return "", errors.WithStack(err)

View File

@ -5,6 +5,7 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/mdns"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/openwrt"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/persistence"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/proxy"
@ -49,10 +50,6 @@ func RunCommand() *cli.Command {
controllers = append(controllers, spec.NewController())
}
if ctrlConf.Proxy.Enabled {
controllers = append(controllers, proxy.NewController())
}
if ctrlConf.UCI.Enabled {
controllers = append(controllers, openwrt.NewUCIController(
string(ctrlConf.UCI.BinPath),
@ -66,6 +63,14 @@ func RunCommand() *cli.Command {
))
}
if ctrlConf.Proxy.Enabled {
controllers = append(controllers, proxy.NewController())
}
if ctrlConf.MDNS.Enabled {
controllers = append(controllers, mdns.NewController())
}
if ctrlConf.SysUpgrade.Enabled {
sysUpgradeArgs := make([]string, 0)
if len(ctrlConf.SysUpgrade.SysUpgradeCommand) > 1 {

View File

@ -3,10 +3,10 @@ package agent
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)

View File

@ -3,12 +3,12 @@ package agent
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/agent/flag"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)

View File

@ -3,11 +3,11 @@ package agent
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/agent/flag"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)

View File

@ -3,11 +3,11 @@ package agent
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)

View File

@ -3,12 +3,12 @@ package spec
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/agent/flag"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)

View File

@ -3,11 +3,11 @@ package spec
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/agent/flag"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)

View File

@ -4,12 +4,12 @@ import (
"encoding/json"
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/agent/flag"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
jsonpatch "github.com/evanphx/json-patch/v5"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"

View File

@ -3,11 +3,11 @@ package agent
import (
"os"
"forge.cadoles.com/Cadoles/emissary/internal/client"
agentFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/agent/flag"
"forge.cadoles.com/Cadoles/emissary/internal/command/api/apierr"
clientFlag "forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
"forge.cadoles.com/Cadoles/emissary/internal/format"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)
@ -22,6 +22,11 @@ func UpdateCommand() *cli.Command {
Usage: "Set `STATUS` to selected agent",
Value: -1,
},
&cli.StringFlag{
Name: "label",
Usage: "Set `LABEL` to selected agent",
Value: "",
},
),
Action: func(ctx *cli.Context) error {
baseFlags := clientFlag.GetBaseFlags(ctx)
@ -43,6 +48,11 @@ func UpdateCommand() *cli.Command {
options = append(options, client.WithAgentStatus(status))
}
label := ctx.String("label")
if label != "" {
options = append(options, client.WithAgentLabel(label))
}
client := client.New(baseFlags.ServerURL, client.WithToken(token))
agent, err := client.UpdateAgent(ctx.Context, agentID, options...)

View File

@ -7,9 +7,10 @@ func agentHints(outputMode format.OutputMode) format.Hints {
OutputMode: outputMode,
Props: []format.Prop{
format.NewProp("ID", "ID"),
format.NewProp("Label", "Label"),
format.NewProp("Thumbprint", "Thumbprint"),
format.NewProp("Status", "Status"),
format.NewProp("CreatedAt", "CreatedAt"),
format.NewProp("ContactedAt", "ContactedAt"),
format.NewProp("UpdatedAt", "UpdatedAt"),
},
}

View File

@ -36,12 +36,17 @@ func CreateTokenCommand() *cli.Command {
subject := ctx.String("subject")
role := ctx.String("role")
key, err := jwk.LoadOrGenerate(string(conf.Server.PrivateKeyPath), jwk.DefaultKeySize)
localAuth := conf.Server.Auth.Local
if localAuth == nil {
return errors.New("local auth is disabled")
}
key, err := jwk.LoadOrGenerate(string(localAuth.PrivateKeyPath), jwk.DefaultKeySize)
if err != nil {
return errors.WithStack(err)
}
token, err := thirdparty.GenerateToken(ctx.Context, key, string(conf.Server.Issuer), subject, thirdparty.Role(role))
token, err := thirdparty.GenerateToken(ctx.Context, key, subject, thirdparty.Role(role))
if err != nil {
return errors.WithStack(err)
}

View File

@ -23,6 +23,7 @@ type ControllersConfig struct {
UCI UCIControllerConfig `yaml:"uci"`
App AppControllerConfig `yaml:"app"`
SysUpgrade SysUpgradeControllerConfig `yaml:"sysupgrade"`
MDNS MDNSControllerConfig `yaml:"mdns"`
}
type PersistenceControllerConfig struct {
@ -55,6 +56,10 @@ type SysUpgradeControllerConfig struct {
FirmwareVersionCommand InterpolatedStringSlice `yaml:"firmwareVersionCommand"`
}
type MDNSControllerConfig struct {
Enabled InterpolatedBool `yaml:"enabled"`
}
func NewDefaultAgentConfig() AgentConfig {
return AgentConfig{
ServerURL: "http://127.0.0.1:3000",
@ -86,6 +91,9 @@ func NewDefaultAgentConfig() AgentConfig {
SysUpgradeCommand: InterpolatedStringSlice{"sysupgrade", "--force", "-u", "-v", openwrt.FirmwareFileTemplate},
FirmwareVersionCommand: InterpolatedStringSlice{"sh", "-c", `source /etc/openwrt_release && echo "$DISTRIB_ID-$DISTRIB_RELEASE-$DISTRIB_REVISION"`},
},
MDNS: MDNSControllerConfig{
Enabled: true,
},
},
Collectors: []ShellCollectorConfig{
{

View File

@ -15,6 +15,6 @@ type DatabaseConfig struct {
func NewDefaultDatabaseConfig() DatabaseConfig {
return DatabaseConfig{
Driver: "sqlite",
DSN: "sqlite://emissary.sqlite",
DSN: "sqlite://emissary.sqlite?_pragma=foreign_keys(1)&_pragma=busy_timeout=60000",
}
}

View File

@ -4,6 +4,7 @@ import (
"os"
"regexp"
"strconv"
"time"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
@ -123,3 +124,37 @@ func (iss *InterpolatedStringSlice) UnmarshalYAML(value *yaml.Node) error {
return nil
}
type InterpolatedDuration time.Duration
func (id *InterpolatedDuration) UnmarshalYAML(value *yaml.Node) error {
var str string
if err := value.Decode(&str); err != nil {
return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line)
}
if match := reVar.FindStringSubmatch(str); len(match) > 0 {
str = os.Getenv(match[1])
}
duration, err := time.ParseDuration(str)
if err != nil {
return errors.Wrapf(err, "could not parse duration '%v', line '%d'", str, value.Line)
}
*id = InterpolatedDuration(duration)
return nil
}
func (id *InterpolatedDuration) MarshalYAML() (interface{}, error) {
duration := time.Duration(*id)
return duration.String(), nil
}
func NewInterpolatedDuration(d time.Duration) *InterpolatedDuration {
id := InterpolatedDuration(d)
return &id
}

View File

@ -1,19 +1,50 @@
package config
import (
"fmt"
"forge.cadoles.com/Cadoles/emissary/internal/auth/thirdparty"
)
type ServerConfig struct {
PrivateKeyPath InterpolatedString `yaml:"privateKeyPath"`
Issuer InterpolatedString `yaml:"issuer"`
HTTP HTTPConfig `yaml:"http"`
Database DatabaseConfig `yaml:"database"`
CORS CORSConfig `yaml:"cors"`
HTTP HTTPConfig `yaml:"http"`
Database DatabaseConfig `yaml:"database"`
CORS CORSConfig `yaml:"cors"`
Auth AuthConfig `yaml:"auth"`
}
func NewDefaultServerConfig() ServerConfig {
return ServerConfig{
PrivateKeyPath: "server-key.json",
Issuer: "http://127.0.0.1:3000",
HTTP: NewDefaultHTTPConfig(),
Database: NewDefaultDatabaseConfig(),
CORS: NewDefaultCORSConfig(),
HTTP: NewDefaultHTTPConfig(),
Database: NewDefaultDatabaseConfig(),
CORS: NewDefaultCORSConfig(),
Auth: NewDefaultAuthConfig(),
}
}
type AuthConfig struct {
Local *LocalAuthConfig `yaml:"local"`
Remote *RemoteAuthConfig `yaml:"remote"`
RoleExtractionRules []string `yaml:"roleExtractionRules"`
}
func NewDefaultAuthConfig() AuthConfig {
return AuthConfig{
Local: &LocalAuthConfig{
PrivateKeyPath: "server-key.json",
},
Remote: nil,
RoleExtractionRules: []string{
fmt.Sprintf("jwt.%s != nil ? str(jwt.%s) : ''", thirdparty.DefaultRoleKey, thirdparty.DefaultRoleKey),
},
}
}
type LocalAuthConfig struct {
PrivateKeyPath InterpolatedString `yaml:"privateKeyPath"`
}
type RemoteAuthConfig struct {
JsonWebKeySetURL InterpolatedString `yaml:"jwksUrl"`
RefreshInterval *InterpolatedDuration `yaml:"refreshInterval"`
}

View File

@ -20,13 +20,15 @@ const (
)
type Agent struct {
ID AgentID `json:"id"`
Thumbprint string `json:"thumbprint"`
KeySet *SerializableKeySet `json:"keyset,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
Status AgentStatus `json:"status"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ID AgentID `json:"id"`
Label string `json:"label"`
Thumbprint string `json:"thumbprint"`
KeySet *SerializableKeySet `json:"keyset,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
Status AgentStatus `json:"status"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
ContactedAt *time.Time `json:"contactedAt,omitempty"`
}
type SerializableKeySet struct {

View File

@ -2,6 +2,7 @@ package datastore
import (
"context"
"time"
"github.com/lestrrat-go/jwx/v2/jwk"
)
@ -68,10 +69,12 @@ func WithAgentQueryThumbprints(thumbprints ...string) AgentQueryOptionFunc {
type AgentUpdateOptionFunc func(*AgentUpdateOptions)
type AgentUpdateOptions struct {
Status *AgentStatus
Metadata *map[string]any
KeySet *jwk.Set
Thumbprint *string
Label *string
Status *AgentStatus
ContactedAt *time.Time
Metadata *map[string]any
KeySet *jwk.Set
Thumbprint *string
}
func WithAgentUpdateStatus(status AgentStatus) AgentUpdateOptionFunc {
@ -97,3 +100,15 @@ func WithAgentUpdateThumbprint(thumbprint string) AgentUpdateOptionFunc {
opts.Thumbprint = &thumbprint
}
}
func WithAgentUpdateLabel(label string) AgentUpdateOptionFunc {
return func(opts *AgentUpdateOptions) {
opts.Label = &label
}
}
func WithAgentUpdateContactedAt(contactedAt time.Time) AgentUpdateOptionFunc {
return func(opts *AgentUpdateOptions) {
opts.ContactedAt = &contactedAt
}
}

View File

@ -20,9 +20,24 @@ type AgentRepository struct {
// DeleteSpec implements datastore.AgentRepository.
func (r *AgentRepository) DeleteSpec(ctx context.Context, agentID datastore.AgentID, name string) error {
query := `DELETE FROM specs WHERE agent_id = $1 AND name = $2`
err := r.withTx(ctx, func(tx *sql.Tx) error {
exists, err := r.agentExists(ctx, tx, agentID)
if err != nil {
return errors.WithStack(err)
}
_, err := r.db.ExecContext(ctx, query, agentID, name)
if !exists {
return errors.WithStack(datastore.ErrNotFound)
}
query := `DELETE FROM specs WHERE agent_id = $1 AND name = $2`
if _, err = tx.ExecContext(ctx, query, agentID, name); err != nil {
return errors.WithStack(err)
}
return nil
})
if err != nil {
return errors.WithStack(err)
}
@ -34,31 +49,55 @@ func (r *AgentRepository) DeleteSpec(ctx context.Context, agentID datastore.Agen
func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentID) ([]*datastore.Spec, error) {
specs := make([]*datastore.Spec, 0)
query := `
err := r.withTx(ctx, func(tx *sql.Tx) error {
exists, err := r.agentExists(ctx, tx, agentID)
if err != nil {
return errors.WithStack(err)
}
if !exists {
return errors.WithStack(datastore.ErrNotFound)
}
query := `
SELECT id, name, revision, data, created_at, updated_at
FROM specs
WHERE agent_id = $1
`
`
rows, err := r.db.QueryContext(ctx, query, agentID)
if err != nil {
return nil, errors.WithStack(err)
}
defer rows.Close()
for rows.Next() {
spec := &datastore.Spec{}
data := JSONMap{}
if err := rows.Scan(&spec.ID, &spec.Name, &spec.Revision, &data, &spec.CreatedAt, &spec.UpdatedAt); err != nil {
return nil, errors.WithStack(err)
rows, err := tx.QueryContext(ctx, query, agentID)
if err != nil {
return errors.WithStack(err)
}
spec.Data = data
defer func() {
if err := rows.Close(); err != nil {
logger.Error(ctx, "could not close rows", logger.E(errors.WithStack(err)))
}
}()
specs = append(specs, spec)
for rows.Next() {
spec := &datastore.Spec{}
data := JSONMap{}
if err := rows.Scan(&spec.ID, &spec.Name, &spec.Revision, &data, &spec.CreatedAt, &spec.UpdatedAt); err != nil {
return errors.WithStack(err)
}
spec.Data = data
specs = append(specs, spec)
}
if err := rows.Err(); err != nil {
return errors.WithStack(err)
}
return nil
})
if err != nil {
return nil, errors.WithStack(err)
}
return specs, nil
@ -69,6 +108,15 @@ func (r *AgentRepository) UpdateSpec(ctx context.Context, agentID datastore.Agen
spec := &datastore.Spec{}
err := r.withTx(ctx, func(tx *sql.Tx) error {
exists, err := r.agentExists(ctx, tx, agentID)
if err != nil {
return errors.WithStack(err)
}
if !exists {
return errors.WithStack(datastore.ErrNotFound)
}
now := time.Now().UTC()
query := `
@ -88,7 +136,7 @@ func (r *AgentRepository) UpdateSpec(ctx context.Context, agentID datastore.Agen
data := JSONMap{}
err := row.Scan(&spec.ID, &spec.Name, &spec.Revision, &data, &spec.CreatedAt, &spec.UpdatedAt)
err = row.Scan(&spec.ID, &spec.Name, &spec.Revision, &data, &spec.CreatedAt, &spec.UpdatedAt)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return errors.WithStack(datastore.ErrUnexpectedRevision)
@ -119,7 +167,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
count := 0
err := r.withTx(ctx, func(tx *sql.Tx) error {
query := `SELECT id, thumbprint, status, created_at, updated_at FROM agents`
query := `SELECT id, label, thumbprint, status, contacted_at, created_at, updated_at FROM agents`
limit := 10
if options.Limit != nil {
@ -176,22 +224,34 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
return errors.WithStack(err)
}
defer rows.Close()
defer func() {
if err := rows.Close(); err != nil {
logger.Error(ctx, "could not close rows", logger.E(errors.WithStack(err)))
}
}()
for rows.Next() {
agent := &datastore.Agent{}
metadata := JSONMap{}
contactedAt := sql.NullTime{}
if err := rows.Scan(&agent.ID, &agent.Thumbprint, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
if err := rows.Scan(&agent.ID, &agent.Label, &agent.Thumbprint, &agent.Status, &contactedAt, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
return errors.WithStack(err)
}
agent.Metadata = metadata
if contactedAt.Valid {
agent.ContactedAt = &contactedAt.Time
}
agents = append(agents, agent)
}
if err := rows.Err(); err != nil {
return errors.WithStack(err)
}
row := tx.QueryRowContext(ctx, `SELECT count(id) FROM agents `+filters, args...)
if err := row.Scan(&count); err != nil {
return errors.WithStack(err)
@ -299,7 +359,7 @@ func (r *AgentRepository) Get(ctx context.Context, id datastore.AgentID) (*datas
err := r.withTx(ctx, func(tx *sql.Tx) error {
query := `
SELECT "id", "thumbprint", "keyset", "metadata", "status", "created_at", "updated_at"
SELECT "id", "label", "thumbprint", "keyset", "metadata", "status", "contacted_at", "created_at", "updated_at"
FROM agents
WHERE id = $1
`
@ -307,9 +367,10 @@ func (r *AgentRepository) Get(ctx context.Context, id datastore.AgentID) (*datas
row := r.db.QueryRowContext(ctx, query, id)
metadata := JSONMap{}
contactedAt := sql.NullTime{}
var rawKeySet []byte
if err := row.Scan(&agent.ID, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
if err := row.Scan(&agent.ID, &agent.Label, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &contactedAt, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return datastore.ErrNotFound
}
@ -318,6 +379,9 @@ func (r *AgentRepository) Get(ctx context.Context, id datastore.AgentID) (*datas
}
agent.Metadata = metadata
if contactedAt.Valid {
agent.ContactedAt = &contactedAt.Time
}
keySet := jwk.NewSet()
if err := json.Unmarshal(rawKeySet, &keySet); err != nil {
@ -346,15 +410,11 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
err := r.withTx(ctx, func(tx *sql.Tx) error {
query := `
UPDATE agents SET updated_at = $2
UPDATE agents SET id = $1
`
now := time.Now().UTC()
args := []any{
id, now,
}
index := 3
args := []any{id}
index := 2
if options.Status != nil {
query += fmt.Sprintf(`, status = $%d`, index)
@ -379,23 +439,51 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
index++
}
if options.Label != nil {
query += fmt.Sprintf(`, label = $%d`, index)
args = append(args, *options.Label)
index++
}
if options.ContactedAt != nil {
query += fmt.Sprintf(`, contacted_at = $%d`, index)
utc := options.ContactedAt.UTC()
args = append(args, utc)
index++
}
if options.Metadata != nil {
query += fmt.Sprintf(`, metadata = $%d`, index)
args = append(args, JSONMap(*options.Metadata))
index++
}
updated := options.Metadata != nil ||
options.Status != nil ||
options.Label != nil ||
options.KeySet != nil ||
options.Thumbprint != nil
if updated {
now := time.Now().UTC()
query += fmt.Sprintf(`, updated_at = $%d`, index)
args = append(args, now)
index++
}
query += `
WHERE id = $1
RETURNING "id", "thumbprint", "keyset", "metadata", "status", "created_at", "updated_at"
RETURNING "id", "label", "thumbprint", "keyset", "metadata", "status", "contacted_at", "created_at", "updated_at"
`
logger.Debug(ctx, "executing query", logger.F("query", query), logger.F("args", args))
row := tx.QueryRowContext(ctx, query, args...)
metadata := JSONMap{}
contactedAt := sql.NullTime{}
var rawKeySet []byte
if err := row.Scan(&agent.ID, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
if err := row.Scan(&agent.ID, &agent.Label, &agent.Thumbprint, &rawKeySet, &metadata, &agent.Status, &contactedAt, &agent.CreatedAt, &agent.UpdatedAt); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return datastore.ErrNotFound
}
@ -404,6 +492,9 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
}
agent.Metadata = metadata
if contactedAt.Valid {
agent.ContactedAt = &contactedAt.Time
}
keySet := jwk.NewSet()
if err := json.Unmarshal(rawKeySet, &keySet); err != nil {
@ -421,8 +512,28 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
return agent, nil
}
func (r *AgentRepository) agentExists(ctx context.Context, tx *sql.Tx, agentID datastore.AgentID) (bool, error) {
row := tx.QueryRowContext(ctx, `SELECT count(id) FROM agents WHERE id = $1`, agentID)
var count int
if err := row.Scan(&count); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return false, errors.WithStack(datastore.ErrNotFound)
}
return false, errors.WithStack(err)
}
if count == 0 {
return false, errors.WithStack(datastore.ErrNotFound)
}
return true, nil
}
func (r *AgentRepository) withTx(ctx context.Context, fn func(*sql.Tx) error) error {
tx, err := r.db.Begin()
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return errors.WithStack(err)
}

View File

@ -0,0 +1,46 @@
package sqlite
import (
"database/sql"
"fmt"
"os"
"testing"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/datastore/testsuite"
"forge.cadoles.com/Cadoles/emissary/internal/migrate"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
_ "modernc.org/sqlite"
)
func TestSQLiteAgentRepository(t *testing.T) {
logger.SetLevel(logger.LevelDebug)
file := "testdata/agent_repository_test.sqlite"
if err := os.Remove(file); err != nil && !errors.Is(err, os.ErrNotExist) {
t.Fatalf("%+v", errors.WithStack(err))
}
dsn := fmt.Sprintf("%s?_pragma=foreign_keys(1)&_pragma=busy_timeout=%d", file, (60 * time.Second).Milliseconds())
migr, err := migrate.New("../../../migrations", "sqlite", "sqlite://"+dsn)
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
if err := migr.Up(); err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
db, err := sql.Open("sqlite", dsn)
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}
repo := NewAgentRepository(db)
testsuite.TestAgentRepository(t, repo)
}

View File

@ -0,0 +1 @@
*.sqlite*

View File

@ -0,0 +1,14 @@
package testsuite
import (
"testing"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
)
func TestAgentRepository(t *testing.T, repo datastore.AgentRepository) {
t.Run("Cases", func(t *testing.T) {
t.Parallel()
runAgentRepositoryTests(t, repo)
})
}

View File

@ -0,0 +1,129 @@
package testsuite
import (
"context"
"testing"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/mdns/spec"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"github.com/pkg/errors"
)
type agentRepositoryTestCase struct {
Name string
Skip bool
Run func(ctx context.Context, repo datastore.AgentRepository) error
}
var agentRepositoryTestCases = []agentRepositoryTestCase{
{
Name: "Create a new agent",
Run: func(ctx context.Context, repo datastore.AgentRepository) error {
thumbprint := "foo"
keySet := jwk.NewSet()
var metadata map[string]any
agent, err := repo.Create(ctx, thumbprint, keySet, metadata)
if err != nil {
return errors.WithStack(err)
}
if agent.CreatedAt.IsZero() {
return errors.Errorf("agent.CreatedAt should not be zero time")
}
if agent.UpdatedAt.IsZero() {
return errors.Errorf("agent.UpdatedAt should not be zero time")
}
if e, g := datastore.AgentStatusPending, agent.Status; e != g {
return errors.Errorf("agent.Status: expected '%v', got '%v'", e, g)
}
return nil
},
},
{
Name: "Try to update spec for an unexistant agent",
Run: func(ctx context.Context, repo datastore.AgentRepository) error {
var unexistantAgentID datastore.AgentID = 9999
var specData map[string]any
agent, err := repo.UpdateSpec(ctx, unexistantAgentID, string(spec.Name), 0, specData)
if err == nil {
return errors.New("error should not be nil")
}
if !errors.Is(err, datastore.ErrNotFound) {
return errors.Errorf("error should be datastore.ErrNotFound, got '%+v'", err)
}
if agent != nil {
return errors.New("agent should be nil")
}
return nil
},
},
{
Name: "Try to delete spec of an unexistant agent",
Run: func(ctx context.Context, repo datastore.AgentRepository) error {
var unexistantAgentID datastore.AgentID = 9999
err := repo.DeleteSpec(ctx, unexistantAgentID, string(spec.Name))
if err == nil {
return errors.New("error should not be nil")
}
if !errors.Is(err, datastore.ErrNotFound) {
return errors.Errorf("error should be datastore.ErrNotFound, got '%+v'", err)
}
return nil
},
},
{
Name: "Try to get specs of an unexistant agent",
Run: func(ctx context.Context, repo datastore.AgentRepository) error {
var unexistantAgentID datastore.AgentID = 9999
specs, err := repo.GetSpecs(ctx, unexistantAgentID)
if err == nil {
return errors.New("error should not be nil")
}
if !errors.Is(err, datastore.ErrNotFound) {
return errors.Errorf("error should be datastore.ErrNotFound, got '%+v'", err)
}
if specs != nil {
return errors.Errorf("specs should be nil, got '%+v'", err)
}
return nil
},
},
}
func runAgentRepositoryTests(t *testing.T, repo datastore.AgentRepository) {
for _, tc := range agentRepositoryTestCases {
func(tc agentRepositoryTestCase) {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()
if tc.Skip {
t.SkipNow()
return
}
ctx := context.Background()
if err := tc.Run(ctx, repo); err != nil {
t.Errorf("%+v", errors.WithStack(err))
}
})
}(tc)
}
}

View File

@ -2,6 +2,7 @@ package spec
import (
_ "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
_ "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/mdns/spec"
_ "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/openwrt/spec/sysupgrade"
_ "forge.cadoles.com/Cadoles/emissary/internal/spec/proxy"
_ "forge.cadoles.com/Cadoles/emissary/internal/spec/uci"

View File

@ -1,11 +1,13 @@
package jwk
import (
"context"
"crypto/rand"
"crypto/rsa"
"encoding/json"
"io/ioutil"
"os"
"time"
"github.com/btcsuite/btcd/btcutil/base58"
"github.com/lestrrat-go/jwx/v2/jwa"
@ -34,7 +36,7 @@ func Parse(src []byte, options ...jwk.ParseOption) (Set, error) {
return jwk.Parse(src, options...)
}
func PublicKeySet(keys ...jwk.Key) (jwk.Set, error) {
func RS256PublicKeySet(keys ...jwk.Key) (jwk.Set, error) {
set := jwk.NewSet()
for _, k := range keys {
@ -85,6 +87,27 @@ func LoadOrGenerate(path string, size int) (jwk.Key, error) {
return key, nil
}
func CreateCachedRemoteKeySet(ctx context.Context, url string, refreshInterval time.Duration) (func(context.Context) (jwk.Set, error), error) {
cache := jwk.NewCache(ctx)
if err := cache.Register(url, jwk.WithMinRefreshInterval(refreshInterval)); err != nil {
return nil, errors.WithStack(err)
}
if _, err := cache.Refresh(ctx, url); err != nil {
return nil, errors.WithStack(err)
}
return func(ctx context.Context) (jwk.Set, error) {
keySet, err := cache.Get(ctx, url)
if err != nil {
return nil, errors.WithStack(err)
}
return keySet, nil
}, nil
}
func Generate(size int) (jwk.Key, error) {
privKey, err := rsa.GenerateKey(rand.Reader, size)
if err != nil {

View File

@ -12,7 +12,7 @@ func TestJWK(t *testing.T) {
t.Fatalf("%+v", errors.WithStack(err))
}
keySet, err := PublicKeySet(privateKey)
keySet, err := RS256PublicKeySet(privateKey)
if err != nil {
t.Fatalf("%+v", errors.WithStack(err))
}

View File

@ -2,7 +2,6 @@ package migrate
import (
"fmt"
"log"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
@ -23,8 +22,6 @@ func New(migrationDir, driver, dsn string) (*migrate.Migrate, error) {
fmt.Sprintf("file://%s/%s", migrationDir, driver),
dsn,
)
log.Println(migrationDir, driver, dsn)
if err != nil {
return nil, errors.WithStack(err)
}

View File

@ -145,6 +145,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
type updateAgentRequest struct {
Status *datastore.AgentStatus `json:"status" validate:"omitempty,oneof=0 1 2 3"`
Label *string `json:"label" validate:"omitempty"`
}
func (s *Server) updateAgent(w http.ResponseWriter, r *http.Request) {
@ -166,6 +167,10 @@ func (s *Server) updateAgent(w http.ResponseWriter, r *http.Request) {
options = append(options, datastore.WithAgentUpdateStatus(*updateAgentReq.Status))
}
if updateAgentReq.Label != nil {
options = append(options, datastore.WithAgentUpdateLabel(*updateAgentReq.Label))
}
agent, err := s.agentRepo.Update(
ctx,
datastore.AgentID(agentID),

View File

@ -6,6 +6,9 @@ import (
"log"
"net"
"net/http"
"reflect"
"strings"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/auth"
"forge.cadoles.com/Cadoles/emissary/internal/auth/agent"
@ -13,9 +16,13 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/config"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/vm"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/cors"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwt"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -72,20 +79,6 @@ func (s *Server) run(parentCtx context.Context, addrs chan net.Addr, errs chan e
}
}()
key, err := jwk.LoadOrGenerate(string(s.conf.PrivateKeyPath), jwk.DefaultKeySize)
if err != nil {
errs <- errors.WithStack(err)
return
}
keys, err := jwk.PublicKeySet(key)
if err != nil {
errs <- errors.WithStack(err)
return
}
router := chi.NewRouter()
router.Use(middleware.Logger)
@ -100,13 +93,20 @@ func (s *Server) run(parentCtx context.Context, addrs chan net.Addr, errs chan e
router.Use(corsMiddleware.Handler)
thirdPartyAuth, err := s.getThirdPartyAuthenticator()
if err != nil {
errs <- errors.WithStack(err)
return
}
router.Route("/api/v1", func(r chi.Router) {
r.Post("/register", s.registerAgent)
r.Group(func(r chi.Router) {
r.Use(auth.Middleware(
thirdparty.NewAuthenticator(keys, string(s.conf.Issuer)),
agent.NewAuthenticator(s.agentRepo),
thirdPartyAuth,
agent.NewAuthenticator(s.agentRepo, agent.DefaultAcceptableSkew),
))
r.Route("/agents", func(r chi.Router) {
@ -131,6 +131,151 @@ func (s *Server) run(parentCtx context.Context, addrs chan net.Addr, errs chan e
logger.Info(ctx, "http server exiting")
}
func (s *Server) getThirdPartyAuthenticator() (*thirdparty.Authenticator, error) {
var localPublicKey jwk.Key
localAuth := s.conf.Auth.Local
if localAuth != nil {
key, err := jwk.LoadOrGenerate(string(localAuth.PrivateKeyPath), jwk.DefaultKeySize)
if err != nil {
return nil, errors.WithStack(err)
}
publicKey, err := key.PublicKey()
if err != nil {
return nil, errors.WithStack(err)
}
if err := publicKey.Set(jwk.AlgorithmKey, jwa.RS256); err != nil {
return nil, errors.WithStack(err)
}
localPublicKey = publicKey
}
var getRemoteKeySet thirdparty.GetKeySet
remoteAuth := s.conf.Auth.Remote
if remoteAuth != nil {
refreshInterval := time.Minute * 15
if remoteAuth.RefreshInterval != nil {
refreshInterval = time.Duration(*remoteAuth.RefreshInterval)
}
fn, err := jwk.CreateCachedRemoteKeySet(context.Background(), string(remoteAuth.JsonWebKeySetURL), refreshInterval)
if err != nil {
return nil, errors.WithStack(err)
}
getRemoteKeySet = fn
}
getKeySet := func(ctx context.Context) (jwk.Set, error) {
keySet := jwk.NewSet()
if localPublicKey != nil {
if err := keySet.AddKey(localPublicKey); err != nil {
return nil, errors.WithStack(err)
}
}
if getRemoteKeySet != nil {
remoteKeySet, err := getRemoteKeySet(ctx)
if err != nil {
return nil, errors.WithStack(err)
}
for idx := 0; idx < remoteKeySet.Len(); idx++ {
key, ok := remoteKeySet.Key(idx)
if !ok {
break
}
if err := keySet.AddKey(key); err != nil {
return nil, errors.WithStack(err)
}
}
}
return keySet, nil
}
getTokenRole, err := s.createGetTokenRoleFunc()
if err != nil {
return nil, errors.WithStack(err)
}
return thirdparty.NewAuthenticator(getKeySet, getTokenRole, thirdparty.DefaultAcceptableSkew), nil
}
func (s *Server) createGetTokenRoleFunc() (func(ctx context.Context, token jwt.Token) (string, error), error) {
rawRules := s.conf.Auth.RoleExtractionRules
rules := make([]*vm.Program, 0, len(rawRules))
type Env struct {
JWT map[string]any `expr:"jwt"`
}
strFunc := expr.Function(
"str",
func(params ...any) (any, error) {
var builder strings.Builder
for _, p := range params {
if _, err := builder.WriteString(fmt.Sprintf("%v", p)); err != nil {
return nil, errors.WithStack(err)
}
}
return builder.String(), nil
},
new(func(any) string),
)
for _, rr := range rawRules {
r, err := expr.Compile(rr,
expr.Env(Env{}),
expr.AsKind(reflect.String),
strFunc,
)
if err != nil {
return nil, errors.Wrapf(err, "could not compile role extraction rule '%s'", rr)
}
rules = append(rules, r)
}
return func(ctx context.Context, token jwt.Token) (string, error) {
jwt, err := token.AsMap(ctx)
if err != nil {
return "", errors.WithStack(err)
}
vm := vm.VM{}
for _, r := range rules {
result, err := vm.Run(r, Env{
JWT: jwt,
})
if err != nil {
return "", errors.WithStack(err)
}
role, ok := result.(string)
if !ok {
logger.Debug(ctx, "ignoring unexpected role extraction result", logger.F("result", result))
continue
}
if role != "" {
return role, nil
}
}
return "", errors.New("could not extract role from token")
}, nil
}
func New(funcs ...OptionFunc) *Server {
opt := defaultOption()
for _, fn := range funcs {

View File

@ -58,6 +58,12 @@ func (s *Server) updateSpec(w http.ResponseWriter, r *http.Request) {
updateSpecReq.SpecData(),
)
if err != nil {
if errors.Is(err, datastore.ErrNotFound) {
api.ErrorResponse(w, http.StatusNotFound, ErrCodeNotFound, nil)
return
}
if errors.Is(err, datastore.ErrUnexpectedRevision) {
api.ErrorResponse(w, http.StatusConflict, ErrCodeUnexpectedRevision, nil)
@ -87,6 +93,12 @@ func (s *Server) getAgentSpecs(w http.ResponseWriter, r *http.Request) {
specs, err := s.agentRepo.GetSpecs(ctx, agentID)
if err != nil {
if errors.Is(err, datastore.ErrNotFound) {
api.ErrorResponse(w, http.StatusNotFound, ErrCodeNotFound, nil)
return
}
logger.Error(ctx, "could not list specs", logger.E(errors.WithStack(err)))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)

View File

@ -0,0 +1 @@
ALTER TABLE agents DROP COLUMN label;

View File

@ -0,0 +1 @@
ALTER TABLE agents ADD COLUMN label TEXT DEFAULT "";

View File

@ -0,0 +1 @@
ALTER TABLE agents DROP COLUMN contacted_at;

View File

@ -0,0 +1 @@
ALTER TABLE agents ADD COLUMN contacted_at datetime;

24
misc/jenkins/Dockerfile Normal file
View File

@ -0,0 +1,24 @@
FROM reg.cadoles.com/proxy_cache/library/ubuntu:22.04
ARG HTTP_PROXY=
ARG HTTPS_PROXY=
ARG http_proxy=
ARG https_proxy=
ARG GO_VERSION=1.20.2
# Install dev environment dependencies
RUN export DEBIAN_FRONTEND=noninteractive &&\
apt-get update -y &&\
apt-get install -y --no-install-recommends curl ca-certificates build-essential wget unzip tar git jq
# Install Go
RUN mkdir -p /tmp \
&& wget -O /tmp/go${GO_VERSION}.linux-amd64.tar.gz https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz \
&& rm -rf /usr/local/go \
&& mkdir -p /usr/local \
&& tar -C /usr/local -xzf /tmp/go${GO_VERSION}.linux-amd64.tar.gz
ENV PATH="${PATH}:/usr/local/go/bin"
# Add LetsEncrypt certificates
RUN curl -k https://forge.cadoles.com/Cadoles/Jenkins/raw/branch/master/resources/com/cadoles/common/add-letsencrypt-ca.sh | bash

View File

@ -2,14 +2,12 @@ logger:
level: 1
format: human
server:
privateKeyPath: /var/lib/emissary/server-key.json
issuer: http://127.0.0.1:3000
http:
host: 0.0.0.0
port: 3000
database:
driver: sqlite
dsn: sqlite:///var/lib/emissary/data.sqlite
dsn: sqlite:///var/lib/emissary/data.sqlite?_pragma=foreign_keys(1)&_pragma=busy_timeout=60000
cors:
allowedOrigins: []
allowCredentials: true
@ -25,3 +23,11 @@ server:
- Authorization
- Sentry-Trace
debug: false
auth:
local:
privateKeyPath: /var/lib/emissary/server-key.json
roleExtractionRules:
- "jwt.role != nil ? str(jwt.role) : ''"
remote: ~
# jwksUrl: https://my-server/.well-known/jwks.json

View File

@ -6,7 +6,7 @@ After=network.target
Type=simple
Restart=always
WorkingDirectory=/usr/share/emissary
ExecStart=/usr/bin/emissary --config /etc/emissary/config.yml agent run
ExecStart=/usr/bin/emissary --config /etc/emissary/agent.yml agent run
[Install]
WantedBy=multi-user.target

View File

@ -4,9 +4,9 @@ After=network.target
[Service]
Type=simple
Restart=always
Restart=on-failure
WorkingDirectory=/usr/share/emissary
ExecStart=/usr/bin/emissary --config /etc/emissary/config.yml server run
ExecStart=/usr/bin/emissary --config /etc/emissary/server.yml server run
[Install]
WantedBy=multi-user.target

1
misc/resources/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,30 +1,33 @@
{
"apps": {
"portal": {
"url": "https://emissary.cadol.es/files/apps/arcad.portal_v2023.3.28-3feda80.zip",
"sha256sum": "921402c44a5fa554d5b630d1284957b05416aa6872b402314cf52e964e06fac5",
"address": "127.0.0.1:8082",
"app.arcad.edge.hextris": {
"url": "https://emissary.cadol.es/files/apps/app.arcad.edge.hextris_v2023.4.20-2bbbe94.zip",
"sha256sum": "67942ef4b623c46308c3f640b534bd4cb6b1d6021a422e40b62ab97658ba4586",
"address": ":8083",
"format": "zip"
},
"hextris": {
"url": "https://emissary.cadol.es/files/apps/app.arcad.edge.hextris_v2023.3.22-33ece28.zip",
"sha256sum": "5f9f3c8d6f22796beb051d747d7ff12efa17af9d1552c0ab08baef13703a2aba",
"address": "127.0.0.1:8083",
"format": "zip"
},
"test": {
"url": "https://emissary.cadol.es/files/apps/edge.sdk.client.test_v2023.3.24-ed535b6.zip",
"sha256sum": "e97b7b79159bb5d6a13b05644c091272b02a1a3cbb1b613dd5eda37e1eb84623",
"address": "127.0.0.1:8084",
"edge.sdk.client.test": {
"url": "https://emissary.cadol.es/files/apps/edge.sdk.client.test_v2023.4.20-20c4189.zip",
"sha256sum": "1edeb4aa75c1675db49cf27367b1537234a04526848ea6657931ca63f26e5dae",
"address": ":8084",
"format": "zip"
}
},
"config": {
"appUrlTemplate": "http://{{ last ( splitList \".\" ( toString .Manifest.ID ) ) }}.arcad.local:8080",
"appUrlResolving": {
"ifaceMappings": {
"eth0": "http://{{ .DeviceIP }}:{{ .AppPort }}",
"eth1": "http://{{ .DeviceIP }}:{{ .AppPort }}"
},
"defaultUrlTemplate": "http://{{ last ( splitList \".\" ( toString .Manifest.ID ) ) }}.localhost.arcad.lan:8080"
},
"unexpectedHostRedirect": {
"acceptedHostPatterns": ["arcad.lan", "*.arcad.lan", "arcad-*.local", "*.*.*.*"],
"hostTarget": "localhost.arcad.lan"
},
"auth": {
"local": {
"key": "absolutlynotsecret",
"cookieDomain": ".arcad.local",
"cookieDuration": "1h",
"accounts": [
{
@ -32,11 +35,44 @@
"algo": "plain",
"password": "admin",
"claims": {
"arcad_role": "admin",
"arcad_tenant": "x86",
"edge_role": "admin",
"edge_tenant": "emissary-dev",
"preferred_username": "Admin",
"sub": "admin"
}
},
{
"username": "superadmin",
"algo": "plain",
"password": "superadmin",
"claims": {
"edge_role": "superadmin",
"edge_tenant": "emissary-dev",
"preferred_username": "SuperAdmin",
"sub": "superadmin"
}
},
{
"username": "user",
"algo": "plain",
"password": "user",
"claims": {
"edge_role": "user",
"edge_tenant": "emissary-dev",
"preferred_username": "User",
"sub": "user"
}
},
{
"username": "superuser",
"algo": "plain",
"password": "superuser",
"claims": {
"edge_role": "superuser",
"edge_tenant": "emissary-dev",
"preferred_username": "SuperUser",
"sub": "superuser"
}
}
]
}

View File

@ -0,0 +1,19 @@
{
"services": {
"arcad": {
"type": "_http._tcp",
"port": 8080,
"host": "arcad"
},
"hextris": {
"type": "_http._tcp",
"port": 8080,
"host": "arcad-hextris"
},
"test": {
"type": "_http._tcp",
"port": 8080,
"host": "arcad-test"
}
}
}

View File

@ -4,20 +4,24 @@
"address": ":8080",
"mappings": [
{
"hostPattern": "portal.arcad.local:*",
"target": "http://localhost:8082"
},
{
"hostPattern": "hextris.arcad.local:*",
"hostPattern": "hextris.localhost.arcad.lan:*",
"target": "http://localhost:8083"
},
{
"hostPattern": "test.arcad.local:*",
"hostPattern": "test.localhost.arcad.lan:*",
"target": "http://localhost:8084"
},
{
"hostPattern": "arcad-hextris.local:*",
"target": "http://localhost:8083"
},
{
"hostPattern": "arcad-test.local:*",
"target": "http://localhost:8084"
},
{
"hostPattern": "*",
"target": "http://localhost:8082"
"target": "http://localhost:8084"
}
]
}

23
pkg/client/alias.go Normal file
View File

@ -0,0 +1,23 @@
package client
import (
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
)
type (
Spec = spec.Spec
SpecName = spec.Name
)
type (
AgentID = datastore.AgentID
Agent = datastore.Agent
AgentStatus = datastore.AgentStatus
)
type MetadataTuple = metadata.Tuple
type Key = jwk.Key

View File

@ -8,7 +8,7 @@ import (
"github.com/pkg/errors"
)
func (c *Client) DeleteAgent(ctx context.Context, agentID datastore.AgentID, funcs ...OptionFunc) (datastore.AgentID, error) {
func (c *Client) DeleteAgent(ctx context.Context, agentID AgentID, funcs ...OptionFunc) (AgentID, error) {
response := withResponse[struct {
AgentID int64 `json:"agentId"`
}]()

View File

@ -4,12 +4,11 @@ import (
"context"
"fmt"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
)
func (c *Client) DeleteAgentSpec(ctx context.Context, agentID datastore.AgentID, name spec.Name, funcs ...OptionFunc) (spec.Name, error) {
func (c *Client) DeleteAgentSpec(ctx context.Context, agentID AgentID, name SpecName, funcs ...OptionFunc) (SpecName, error) {
payload := struct {
Name spec.Name `json:"name"`
}{

View File

@ -4,13 +4,12 @@ import (
"context"
"fmt"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"github.com/pkg/errors"
)
func (c *Client) GetAgent(ctx context.Context, agentID datastore.AgentID, funcs ...OptionFunc) (*datastore.Agent, error) {
func (c *Client) GetAgent(ctx context.Context, agentID AgentID, funcs ...OptionFunc) (*Agent, error) {
response := withResponse[struct {
Agent *datastore.Agent `json:"agent"`
Agent *Agent `json:"agent"`
}]()
path := fmt.Sprintf("/api/v1/agents/%d", agentID)

View File

@ -4,12 +4,11 @@ import (
"context"
"fmt"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
)
func (c *Client) GetAgentSpecs(ctx context.Context, agentID datastore.AgentID, funcs ...OptionFunc) ([]spec.Spec, error) {
func (c *Client) GetAgentSpecs(ctx context.Context, agentID AgentID, funcs ...OptionFunc) ([]Spec, error) {
response := withResponse[struct {
Specs []*spec.RawSpec `json:"specs"`
}]()

View File

@ -16,8 +16,8 @@ type QueryAgentsOptions struct {
Limit *int
Offset *int
Thumbprints []string
IDs []datastore.AgentID
Statuses []datastore.AgentStatus
IDs []AgentID
Statuses []AgentStatus
}
func WithQueryAgentsOptions(funcs ...OptionFunc) QueryAgentsOptionFunc {
@ -56,7 +56,7 @@ func WithQueryAgentsStatus(statuses ...datastore.AgentStatus) QueryAgentsOptionF
}
}
func (c *Client) QueryAgents(ctx context.Context, funcs ...QueryAgentsOptionFunc) ([]*datastore.Agent, int, error) {
func (c *Client) QueryAgents(ctx context.Context, funcs ...QueryAgentsOptionFunc) ([]*Agent, int, error) {
options := &QueryAgentsOptions{}
for _, fn := range funcs {
fn(options)

View File

@ -9,8 +9,8 @@ import (
"github.com/pkg/errors"
)
func (c *Client) RegisterAgent(ctx context.Context, key jwk.Key, thumbprint string, meta []metadata.Tuple, funcs ...OptionFunc) (*datastore.Agent, error) {
keySet, err := jwk.PublicKeySet(key)
func (c *Client) RegisterAgent(ctx context.Context, key Key, thumbprint string, meta []MetadataTuple, funcs ...OptionFunc) (*Agent, error) {
keySet, err := jwk.RS256PublicKeySet(key)
if err != nil {
return nil, errors.WithStack(err)
}

View File

@ -10,6 +10,7 @@ import (
type UpdateAgentOptions struct {
Status *int
Label *string
Options []OptionFunc
}
@ -21,6 +22,12 @@ func WithAgentStatus(status int) UpdateAgentOptionFunc {
}
}
func WithAgentLabel(label string) UpdateAgentOptionFunc {
return func(opts *UpdateAgentOptions) {
opts.Label = &label
}
}
func WithUpdateAgentsOptions(funcs ...OptionFunc) UpdateAgentOptionFunc {
return func(opts *UpdateAgentOptions) {
opts.Options = funcs
@ -39,6 +46,10 @@ func (c *Client) UpdateAgent(ctx context.Context, agentID datastore.AgentID, fun
payload["status"] = *opts.Status
}
if opts.Label != nil {
payload["label"] = *opts.Label
}
response := withResponse[struct {
Agent *datastore.Agent `json:"agent"`
}]()

View File

@ -10,7 +10,7 @@ import (
"github.com/pkg/errors"
)
func (c *Client) UpdateAgentSpec(ctx context.Context, agentID datastore.AgentID, spc spec.Spec, funcs ...OptionFunc) (*datastore.Spec, error) {
func (c *Client) UpdateAgentSpec(ctx context.Context, agentID AgentID, spc Spec, funcs ...OptionFunc) (Spec, error) {
payload := struct {
Name spec.Name `json:"name"`
Revision int `json:"revision"`