Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flux updates #1286

Merged
merged 11 commits into from
Jul 4, 2024
Merged
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ jobs:
echo "Installing @prosopo/flux..."
npm i -g @prosopo/flux
echo "Soft redeploying flux docker js_server."
npx flux redeploy --app ProcaptchaJavascriptServer
npx flux redeploy ProcaptchaJavascriptServer
else
echo "Skipping flux redeploy."
fi
Expand Down
44 changes: 34 additions & 10 deletions dev/flux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ the app you are working with and login with the login phrase and signature.

```bash
# authenticate with the network for a specific app
npx flux auth --app <app_name>
npx flux auth <app_name>
{
nodeAPIURL: URL {
# You can now visit this (using port 16126) to login with the login phrase and signature
Expand All @@ -52,7 +52,7 @@ Use to generate the authentication for a Flux node for a specific app on a speci

```bash
# authenticate with the network for a specific app at a specific ip
npx flux auth --app <app_name> --ip <node_ip=x.x.x.x:port>
npx flux auth <app_name> --ip <node_ip=x.x.x.x:port>
```

### Get Dapp Details
Expand All @@ -74,7 +74,7 @@ Use this command to get the full details of a dapp running on the network.

```bash
# get details of a specific dapp
npx flux getDapp --app <app_name>
npx flux getDapp <app_name>
```

#### Nodes only
Expand All @@ -83,7 +83,7 @@ Use this command to get the IP addresses of the nodes that are running the app.

```bash
# get details of a specific dapp and show only the nodes
npx flux getDapp --app <app_name> --nodes
npx flux getDapp <app_name> --nodes
```

### Redeploy
Expand All @@ -94,7 +94,7 @@ Restart the app on all nodes that are running the app.

```bash
# redeploy the app
npx flux redeploy --app <app_name>
npx flux redeploy <app_name>
...
ℹ apiUrl: http://x.x.x.x:16127/id/verifylogin deploy.js 15:00:42
ℹ { status: 'success', deploy.js 15:00:42
Expand All @@ -107,7 +107,7 @@ Remove the container and restart the app on all nodes that are running the app.

```bash
# hard redeploy the app
npx flux redeploy --app <app_name> --hard
npx flux redeploy <app_name> --hard
...
ℹ apiUrl: http://x.x.x.x:16127/id/verifylogin deploy.js 15:00:42
ℹ { status: 'success', deploy.js 15:00:42
Expand All @@ -122,7 +122,7 @@ Use this command to get the logs of the app for all nodes.

```bash
# get logs of a specific dapp
npx flux getLogs --app <app_name>
npx flux getLogs <app_name>

┌─────────┬─────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────┐
│ (index) │ url │ logs │
Expand All @@ -148,7 +148,7 @@ Use this command to get the logs of the app from a specific node.

```bash
# get logs of a specific dapp at a specific ip
npx flux getLogs --app <app_name> --ip <node_ip=x.x.x.x:port>
npx flux getLogs <app_name> --ip <node_ip=x.x.x.x:port>
```

#### Save the logs to a file
Expand All @@ -157,7 +157,7 @@ Use this command to get the logs of the app from a specific node.

```bash
# get logs of a specific dapp and save them to a file. The log format will be `host | log` with the logs separated by a newline
npx flux getLogs --app <app_name> --file <file_name>
npx flux getLogs <app_name> --file <file_name>
```

#### Sign a Message
Expand All @@ -166,5 +166,29 @@ Use this command to sign a message with the private key of the node.

```bash
# sign a message
npx flux sign --msg <message>
> npx flux sign <msg>
CLI:info {
_: [ 'sign' ],
'$0': 'node_modules/.bin/flux',
msg: '<msg>'
}
CLI:info Public Key: 15...b
CLI:info Base64 Signature: H...=
```

### Format an env file

Use this command to format an env file in the array format needed for updating in FluxOS. The output will be printed to the terminal.

```bash
# format the env file
> npx flux formatenv .env
CLI:info ["FOO=bar","BAR=BLAH"]
```

You can write the output to a file by using the `--write` flag.

```bash
# format the env file and write the output to a file
> npx flux formatenv .env --write <file_name>
```
1 change: 1 addition & 0 deletions dev/flux/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"consola": "^3.2.3",
"dotenv": "^16.0.3",
"glob": "^10.0.0",
"openpgp": "^5.11.1",
"qs": "^6.11.2",
"socket.io-client": "^4.7.4",
"varuint-bitcoin": "^1.1.2",
Expand Down
4 changes: 2 additions & 2 deletions dev/flux/src/commands/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ export default (cmdArgs?: { logger?: Logger }) => {
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.auth')

return {
command: 'auth',
command: 'auth <app>',
describe: 'Authenticate with a Flux Node',
builder: (yargs: Argv) =>
yargs
.option('app', {
.positional('app', {
type: 'string' as const,
demandOption: false,
desc: 'Name of the app to authenticate with. Authentication is done with api.runonflux.io by default.',
Expand Down
49 changes: 49 additions & 0 deletions dev/flux/src/commands/formatEnv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as z from 'zod'
import { ArgumentsCamelCase, Argv } from 'yargs'
import { LogLevel, Logger, getLogger } from '@prosopo/common'
import { formatEnvToArray } from '../lib/formatEnv.js'
import fs from 'fs'
import path from 'path'

const fluxFormatEnvArgs = z.object({
file: z.string(),
write: z.string().optional(),
})
export default (cmdArgs?: { logger?: Logger }) => {
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.getDapp')

return {
command: 'formatenv <file>',
describe: 'Format an environment file to an array',
builder: (yargs: Argv) =>
yargs
.positional('file', {
type: 'string' as const,
demandOption: false,
desc: 'Name of the dapp to get the details of',
} as const)
.option('--write', {
type: 'string' as const,
demandOption: false,
desc: 'Write the formatted env to a file',
} as const),
handler: async (argv: ArgumentsCamelCase) => {
try {
const parsedArgs = fluxFormatEnvArgs.parse(argv)

const formattedEnv = formatEnvToArray(parsedArgs.file)

logger.info(formattedEnv)

if (parsedArgs.write) {
const writePath = path.resolve(parsedArgs.write)
fs.writeFileSync(writePath, formattedEnv)
logger.info(`Formatted env written to ${writePath}`)
}
} catch (err) {
logger.error(err)
}
},
middlewares: [],
}
}
4 changes: 2 additions & 2 deletions dev/flux/src/commands/getDapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ export default (cmdArgs?: { logger?: Logger }) => {
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.getDapp')

return {
command: 'getDapp',
command: 'getDapp <app>',
describe: 'Get dapp details',
builder: (yargs: Argv) =>
yargs
.option('app', {
.positional('app', {
type: 'string' as const,
demandOption: false,
desc: 'Name of the dapp to get the details of',
Expand Down
1 change: 1 addition & 0 deletions dev/flux/src/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export { default as commandGetDapp } from './getDapp.js'
export { default as commandLogs } from './logs.js'
export { default as commandSign } from './sign.js'
export { default as commandTerminal } from './terminal.js'
export { default as commandFormatEnv } from './formatEnv.js'
2 changes: 1 addition & 1 deletion dev/flux/src/commands/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default (cmdArgs?: { logger?: Logger }) => {
describe: 'Output the last `n` lines of logs from a Flux Node',
builder: (yargs: Argv) =>
yargs
.option('app', {
.positional('<app>', {
type: 'string' as const,
demandOption: false,
desc: 'Name of the app to authenticate with. Authentication is done with api.runonflux.io by default.',
Expand Down
23 changes: 17 additions & 6 deletions dev/flux/src/commands/redeploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,25 @@ export default (cmdArgs?: { logger?: Logger }) => {
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.deploy')

return {
command: 'redeploy',
command: 'redeploy <app>',
describe: 'Deploy a Flux application',
builder: (yargs: Argv) =>
yargs.option('hard', {
type: 'boolean' as const,
demand: false,
desc: 'Whether to hard redeploy the app',
} as const),
yargs
.positional('app', {
type: 'string' as const,
demandOption: false,
desc: 'Name of the app to redeploy.',
} as const)
.option('ip', {
type: 'string' as const,
demandOption: false,
desc: 'IP of the Flux node to authenticate with. Authentication is done with api.runonflux.io by default.',
} as const)
.option('hard', {
type: 'boolean' as const,
demand: false,
desc: 'Whether to hard redeploy the app',
} as const),
handler: async (argv: ArgumentsCamelCase) => {
try {
const privateKey = getPrivateKey()
Expand Down
19 changes: 10 additions & 9 deletions dev/flux/src/commands/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,42 @@ import { ArgumentsCamelCase, Argv } from 'yargs'
import { Keypair } from '@polkadot/util-crypto/types'
import { LogLevel, Logger, getLogger } from '@prosopo/common'
import { base58Decode, base64Encode } from '@polkadot/util-crypto'
import { sign, wifToPrivateKey } from '../lib/sep256k1Sign.js'
import { getPrivateKey, getPublicKey } from './process.env.js'
import { sign } from '../lib/sep256k1Sign.js'
import { u8aToHex } from '@polkadot/util'
const msgSpec = z.string()

export default (cmdArgs?: { logger?: Logger }) => {
const logger = cmdArgs?.logger || getLogger(LogLevel.enum.info, 'flux.cli.auth')

return {
command: 'sign',
command: 'sign <msg>',
describe: 'Sign a message with a private key',
builder: (yargs: Argv) =>
yargs.option('msg', {
yargs.positional('msg', {
type: 'string',
demandOption: true,
desc: 'Message to sign',
} as const),
handler: async (argv: ArgumentsCamelCase) => {
const secretKey = wifToPrivateKey(process.env.PROSOPO_ZELCORE_PRIVATE_KEY || '')
const publicKey: Uint8Array = base58Decode(process.env.PROSOPO_ZELCORE_PUBLIC_KEY || '')
const publicKeyEncoded = getPublicKey()
const secretKey = getPrivateKey()
const publicKey: Uint8Array = base58Decode(publicKeyEncoded)
const keypair: Keypair = { secretKey, publicKey }
const message = msgSpec.parse(argv.msg)
if (message.length === 0) {
console.error('No message provided')
logger.error('No message provided')
process.exit()
}
sign(message, keypair)
.then((sig) => {
const hexSig = u8aToHex(sig)
logger.info(`Hex Signature : ${hexSig}`)
logger.info(`Public Key: ${publicKey}`)
logger.info(`Public Key: ${publicKeyEncoded}`)
logger.info(`Base64 Signature: ${base64Encode(hexSig)}`)
process.exit()
})
.catch((error) => {
console.error(error)
logger.error(error)
process.exit()
})
},
Expand Down
2 changes: 2 additions & 0 deletions dev/flux/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import { LogLevel, getLogger } from '@prosopo/common'
import {
commandAuth,
commandFormatEnv,
commandGetDapp,
commandGetDapps,
commandLogs,
Expand All @@ -32,6 +33,7 @@ export default async function processArgs(args: string[]) {
.usage('Usage: $0 [global options] <command> [options]')
.command(commandAuth({ logger }))
.command(commandRedeploy({ logger }))
.command(commandFormatEnv({ logger }))
.command(commandGetDapp({ logger }))
.command(commandGetDapps({ logger }))
.command(commandLogs({ logger }))
Expand Down
69 changes: 69 additions & 0 deletions dev/flux/src/lib/appUpdateSpecification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Example of an AppUpdateSpecification Object
// {
// "name": "emailTriggerServer",
// "compose": [
// {
// "name": "emailTriggerSignupApi",
// "description": "emailTriggerSignupApi",
// "repotag": "prosopo/email-trigger-server:latest",
// "ports": "[3400]",
// "domains": "[\"email.prosopo.io\"]",
// "environmentParameters": "[]",
// "commands": "[]",
// "containerPorts": "[9232]",
// "containerData": "/data",
// "cpu": 1,
// "ram": 1100,
// "hdd": 5,
// "tiered": false,
// "secrets": "-----BEGIN PGP MESSAGE-----\n=yFqX\n-----END PGP MESSAGE-----\n",
// "repoauth": ""
// }
// ],
// "contacts": "[\"dev@prosopo.io\"]",
// "description": "Triggers email sends for signups",
// "expire": 195800,
// "geolocation": [],
// "hash": "1dec38f3fc41dd353afb75c7fa17a6f051018f1cbf6266f730f235eb15f966ba",
// "height": 1663852,
// "instances": 3,
// "owner": "15gSe8HrNhVrWph6CTPtpb6nXESqPtgCCe",
// "version": 7,
// "nodes": [
// "65.109.20.197",
// "65.109.91.17",
// ],
// "staticip": false
// }

export interface AppUpdateSpecification {
name: string
compose: {
name: string
description: string
repotag: string
ports: string
domains: string
environmentParameters: string
commands: string
containerPorts: string
containerData: string
cpu: number
ram: number
hdd: number
tiered: boolean
secrets: string
repoauth: string
}[]
contacts: string
description: string
expire: number
geolocation: string[]
hash: string
height: number
instances: number
owner: string
version: number
nodes: string[]
staticip: boolean
}
Loading
Loading