Skip to content

Commit

Permalink
Many fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Hexagon committed May 4, 2024
1 parent a9dd365 commit ce3b829
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 74 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ _For detailed documentation, visit [pup.56k.guru](https://pup.56k.guru)._
To install Pup, make sure you run the latest version of Deno (`deno upgrade`), then open your terminal and execute the following command:

```bash
deno run -Ar jsr:@pup/pup@1.0.0-rc.37 setup --channel prerelease
deno run -Ar jsr:@pup/pup@1.0.0-rc.39 setup --channel prerelease
```

This command downloads the latest version of Pup and installs it on your system. The `--channel prerelease` option is included as there is no stable version of Pup yet. Read more abour release
Expand Down
2 changes: 1 addition & 1 deletion application.meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

const Application = {
name: "pup",
version: "1.0.0-rc.38",
version: "1.0.0-rc.39",
url: "jsr:@pup/pup@$VERSION",
canary_url: "https://raw.githubusercontent.com/Hexagon/pup/main/pup.ts",
deno: null, /* Minimum stable version of Deno required to run Pup (without --unstable-* flags) */
Expand Down
12 changes: 6 additions & 6 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pup/pup",
"version": "1.0.0-rc.38",
"version": "1.0.0-rc.39",

"exports": {
".": "./pup.ts",
Expand Down Expand Up @@ -41,14 +41,14 @@
"@cross/deepmerge": "jsr:@cross/deepmerge@^1.0.0",
"@cross/env": "jsr:@cross/env@^1.0.2",
"@cross/fs": "jsr:@cross/fs@^0.1.11",
"@cross/jwt": "jsr:@cross/jwt@^0.4.6",
"@cross/jwt": "jsr:@cross/jwt@^0.4.7",
"@cross/runtime": "jsr:@cross/runtime@^1.0.0",
"@cross/service": "jsr:@cross/service@^1.0.3",
"@cross/test": "jsr:@cross/test@^0.0.9",
"@cross/utils": "jsr:@cross/utils@^0.12.0",
"@hexagon/croner": "jsr:@hexagon/croner@^8.0.2",
"@oak/oak": "jsr:@oak/oak@^15.0.0",
"@pup/api-client": "jsr:@pup/api-client@^1.0.4",
"@pup/api-client": "jsr:@pup/api-client@^1.0.6",
"@pup/api-definitions": "jsr:@pup/api-definitions@^1.0.2",
"@pup/common": "jsr:@pup/common@^1.0.3",
"@pup/plugin": "jsr:@pup/plugin@^1.0.1",
Expand All @@ -58,11 +58,11 @@
"@std/io": "jsr:@std/io@^0.224.0",
"@std/path": "jsr:@std/path@^0.224.0",
"@std/semver": "jsr:@std/semver@^0.224.0",
"dax-sh": "npm:dax-sh@^0.40.0",
"dax-sh": "npm:dax-sh@^0.41.0",
"filesize": "npm:filesize@^10.1.1",
"json5": "npm:json5@^2.2.3",
"timeago.js": "npm:timeago.js@^4.0.2",
"zod": "npm:zod@^3.22.4",
"zod-to-json-schema": "npm:zod-to-json-schema@^3.22.5"
"zod": "npm:zod@^3.23.6",
"zod-to-json-schema": "npm:zod-to-json-schema@^3.23.0"
}
}
2 changes: 1 addition & 1 deletion docs/src/_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"description": "Universal Process Manager"
},
"substitute": {
"$PUP_VERSION": "1.0.0-rc.38"
"$PUP_VERSION": "1.0.0-rc.39"
},
"top_links": [
{
Expand Down
9 changes: 8 additions & 1 deletion docs/src/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ nav_order: 13

All notable changes to this project will be documented in this section.

## [1.0.0-rc.39] - Unstable
## [1.0.0-rc.39] - 2024-05-04

- fix(core): Clustered processes were duplicated in API and `pup status`
- fix(core): Fix regression with `pup monitor`
- fix(core): Add API connection timeout
- chore(deps): Full dependency update
- fix(api): Log host and port when starting the Rest API Server
- fix(api): Clarify error messages
- fix(api): Remove unused (commented out) code
- fix(cli): Require `--expire-in` when generating tokens on the CLI

## [1.0.0-rc.38] - 2024-05-01

Expand Down
114 changes: 64 additions & 50 deletions lib/cli/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import { PupRestClient } from "@pup/api-client"
import { CurrentRuntime, Runtime } from "@cross/runtime"
import { Prop } from "../common/prop.ts"
import { encodeBase64 } from "@std/encoding/base64"
import { ApiLogItem } from "@pup/api-definitions"
import { EventHandler } from "@pup/common/eventemitter"

/**
* Define the main entry point of the CLI application
Expand Down Expand Up @@ -222,7 +224,7 @@ async function main() {

// Send api request
const apiBaseUrl = `http://${configuration.api?.hostname || DEFAULT_REST_API_HOSTNAME}:${port}`
client = new PupRestClient(apiBaseUrl, token!)
client = new PupRestClient(apiBaseUrl, token!, baseArgument === "monitor", 3000, 1)
} catch (_e) {
/* Ignore */
}
Expand All @@ -240,6 +242,9 @@ async function main() {
const expiresInSeconds = checkedArgs.get("expire-in")
if (expiresInSeconds) {
expiresAt = Date.now() + (parseInt(expiresInSeconds, 10) * 1000)
} else {
console.error("Error: You need to specify expiry time using --expire-in <seconds>")
exit(1)
}
const token = await GenerateToken(
secret,
Expand Down Expand Up @@ -360,59 +365,64 @@ async function main() {
* using websockets, and prints all received messages
*/
if (baseArgument === "monitor") {
const apiHostname = configuration.api?.hostname || DEFAULT_REST_API_HOSTNAME
const apiPort = port
const wsUrl = `ws://${apiHostname}:${apiPort}/wss`
const wss = new WebSocketStream(wsUrl, {
headers: {
"Authorization": `Bearer ${token}`,
},
})
const { readable } = await wss.opened
const reader = readable.getReader()
while (true) {
const { value, done } = await reader.read()
if (done) {
break
}
const logHandler = (e: ApiLogItem) => {
try {
const v = JSON.parse(value.toString())
if (v.t === "log") {
const logWithColors = configuration!.logger?.colors ?? true

const { processId, severity, category, timeStamp, text } = v.d

const severityFilter = !checkedArgs.get("severity") || checkedArgs.get("severity") === "" || checkedArgs.get("severity")!.toLowerCase() === severity.toLowerCase()
const processFilter = !checkedArgs.get("id") || checkedArgs.get("id") === "" || !processId || checkedArgs.get("id")!.toLowerCase() === processId.toLowerCase()

if (!severityFilter) continue
if (!processFilter) continue

const isStdErr = severity === "error" || category === "stderr"
const decoratedLogText = `${new Date(timeStamp).toISOString()} [${severity.toUpperCase()}] [${processId || "core"}:${category}] ${text}`
let color = null
// Apply coloring rules
if (logWithColors) {
if (processId === "core") color = "gray"
if (category === "starting") color = "green"
if (category === "finished") color = "yellow"
if (isStdErr) color = "red"
}
let logFn = console.log
if (severity === "warn") logFn = console.warn
if (severity === "info") logFn = console.info
if (severity === "error") logFn = console.error
if (color !== null) {
logFn(`%c${decoratedLogText}`, `color: ${color}`)
} else {
logFn(decoratedLogText)
}
const logWithColors = configuration!.logger?.colors ?? true
const { processId, severity, category, timeStamp, text } = e
const severityFilter = !checkedArgs.get("severity") || checkedArgs.get("severity") === "" || checkedArgs.get("severity")!.toLowerCase() === severity.toLowerCase()
const processFilter = !checkedArgs.get("id") || checkedArgs.get("id") === "" || !processId || checkedArgs.get("id")!.toLowerCase() === processId.toLowerCase()

if (!severityFilter) return
if (!processFilter) return

const isStdErr = severity === "error" || category === "stderr"
const decoratedLogText = `${new Date(timeStamp).toISOString()} [${severity.toUpperCase()}] [${processId || "core"}:${category}] ${text}`
let color = null
// Apply coloring rules
if (logWithColors) {
if (processId === "core") color = "gray"
if (category === "starting") color = "green"
if (category === "finished") color = "yellow"
if (isStdErr) color = "red"
}
let logFn = console.log
if (severity === "warn") logFn = console.warn
if (severity === "info") logFn = console.info
if (severity === "error") logFn = console.error
if (color !== null) {
logFn(`%c${decoratedLogText}`, `color: ${color}`)
} else {
logFn(decoratedLogText)
}
} catch (_e) {
console.error("Error in log streamer: " + _e)
}
}
return

// Test the client
let responseState
try {
responseState = await client?.getState()
if (!responseState?.data) {
console.error("Could not contact the Pup instance.")
exit(1)
}
} catch (_e) {
console.error("Action failed: Could not contact the Pup instance.")
exit(1)
}

// Output status
console.log(`Connected to Pup, streaming logs. Abort with CTRL+C.`)

// Start streaming logs
client?.on("log", logHandler as EventHandler<unknown>)

// Wait a year or so
await new Promise((resolve) => setTimeout(resolve, 365 * 24 * 60 * 60 * 1000))

// Exit
exit(0)
}

/**
Expand Down Expand Up @@ -537,7 +547,7 @@ async function main() {
return exit(1)
}
} catch (e) {
console.error("Action failed:", e)
console.error("Action failed:", e.name)
return exit(1)
}
}
Expand All @@ -556,7 +566,11 @@ async function main() {
console.warn(`Pup already running. Exiting.`)
exit(1)
}
} catch (_e) { /* Expected! ^*/ }
} catch (_e) {
/* Expected! ^*/
} finally {
client?.close()
}

/**
* Error handling: Require at least one configured process
Expand Down
17 changes: 3 additions & 14 deletions lib/core/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ const generateAuthMiddleware = (key: CryptoKey, revoked?: string[]) => {
if (payload.data?.consumer) {
if (revoked && revoked.find((r) => r.toLowerCase().trim() === payload.data?.consumer.toLowerCase().trim())) {
ctx.response.status = Status.Unauthorized
ctx.response.body = { error: "Invalid token" }
ctx.response.body = { error: "Revoked token" }
} else {
ctx.state.consumer = payload.data?.consumer
await next()
}
} else {
ctx.response.status = Status.Unauthorized
ctx.response.body = { error: "Invalid token" }
ctx.response.body = { error: "Token missing consumer" }
}
} else {
ctx.response.status = Status.Unauthorized
Expand Down Expand Up @@ -117,12 +117,6 @@ export class RestApi {
return ctx.throw(501)
}

// Handle incoming message, but y tho?
/*ws.onmessage = (m) => {
this.pupApi.events.on(evtName, proxyFnFactory(evtName))
ws.send(m.data as string)
}*/

// Expose events to the API Consumer
const proxyFns: Record<string, string | EventHandler<unknown>>[] = []
const proxyFnFactory = (evtName: string) => {
Expand Down Expand Up @@ -409,17 +403,12 @@ export class RestApi {
)
this.app.use(this.router.routes())
this.app.use(this.router.allowedMethods())
this.pupApi.log("info", "rest", `Starting the Rest API`)
this.pupApi.log("info", "rest", `Starting the Rest API on ${this.hostname}:${this.port}`)
await this.app.listen({
port: this.port,
hostname: this.hostname,
signal: this.appAbortController.signal,
})
this.pupApi.log(
"info",
"rest",
`Rest API running, available on ${this.hostname}:${this.port}`,
)
return this.port
}

Expand Down
14 changes: 14 additions & 0 deletions versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@
"canary_url": "https://raw.githubusercontent.com/Hexagon/pup/main/pup.ts",
"stable": [],
"prerelease": [
{
"version": "1.0.0-rc.39",
"url": "jsr:@pup/pup@1.0.0-rc.39",
"deno": null,
"deno_unstable": "1.43.0",
"default_permissions": [
"--allow-env",
"--allow-read",
"--allow-write",
"--allow-sys=loadavg,systemMemoryInfo,osUptime,osRelease,uid,gid",
"--allow-net",
"--allow-run"
]
},
{
"version": "1.0.0-rc.38",
"url": "jsr:@pup/pup@1.0.0-rc.38",
Expand Down

0 comments on commit ce3b829

Please sign in to comment.