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

New module: SSH client #115

Open
runsisi opened this issue Nov 23, 2023 · 8 comments
Open

New module: SSH client #115

runsisi opened this issue Nov 23, 2023 · 8 comments
Labels
enhancement New feature or request

Comments

@runsisi
Copy link
Contributor

runsisi commented Nov 23, 2023

i think ssh support is a must for devops, it is possible for risor?

thank you for your amazing work :)

@myzie
Copy link
Collaborator

myzie commented Dec 7, 2023

Hi @runsisi, probably so. I would guess you're most interested in having Risor be an SSH client, right?

Looks like we should just be able to wrap golang.org/x/crypto/ssh.

Any chance you want to take a stab at the implementation? I could provide guidance as needed :-)

@luisdavim
Copy link
Contributor

I can look into this, if no one else is, @runsisi do you have any specific use cases in mind?

@runsisi
Copy link
Contributor Author

runsisi commented Jan 19, 2024

hi @myzie i'm so sorry for delayed response, really busy these days :(

hi @luisdavim , my use case is simple enough:

  1. connect to remote node
  2. scp local file/directory to remote node (for directory copy then something like os: add CopyFS golang/go#62484 ?)
  3. run command on remote node and get stdout/stderr output (maybe in real time)
  4. with context support, e.g., cancel/timeout, would be better :)

something like the code snippet:

scp

import "github.com/bramvdbogaerde/go-scp"

func ScpFile(ctx context.Context, sshc *ssh.Client, r io.Reader, p string, perm os.FileMode) error {
	scpc, err := scp.NewClientBySSH(sshc)
	if err != nil {
		return errors.New(err)
	}
	defer scpc.Close()

	if err := scpc.CopyFile(ctx, r, p, "0"+strconv.FormatUint(uint64(perm), 8)); err != nil {
		return errors.New(err)
	}
	return nil
}

func ScpContent(ctx context.Context, sshc *ssh.Client, r io.Reader, p string, perm os.FileMode, len int) error {
	scpc, err := scp.NewClientBySSH(sshc)
	if err != nil {
		return errors.New(err)
	}
	defer scpc.Close()

	if err := scpc.Copy(ctx, r, p, "0"+strconv.FormatUint(uint64(perm), 8), int64(len)); err != nil {
		return errors.New(err)
	}
	return nil
}

run command

func SshRunCommand(sshc *ssh.Client, cmdline string, out io.Writer) (string, string, error) {
	sess, err := sshc.NewSession()
	if err != nil {
		return "", "", errors.New(err)
	}
	defer sess.Close()

	if out == nil {
		out = io.Discard
	}

	sob := &bytes.Buffer{}
	seb := &bytes.Buffer{}

	var sow io.Writer = sob
	var sew io.Writer = seb

	if out != nil {
		sw := &singleWriter{
			w: out,
		}

		sow = io.MultiWriter(sob, sw)
		sew = io.MultiWriter(seb, sw)
	}

	sess.Stdout = sow
	sess.Stderr = sew

	if err := sess.Start(cmdline); err != nil {
		return "", "", errors.New(err)
	}
	if err := sess.Wait(); err != nil {
		return "", "", errors.New(err)
	}

	return strings.TrimSpace(sob.String()), strings.TrimSpace(sob.String()), nil
}

@roopeshsn
Copy link

Hi! I am using Risor for myself and would like to work on this issue.

@myzie
Copy link
Collaborator

myzie commented Feb 19, 2024

Hi @roopeshsn, to my knowledge no one has started on this yet. Go ahead and take a stab at it and I'm sure a couple of us will help with reviews.

It seems like the main two cases are 1) an scp like command and 2) running a command remotely via SSH.

@roopeshsn
Copy link

Hi @roopeshsn, to my knowledge no one has started on this yet. Go ahead and take a stab at it and I'm sure a couple of us will help with reviews.

It seems like the main two cases are 1) an scp like command and 2) running a command remotely via SSH.

Thanks! I'll take a look at the code and reach back for queries.

@myzie myzie added the enhancement New feature or request label Feb 29, 2024
@myzie myzie changed the title [feature request] is it possible to add ssh support? New module: SSH client Feb 29, 2024
@roopeshsn
Copy link

Hi @myzie! For SCP, there is a package called go-scp. It depends on crypto/ssh for copying files. From the discussions, what I understood was that in addition to implementing SCP, we need the crypto/ssh package to be implemented in Risor for other tasks, right?

@myzie
Copy link
Collaborator

myzie commented Mar 5, 2024

It's ok to depend on another library. When we do that, it needs to be a Risor module that has its own go.mod file. For example this would make it like the K8s module.

https://github.com/risor-io/risor/blob/main/modules/kubernetes/go.mod

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants