mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 00c2ab9fc4 | |||
| 81294820c8 | |||
| bb8f5dc660 | |||
| c3917444a2 | |||
| 2cc86f39d6 | |||
| af22fd38af |
@@ -1,30 +0,0 @@
|
||||
name: Publish a new release
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
env:
|
||||
NODE_VERSION: "21.5.0"
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: ${{env.NODE_VERSION}}
|
||||
cache: "yarn"
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
VERSION=$(node -e 'console.log(require("./version.js"))')
|
||||
echo "WAVETERM_VERSION=${VERSION}" >> "$GITHUB_OUTPUT"
|
||||
- name: Download staged artifacts
|
||||
run: |
|
||||
. ./buildres/download-staged-artifacts.sh
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: "${{ secrets.S3_USERID }}"
|
||||
AWS_SECRET_ACCESS_KEY: "${{ secrets.S3_SECRETKEY }}"
|
||||
AWS_DEFAULT_REGION: us-west-2
|
||||
- name: Generate Flatpak manifest
|
||||
run: node buildres/flatpak/generate-flatpak-manifest.js
|
||||
@@ -1,116 +0,0 @@
|
||||
app-id: com.visualstudio.code
|
||||
default-branch: stable
|
||||
runtime: org.freedesktop.Sdk
|
||||
runtime-version: '23.08'
|
||||
sdk: org.freedesktop.Sdk
|
||||
base: org.electronjs.Electron2.BaseApp
|
||||
base-version: '23.08'
|
||||
command: code
|
||||
tags: [proprietary]
|
||||
separate-locales: false
|
||||
finish-args:
|
||||
- --require-version=0.10.3
|
||||
- --share=network
|
||||
- --share=ipc
|
||||
- --socket=x11
|
||||
- --socket=pulseaudio
|
||||
- --socket=ssh-auth
|
||||
- --device=all
|
||||
- --allow=devel
|
||||
- --filesystem=host
|
||||
- --env=NPM_CONFIG_GLOBALCONFIG=/app/etc/npmrc
|
||||
- --env=LD_LIBRARY_PATH=/app/lib
|
||||
# required to fix cursor scaling on wayland
|
||||
- --env=XCURSOR_PATH=/run/host/user-share/icons:/run/host/share/icons
|
||||
- --system-talk-name=org.freedesktop.login1
|
||||
- --talk-name=org.freedesktop.Notifications
|
||||
- --talk-name=org.freedesktop.secrets
|
||||
- --talk-name=org.freedesktop.Flatpak
|
||||
- --talk-name=com.canonical.AppMenu.Registrar
|
||||
- --talk-name=com.canonical.AppMenu.Registrar.*
|
||||
add-extensions:
|
||||
com.visualstudio.code.tool:
|
||||
directory: tools
|
||||
subdirectories: true
|
||||
version: '23.08'
|
||||
add-ld-path: lib
|
||||
no-autodownload: true
|
||||
cleanup:
|
||||
- /include
|
||||
- /lib/pkgconfig
|
||||
- /share/gtk-doc
|
||||
- '*.la'
|
||||
modules:
|
||||
- shared-modules/libusb/libusb.json
|
||||
|
||||
- name: vscode
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- install -D code.sh /app/bin/code
|
||||
- install -Dm644 vscode_64.png /app/share/icons/hicolor/64x64/apps/com.visualstudio.code.png
|
||||
- install -Dm644 vscode_128.png /app/share/icons/hicolor/128x128/apps/com.visualstudio.code.png
|
||||
- install -Dm644 vscode_256.png /app/share/icons/hicolor/256x256/apps/com.visualstudio.code.png
|
||||
- install -Dm644 vscode_512.png /app/share/icons/hicolor/512x512/apps/com.visualstudio.code.png
|
||||
- install -Dm644 com.visualstudio.code.metainfo.xml -t /app/share/metainfo
|
||||
- install -Dm644 com.visualstudio.code.desktop -t /app/share/applications
|
||||
- install -Dm644 com.visualstudio.code-url-handler.desktop -t /app/share/applications
|
||||
- install -Dm644 com.visualstudio.code-workspace.xml -t /app/share/mime/packages
|
||||
- install -Dm644 npmrc -t /app/etc
|
||||
- install -Dm644 flatpak-warning.txt -t /app/share/vscode
|
||||
- install -D apply_extra -t /app/bin
|
||||
- cp /usr/bin/ar /app/bin
|
||||
- ARCH_TRIPLE=$(gcc --print-multiarch) && cp /usr/lib/${ARCH_TRIPLE}/libbfd-*.so
|
||||
/app/lib
|
||||
- ARCH_TRIPLE=$(gcc --print-multiarch) && ln -s /usr/lib/${ARCH_TRIPLE}/libtinfo.so/app/lib/libtinfo.so.5
|
||||
- mkdir /app/tools
|
||||
sources:
|
||||
- type: script
|
||||
dest-filename: apply_extra
|
||||
commands:
|
||||
- ar x code.deb
|
||||
- tar xf data.tar.xz
|
||||
- mv usr/share/code vscode
|
||||
- rm -r code.deb control.tar.* data.tar.xz debian-binary usr
|
||||
- type: file
|
||||
path: code.sh
|
||||
- type: file
|
||||
path: flatpak-warning.txt
|
||||
- type: file
|
||||
path: npmrc
|
||||
- type: file
|
||||
path: com.visualstudio.code.metainfo.xml
|
||||
- type: file
|
||||
path: com.visualstudio.code.desktop
|
||||
- type: file
|
||||
path: com.visualstudio.code-url-handler.desktop
|
||||
- type: file
|
||||
path: com.visualstudio.code-workspace.xml
|
||||
- type: file
|
||||
path: icons/vscode_64.png
|
||||
- type: file
|
||||
path: icons/vscode_128.png
|
||||
- type: file
|
||||
path: icons/vscode_256.png
|
||||
- type: file
|
||||
path: icons/vscode_512.png
|
||||
- type: extra-data
|
||||
filename: code.deb
|
||||
only-arches: [x86_64]
|
||||
url: <to-replace>
|
||||
sha256: <to-replace>
|
||||
size: <to-replace>
|
||||
x-checker-data:
|
||||
type: electron-updater
|
||||
url: https://dl.waveterm.dev/releases/latest-linux.yml
|
||||
is-main-source: true
|
||||
|
||||
- name: host-spawn
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- install -Dm755 host-spawn /app/bin/host-spawn
|
||||
sources:
|
||||
- type: file
|
||||
url: https://github.com/1player/host-spawn/releases/download/1.5.0/host-spawn-x86_64
|
||||
sha256: dbf67e7e111c4fe1edb0c642cbb4193064ca5b384aeb1054fc2befba6ed88b83
|
||||
dest-filename: host-spawn
|
||||
only-arches: [x86_64]
|
||||
@@ -1,16 +0,0 @@
|
||||
// Updates the Flatpak manifest with the latest values for the staged artifact
|
||||
// Usage: node generate-flatpak-manifest.js <path-to-staging-directory>
|
||||
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const yaml = require("yaml");
|
||||
|
||||
async function generateFlatpakManifest(stagingDir) {
|
||||
const latestYmlPath = path.join(stagingDir, "latest-linux.yml");
|
||||
const latestYml = yaml.parse(fs.readFileSync(latestYmlPath, "utf8"));
|
||||
const manifestPath = path.join(stagingDir, "dev.commandline.waveterm.yml");
|
||||
const manifestYml = yaml.parse(fs.readFileSync(manifestPath, "utf8"));
|
||||
const latestDeb = latestYml.files.find((file) => file.url.endsWith(".deb"));
|
||||
const latestDebUrl = `https://dl.waveterm.dev/releases/${latestDeb.url}`;
|
||||
const latestDebSha512 = latestDeb.sha512;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from "react";
|
||||
import { GlobalModel } from "@/models";
|
||||
import { Choose, When, If } from "tsx-control-statements/components";
|
||||
import { Modal, PasswordField, Markdown, Checkbox } from "@/elements";
|
||||
import { Modal, PasswordField, TextField, Markdown, Checkbox } from "@/elements";
|
||||
import { checkKeyPressed, adaptFromReactOrNativeKeyEvent } from "@/util/keyutil";
|
||||
|
||||
import "./userinput.less";
|
||||
@@ -82,8 +82,17 @@ export const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
</If>
|
||||
<If condition={!userInputRequest.markdown}>{userInputRequest.querytext}</If>
|
||||
</div>
|
||||
<Choose>
|
||||
<When condition={userInputRequest.responsetype == "text"}>
|
||||
<If condition={userInputRequest.responsetype == "text"}>
|
||||
<If condition={userInputRequest.publictext}>
|
||||
<TextField
|
||||
onChange={setResponseText}
|
||||
value={responseText}
|
||||
maxLength={400}
|
||||
autoFocus={true}
|
||||
onKeyDown={(e) => handleTextKeyDown(e)}
|
||||
/>
|
||||
</If>
|
||||
<If condition={!userInputRequest.publictext}>
|
||||
<PasswordField
|
||||
onChange={setResponseText}
|
||||
value={responseText}
|
||||
@@ -91,8 +100,8 @@ export const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
autoFocus={true}
|
||||
onKeyDown={(e) => handleTextKeyDown(e)}
|
||||
/>
|
||||
</When>
|
||||
</Choose>
|
||||
</If>
|
||||
</If>
|
||||
</div>
|
||||
<If condition={userInputRequest.checkboxmsg != ""}>
|
||||
<Checkbox
|
||||
|
||||
Vendored
+1
@@ -667,6 +667,7 @@ declare global {
|
||||
markdown: boolean;
|
||||
timeoutms: number;
|
||||
checkboxmsg: string;
|
||||
publictext: boolean;
|
||||
};
|
||||
|
||||
type UserInputResponsePacket = {
|
||||
|
||||
@@ -126,7 +126,7 @@ var SetVarScopes = []SetVarScope{
|
||||
{ScopeName: "remote", VarNames: []string{}},
|
||||
}
|
||||
|
||||
var userHostRe = regexp.MustCompile(`^(sudo@)?([a-zA-Z0-9][a-zA-Z0-9._@\\-]*)@([a-z0-9][a-z0-9.-]*)(?::([0-9]+))?$`)
|
||||
var userHostRe = regexp.MustCompile(`^(sudo@)?([a-zA-Z0-9][a-zA-Z0-9._@\\-]*@)?([a-z0-9][a-z0-9.-]*)(?::([0-9]+))?$`)
|
||||
var remoteAliasRe = regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9._-]*$")
|
||||
var genericNameRe = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9_ .()<>,/\"'\\[\\]{}=+$@!*-]*$")
|
||||
var rendererRe = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9_.:-]*$")
|
||||
@@ -1796,6 +1796,7 @@ func parseRemoteEditArgs(isNew bool, pk *scpacket.FeCommandPacketType, isLocal b
|
||||
return nil, fmt.Errorf("invalid format of user@host argument")
|
||||
}
|
||||
sudoStr, remoteUser, remoteHost, remotePortStr := m[1], m[2], m[3], m[4]
|
||||
remoteUser = strings.Trim(remoteUser, "@")
|
||||
var uhPort int
|
||||
if remotePortStr != "" {
|
||||
var err error
|
||||
@@ -1837,7 +1838,11 @@ func parseRemoteEditArgs(isNew bool, pk *scpacket.FeCommandPacketType, isLocal b
|
||||
return nil, fmt.Errorf("invalid port argument, \"%d\" is not in the range of 1 to 65535", portVal)
|
||||
}
|
||||
sshOpts.SSHPort = portVal
|
||||
canonicalName = remoteUser + "@" + remoteHost
|
||||
if remoteUser == "" {
|
||||
canonicalName = remoteHost
|
||||
} else {
|
||||
canonicalName = remoteUser + "@" + remoteHost
|
||||
}
|
||||
if portVal != 0 && portVal != 22 {
|
||||
canonicalName = canonicalName + ":" + strconv.Itoa(portVal)
|
||||
}
|
||||
@@ -2136,17 +2141,17 @@ func createSshImportSummary(changeList map[string][]string) string {
|
||||
|
||||
func NewHostInfo(hostName string) (*HostInfoType, error) {
|
||||
userName, _ := ssh_config.GetStrict(hostName, "User")
|
||||
if userName == "" {
|
||||
// we cannot store a remote with a missing user
|
||||
// in the current setup
|
||||
return nil, fmt.Errorf("could not parse \"%s\" - no User in config\n", hostName)
|
||||
var canonicalName string
|
||||
if userName != "" {
|
||||
canonicalName = userName + "@" + hostName
|
||||
} else {
|
||||
canonicalName = hostName
|
||||
}
|
||||
canonicalName := userName + "@" + hostName
|
||||
|
||||
// check if user and host are okay
|
||||
// check if canonicalname is okay
|
||||
m := userHostRe.FindStringSubmatch(canonicalName)
|
||||
if m == nil || m[2] == "" || m[3] == "" {
|
||||
return nil, fmt.Errorf("could not parse \"%s\" - %s did not fit user@host requirement\n", hostName, canonicalName)
|
||||
if m == nil {
|
||||
return nil, fmt.Errorf("could not parse \"%s\" - %s did not fit user@host requirement", hostName, canonicalName)
|
||||
}
|
||||
|
||||
portStr, _ := ssh_config.GetStrict(hostName, "Port")
|
||||
@@ -2157,10 +2162,10 @@ func NewHostInfo(hostName string) (*HostInfoType, error) {
|
||||
portVal, err = strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
// do not make assumptions about port if incorrectly configured
|
||||
return nil, fmt.Errorf("could not parse \"%s\" (%s) - %s could not be converted to a valid port\n", hostName, canonicalName, portStr)
|
||||
return nil, fmt.Errorf("could not parse \"%s\" (%s) - %s could not be converted to a valid port", hostName, canonicalName, portStr)
|
||||
}
|
||||
if portVal <= 0 || portVal > 65535 {
|
||||
return nil, fmt.Errorf("could not parse port \"%d\": number is not valid for a port\n", portVal)
|
||||
return nil, fmt.Errorf("could not parse port \"%d\": number is not valid for a port", portVal)
|
||||
}
|
||||
}
|
||||
identityFile, _ := ssh_config.GetStrict(hostName, "IdentityFile")
|
||||
|
||||
+20
-167
@@ -15,6 +15,7 @@ import (
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -44,8 +45,6 @@ import (
|
||||
"golang.org/x/mod/semver"
|
||||
)
|
||||
|
||||
const UseSshLibrary = true
|
||||
|
||||
const RemoteTypeMShell = "mshell"
|
||||
const DefaultTerm = "xterm-256color"
|
||||
const DefaultMaxPtySize = 1024 * 1024
|
||||
@@ -129,12 +128,6 @@ type pendingStateKey struct {
|
||||
RemotePtr sstore.RemotePtrType
|
||||
}
|
||||
|
||||
// for conditional launch method based on ssh library in use
|
||||
// remove once ssh library is stabilized
|
||||
type Launcher interface {
|
||||
Launch(*MShellProc, bool)
|
||||
}
|
||||
|
||||
type MShellProc struct {
|
||||
Lock *sync.Mutex
|
||||
Remote *sstore.RemoteType
|
||||
@@ -163,7 +156,6 @@ type MShellProc struct {
|
||||
|
||||
RunningCmds map[base.CommandKey]*RunCmdType
|
||||
PendingStateCmds map[pendingStateKey]base.CommandKey // key=[remoteinstance name]
|
||||
launcher Launcher // for conditional launch method based on ssh library in use. remove once ssh library is stabilized
|
||||
Client *ssh.Client
|
||||
}
|
||||
|
||||
@@ -188,12 +180,6 @@ func CanComplete(remoteType string) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// for conditional launch method based on ssh library in use
|
||||
// remove once ssh library is stabilized
|
||||
func (msh *MShellProc) Launch(interactive bool) {
|
||||
msh.launcher.Launch(msh, interactive)
|
||||
}
|
||||
|
||||
func (msh *MShellProc) GetStatus() string {
|
||||
msh.Lock.Lock()
|
||||
defer msh.Lock.Unlock()
|
||||
@@ -711,14 +697,8 @@ func MakeMShell(r *sstore.RemoteType) *MShellProc {
|
||||
RunningCmds: make(map[base.CommandKey]*RunCmdType),
|
||||
PendingStateCmds: make(map[pendingStateKey]base.CommandKey),
|
||||
StateMap: server.MakeShellStateMap(),
|
||||
launcher: LegacyLauncher{}, // for conditional launch method based on ssh library in use. remove once ssh library is stabilized
|
||||
DataPosMap: utilfn.MakeSyncMap[base.CommandKey, int64](),
|
||||
}
|
||||
// for conditional launch method based on ssh library in use
|
||||
// remove once ssh library is stabilized
|
||||
if UseSshLibrary {
|
||||
rtn.launcher = NewLauncher{}
|
||||
}
|
||||
|
||||
rtn.WriteToPtyBuffer("console for connection [%s]\n", r.GetName())
|
||||
return rtn
|
||||
@@ -1201,6 +1181,15 @@ func (msh *MShellProc) WaitAndSendPassword(pw string) {
|
||||
}
|
||||
|
||||
func (msh *MShellProc) RunInstall(autoInstall bool) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
errMsg := fmt.Errorf("this should not happen. if it does, please reach out to us in our discord or open an issue on our github\n\n"+
|
||||
"error:\n%v\n\nstack trace:\n%s", r, string(debug.Stack()))
|
||||
log.Printf("fatal error, %s\n", errMsg)
|
||||
msh.WriteToPtyBuffer("*fatal error, %s\n", errMsg)
|
||||
msh.setErrorStatus(errMsg)
|
||||
}
|
||||
}()
|
||||
remoteCopy := msh.GetRemoteCopy()
|
||||
if remoteCopy.Archived {
|
||||
msh.WriteToPtyBuffer("*error: cannot install on archived remote\n")
|
||||
@@ -1574,12 +1563,16 @@ func (msh *MShellProc) createWaveshellSession(clientCtx context.Context, remoteC
|
||||
return wsSession, nil
|
||||
}
|
||||
|
||||
// for conditional launch method based on ssh library in use
|
||||
// remove once ssh library is stabilized
|
||||
type NewLauncher struct{}
|
||||
|
||||
// func (msh *MShellProc) LaunchNew(interactive bool) {
|
||||
func (NewLauncher) Launch(msh *MShellProc, interactive bool) {
|
||||
func (msh *MShellProc) Launch(interactive bool) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
errMsg := fmt.Errorf("this should not happen. if it does, please reach out to us in our discord or open an issue on our github\n\n"+
|
||||
"error:\n%v\n\nstack trace:\n%s", r, string(debug.Stack()))
|
||||
log.Printf("fatal error, %s\n", errMsg)
|
||||
msh.WriteToPtyBuffer("*fatal error, %s\n", errMsg)
|
||||
msh.setErrorStatus(errMsg)
|
||||
}
|
||||
}()
|
||||
remoteCopy := msh.GetRemoteCopy()
|
||||
if remoteCopy.Archived {
|
||||
msh.WriteToPtyBuffer("cannot launch archived remote\n")
|
||||
@@ -1687,146 +1680,6 @@ func (NewLauncher) Launch(msh *MShellProc, interactive bool) {
|
||||
go msh.NotifyRemoteUpdate()
|
||||
}
|
||||
|
||||
// for conditional launch method based on ssh library in use
|
||||
// remove once ssh library is stabilized
|
||||
type LegacyLauncher struct{}
|
||||
|
||||
// func (msh *MShellProc) LaunchLegacy(interactive bool) {
|
||||
func (LegacyLauncher) Launch(msh *MShellProc, interactive bool) {
|
||||
remoteCopy := msh.GetRemoteCopy()
|
||||
if remoteCopy.Archived {
|
||||
msh.WriteToPtyBuffer("cannot launch archived remote\n")
|
||||
return
|
||||
}
|
||||
curStatus := msh.GetStatus()
|
||||
if curStatus == StatusConnected {
|
||||
msh.WriteToPtyBuffer("remote is already connected (no action taken)\n")
|
||||
return
|
||||
}
|
||||
if curStatus == StatusConnecting {
|
||||
msh.WriteToPtyBuffer("remote is already connecting, disconnect before trying to connect again\n")
|
||||
return
|
||||
}
|
||||
sapi, err := shellapi.MakeShellApi(msh.GetShellType())
|
||||
if err != nil {
|
||||
msh.WriteToPtyBuffer("*error, %v\n", err)
|
||||
return
|
||||
}
|
||||
istatus := msh.GetInstallStatus()
|
||||
if istatus == StatusConnecting {
|
||||
msh.WriteToPtyBuffer("remote is trying to install, cancel install before trying to connect again\n")
|
||||
return
|
||||
}
|
||||
if remoteCopy.SSHOpts.SSHPort != 0 && remoteCopy.SSHOpts.SSHPort != 22 {
|
||||
msh.WriteToPtyBuffer("connecting to %s (port %d)...\n", remoteCopy.RemoteCanonicalName, remoteCopy.SSHOpts.SSHPort)
|
||||
} else {
|
||||
msh.WriteToPtyBuffer("connecting to %s...\n", remoteCopy.RemoteCanonicalName)
|
||||
}
|
||||
sshOpts := convertSSHOpts(remoteCopy.SSHOpts)
|
||||
sshOpts.SSHErrorsToTty = true
|
||||
if remoteCopy.ConnectMode != sstore.ConnectModeManual && remoteCopy.SSHOpts.SSHPassword == "" && !interactive {
|
||||
sshOpts.BatchMode = true
|
||||
}
|
||||
var cmdStr string
|
||||
if sshOpts.SSHHost == "" && remoteCopy.Local {
|
||||
var err error
|
||||
cmdStr, err = MakeLocalMShellCommandStr(remoteCopy.IsSudo())
|
||||
if err != nil {
|
||||
msh.WriteToPtyBuffer("*error, cannot find local mshell binary: %v\n", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
cmdStr = MakeServerCommandStr()
|
||||
}
|
||||
ecmd := sshOpts.MakeSSHExecCmd(cmdStr, sapi)
|
||||
cmdPty, err := msh.addControllingTty(ecmd)
|
||||
if err != nil {
|
||||
statusErr := fmt.Errorf("cannot attach controlling tty to mshell command: %w", err)
|
||||
msh.WriteToPtyBuffer("*error, %s\n", statusErr.Error())
|
||||
msh.setErrorStatus(statusErr)
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if len(ecmd.ExtraFiles) > 0 {
|
||||
ecmd.ExtraFiles[len(ecmd.ExtraFiles)-1].Close()
|
||||
}
|
||||
}()
|
||||
go msh.RunPtyReadLoop(cmdPty)
|
||||
if remoteCopy.SSHOpts.SSHPassword != "" {
|
||||
go msh.WaitAndSendPassword(remoteCopy.SSHOpts.SSHPassword)
|
||||
}
|
||||
var makeClientCtx context.Context
|
||||
var makeClientCancelFn context.CancelFunc
|
||||
msh.WithLock(func() {
|
||||
deadlineTime := time.Now().Add(RemoteConnectTimeout)
|
||||
makeClientCtx, makeClientCancelFn = context.WithDeadline(context.Background(), deadlineTime)
|
||||
defer makeClientCancelFn()
|
||||
msh.Err = nil
|
||||
msh.ErrNoInitPk = false
|
||||
msh.Status = StatusConnecting
|
||||
msh.MakeClientCancelFn = makeClientCancelFn
|
||||
msh.MakeClientDeadline = &deadlineTime
|
||||
go msh.NotifyRemoteUpdate()
|
||||
})
|
||||
go msh.watchClientDeadlineTime()
|
||||
cproc, err := shexec.MakeClientProc(makeClientCtx, shexec.CmdWrap{Cmd: ecmd})
|
||||
msh.WithLock(func() {
|
||||
msh.MakeClientCancelFn = nil
|
||||
msh.MakeClientDeadline = nil
|
||||
msh.StateMap.Clear()
|
||||
// no notify here, because we'll call notify in either case below
|
||||
})
|
||||
if err == context.DeadlineExceeded {
|
||||
msh.WriteToPtyBuffer("*connect timeout\n")
|
||||
msh.setErrorStatus(errors.New("connect timeout"))
|
||||
return
|
||||
} else if err == context.Canceled {
|
||||
msh.WriteToPtyBuffer("*forced disconnection\n")
|
||||
msh.WithLock(func() {
|
||||
msh.Status = StatusDisconnected
|
||||
go msh.NotifyRemoteUpdate()
|
||||
})
|
||||
return
|
||||
} else if serr, ok := err.(shexec.WaveshellLaunchError); ok {
|
||||
msh.WithLock(func() {
|
||||
msh.UName = serr.InitPk.UName
|
||||
if semver.Compare(serr.InitPk.Version, scbase.MShellVersion) < 0 {
|
||||
// only set NeedsMShellUpgrade if we got an InitPk
|
||||
msh.NeedsMShellUpgrade = true
|
||||
}
|
||||
msh.InitPkShellType = serr.InitPk.Shell
|
||||
})
|
||||
msh.WriteToPtyBuffer("*error, %s\n", serr.Error())
|
||||
msh.setErrorStatus(serr)
|
||||
go msh.tryAutoInstall()
|
||||
return
|
||||
} else if err != nil {
|
||||
msh.WriteToPtyBuffer("*error, %s\n", serr.Error())
|
||||
msh.setErrorStatus(err)
|
||||
return
|
||||
}
|
||||
|
||||
msh.updateRemoteStateVars(context.Background(), msh.RemoteId, cproc.InitPk)
|
||||
msh.WithLock(func() {
|
||||
msh.ServerProc = cproc
|
||||
msh.Status = StatusConnected
|
||||
})
|
||||
go func() {
|
||||
exitErr := cproc.Cmd.Wait()
|
||||
exitCode := shexec.GetExitCode(exitErr)
|
||||
msh.WithLock(func() {
|
||||
if msh.Status == StatusConnected || msh.Status == StatusConnecting {
|
||||
msh.Status = StatusDisconnected
|
||||
go msh.NotifyRemoteUpdate()
|
||||
}
|
||||
})
|
||||
msh.WriteToPtyBuffer("*disconnected exitcode=%d\n", exitCode)
|
||||
}()
|
||||
go msh.ProcessPackets()
|
||||
msh.initActiveShells()
|
||||
go msh.NotifyRemoteUpdate()
|
||||
}
|
||||
|
||||
func (msh *MShellProc) initActiveShells() {
|
||||
ctx, cancelFn := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancelFn()
|
||||
|
||||
@@ -230,6 +230,7 @@ func promptChallengeQuestion(connCtx context.Context, question string, echo bool
|
||||
QueryText: queryText,
|
||||
Markdown: true,
|
||||
Title: "Keyboard Interactive Authentication",
|
||||
PublicText: echo,
|
||||
}
|
||||
response, err := userinput.GetUserInput(ctx, scbus.MainRpcBus, request)
|
||||
if err != nil {
|
||||
|
||||
@@ -22,6 +22,7 @@ type UserInputRequestType struct {
|
||||
Markdown bool `json:"markdown"`
|
||||
TimeoutMs int `json:"timeoutms"`
|
||||
CheckBoxMsg string `json:"checkboxmsg"`
|
||||
PublicText bool `json:"publictext"`
|
||||
}
|
||||
|
||||
func (*UserInputRequestType) GetType() string {
|
||||
|
||||
Reference in New Issue
Block a user