Skip to content

Commit

Permalink
Change: split apm in more files and add more apm docs
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed May 22, 2024
1 parent ef3bbe9 commit 410a06a
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 91 deletions.
50 changes: 43 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
- [Execute and assets](#execute-and-assets)
- [Sftp](#sftp)
- [AbstractPackageManager](#abstractpackagemanager)
- [Custom package manager](#custom-package-manager)
- [Register package manager](#register-package-manager)
- [Exec Session](#exec-session)
- [Technologies](#technologies)
- [Contributing](#contributing)
Expand Down Expand Up @@ -62,19 +64,31 @@ npm i hivessh

```ts
import { SshHost } from "hivelib"
// or import SshHost from "hivelib" (SshHost is also the default export)

//connect
// connect
const myHost = await SshHost.connect({
host: "127.0.0.1",
//port: 22, (default 22)
//user: "root", (default root)

//password: "123456789",
// or
//privateKey: "..."
// or
//privateKeyPath:"/home/user/.ssh/id_rsa",
password: "123456789",
})
// or
const myHost = await SshHost.connect({
host: "127.0.0.1",
//port: 22, (default 22)
//user: "root", (default root)

privateKey: "..."
//passphrase: "123456789"
})
// or
const myHost = await SshHost.connect({
host: "127.0.0.1",
//port: 22, (default 22)
//user: "root", (default root)

privateKeyPath:"/home/user/.ssh/id_rsa",
//passphrase: "123456789"
})
```
Expand Down Expand Up @@ -156,6 +170,28 @@ await apm.upgradeAll()
await apm.install("git")
```

### Custom package manager

For creating a custon apm you need to implement the following typescript interface:
[https://github.com/NobleMajo/hivessh/blob/main/src/apm/ApmInterface.ts](https://github.com/NobleMajo/hivessh/blob/main/src/apm/ApmInterface.ts)

### Register package manager

After implementing the custom package manager you need to register it global via a checker function:
```ts
import { apmChecker, AbstractPackageManager } from "./apm/apm.js"

apmChecker.push(async (host) => {
if (await host.cmdExists("myapm")) {
const myApm: AbstractPackageManager = { ... }

return myApm
}
})
```

This function is called when the `getApm()` is called and can return a package manager depending on the host.

## Exec Session
Sessions are available so that the PWD (process working directory) and environment do not have to be specified for every single command.
These sessions store that persistent settings across multiple executions and can even resolve relative paths.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hivessh",
"version": "0.3.9",
"version": "0.3.10",
"description": "HiveSsh simplifies SSH2 connections via promise-based task execution on Linux servers with built-in server utilities and powerful command execution functions",
"main": "dist/index.js",
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion src/SshHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ExecSession } from "./ExecSession.js"
import { handleHops } from "./HostHop.js"
import { CmdChannelOptions, CmdExecOptions, SshChannel, SshChannelExit, execSshChannel } from "./SshExec.js"
import { SshHostOptions, SshHostSettings, loadSettings } from "./SshHostOptions.js"
import { AbstractPackageManager, getApm } from "./apm/Apm.js"
import { AbstractPackageManager, getApm } from "./apm/apm.js"
import { OsRelease, fetchOsRelease } from "./essentials/OsRelease.js"
import { SFTPPromiseWrapper, createSFTPPromiseWrapper } from "./essentials/SftpPromiseWrapper.js"
import { Awaitable, trimAll } from "./utils/base.js"
Expand Down
71 changes: 0 additions & 71 deletions src/apm/Apm.ts → src/apm/Wrapper.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { SshHost } from "../SshHost.js"
import { Awaitable } from "../utils/base.js"
import { AbstractPackage, AbstractPackageManager } from "./ApmInterface.js"
import { initAptApm } from "./apt.js"
import { initDnfApm } from "./dnf.js"
import { initYumApm } from "./yum.js"
export { AbstractPackage, AbstractPackageManager } from "./ApmInterface.js"

export class AbstractPackageManagerWrapper {
type: string
Expand Down Expand Up @@ -220,70 +216,3 @@ export class AbstractPackageManagerWrapper {
return this.apm.describe(pkg)
}
}

export type ApmInit = (
sshHost: SshHost
) => Awaitable<AbstractPackageManager>

export type ApmChecker = (
sshHost: SshHost,
) => Awaitable<AbstractPackageManager | undefined | void>

export const apmChecker: ApmChecker[] = []

export async function getApm(
sshHost: SshHost
): Promise<AbstractPackageManagerWrapper> {
for (const apmCheck of apmChecker) {
const apm = await apmCheck(
sshHost,
)
if (apm) {
return new AbstractPackageManagerWrapper(
apm
)
}
}

throw new Error(
"No package manager found for:\n" +
" " + sshHost.settings.user + "@" +
sshHost.settings.host + ":" + sshHost.settings.port
)
}

export function registerDefaultApmMapperChecker(): void {
apmChecker.push(
async (sshHost) => {
if (
await sshHost.cmdExists("apt") &&
await sshHost.cmdExists("apt-get")
) {
return initAptApm(sshHost)
}
}
)

apmChecker.push(
async (sshHost) => {
if (
await sshHost.cmdExists("dnf")
) {
return initDnfApm(sshHost)
}
}
)

apmChecker.push(
async (sshHost) => {
if (
await sshHost.cmdExists("yum")
) {
return initYumApm(sshHost)
}
}
)
}

registerDefaultApmMapperChecker()

4 changes: 4 additions & 0 deletions src/apm/apm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { AbstractPackage, AbstractPackageManager } from "./ApmInterface.js"
export { AbstractPackageManagerWrapper } from "./Wrapper.js"
export { ApmChecker, ApmInit, apmChecker, getApm, registerDefaultApmMapperChecker } from "./checker.js"

2 changes: 1 addition & 1 deletion src/apm/apt.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SshChannelExit, StreamDataMapper } from "../SshExec.js"
import { SshHost } from "../SshHost.js"
import { Awaitable, trimAll } from "../utils/base.js"
import { AbstractPackage, AbstractPackageManager, ApmInit } from "./Apm.js"
import { AbstractPackage, AbstractPackageManager, ApmInit } from "./apm.js"

export const aptEnv = {
"LANG": "en_US.UTF-8",
Expand Down
74 changes: 74 additions & 0 deletions src/apm/checker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { SshHost } from "../SshHost.js"
import { Awaitable } from "../utils/base.js"
import { AbstractPackageManager } from "./ApmInterface.js"
import { AbstractPackageManagerWrapper } from "./apm.js"
import { initAptApm } from "./apt.js"
import { initDnfApm } from "./dnf.js"
import { initYumApm } from "./yum.js"

export type ApmInit = (
sshHost: SshHost
) => Awaitable<AbstractPackageManager>

export type ApmChecker = (
sshHost: SshHost,
) => Awaitable<AbstractPackageManager | undefined | void>

export const apmChecker: ApmChecker[] = []

export async function getApm(
sshHost: SshHost
): Promise<AbstractPackageManagerWrapper> {
for (const apmCheck of apmChecker) {
const apm = await apmCheck(
sshHost,
)
if (apm) {
return new AbstractPackageManagerWrapper(
apm
)
}
}

throw new Error(
"No package manager found for:\n" +
" " + sshHost.settings.user + "@" +
sshHost.settings.host + ":" + sshHost.settings.port
)
}

export function registerDefaultApmMapperChecker(): void {
apmChecker.push(
async (sshHost) => {
if (
await sshHost.cmdExists("apt") &&
await sshHost.cmdExists("apt-get")
) {
return initAptApm(sshHost)
}
}
)

apmChecker.push(
async (sshHost) => {
if (
await sshHost.cmdExists("dnf")
) {
return initDnfApm(sshHost)
}
}
)

apmChecker.push(
async (sshHost) => {
if (
await sshHost.cmdExists("yum")
) {
return initYumApm(sshHost)
}
}
)
}

registerDefaultApmMapperChecker()

2 changes: 1 addition & 1 deletion src/apm/dnf.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SshChannelExit, StreamDataMapper } from "../SshExec.js"
import { SshHost } from "../SshHost.js"
import { Awaitable, filterEmpty } from "../utils/base.js"
import { AbstractPackage, AbstractPackageManager, ApmInit } from "./Apm.js"
import { AbstractPackage, AbstractPackageManager, ApmInit } from "./apm.js"

export const dnfEnv = {
LANG: "en_US.UTF-8"
Expand Down
2 changes: 1 addition & 1 deletion src/apm/yum.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SshChannelExit, StreamDataMapper } from "../SshExec.js"
import { SshHost } from "../SshHost.js"
import { Awaitable, filterEmpty } from "../utils/base.js"
import { AbstractPackage, AbstractPackageManager, ApmInit } from "./Apm.js"
import { AbstractPackage, AbstractPackageManager, ApmInit } from "./apm.js"

export const yumEnv = {
LANG: "en_US.UTF-8"
Expand Down
9 changes: 1 addition & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,11 @@ export * from "./HostId.js"
export * from "./SshExec.js"
export * from "./SshHost.js"
export * from "./SshHostOptions.js"
export * from "./apm/Apm.js"
export * from "./apm/apm.js"
export * from "./essentials/SftpPromiseWrapper.js"

export * from "./utils/base.js"

import { SshHost } from "./SshHost.js"

export default SshHost

// const host: SshHost = undefined as any

// const apm = await host.getApm()

// await apm.clearCache()

0 comments on commit 410a06a

Please sign in to comment.