Giter Club home page Giter Club logo

go-dockerpty's Introduction

go-dockerpty

Provides the functionality needed to operate the pseudo-tty (PTY) allocated to a docker container, using the Go client.

Inspired by https://github.com/d11wtq/dockerpty

⚠️ Unmaintained ⚠️

Project is no longer being maintained and has been archived.

Usage

This package provides two functions: dockerpty.Start and dockerpty.StartExec.

The following example will run Busybox in a docker container and place the user at the shell prompt via Go. It is the same as running docker run -ti --rm busybox /bin/sh.

This obviously only works when run in a terminal.

package main

import (
	"fmt"
	"github.com/fgrehm/go-dockerpty"
	"github.com/fsouza/go-dockerclient"
	"os"
)

func main() {
	endpoint := "unix:///var/run/docker.sock"
	client, _ := docker.NewClient(endpoint)

	// Create container
	container, err := client.CreateContainer(docker.CreateContainerOptions{
		Config: &docker.Config{
			Image:        "busybox",
			Cmd:          []string{"/bin/sh"},
			OpenStdin:    true,
			StdinOnce:    true,
			AttachStdin:  true,
			AttachStdout: true,
			AttachStderr: true,
			Tty:          true,
		},
	})

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Cleanup when done
	defer func() {
		client.RemoveContainer(docker.RemoveContainerOptions{
			ID: container.ID,
			Force: true,
		})
	}()

	// Fire up the console
	if err = dockerpty.Start(client, container, &docker.HostConfig{}); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

The following example will run a "date service" on a Busybox docker container and place the user at the shell prompt via Go. It is the same as running docker exec -ti date-service /bin/sh.

This obviously only works when run in a terminal.

package main

import (
	"fmt"
	"github.com/fgrehm/go-dockerpty"
	"github.com/fsouza/go-dockerclient"
	"os"
)

func main() {
	endpoint := "unix:///var/run/docker.sock"
	client, _ := docker.NewClient(endpoint)

	// Create container
	container, err := client.CreateContainer(docker.CreateContainerOptions{
		Name: "date-service",
		Config: &docker.Config{
			Image: "busybox",
			Cmd:   []string{"/bin/sh", "-c", "while true; do date >> /tmp/date.log; sleep 1; done"},
		},
	})

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Cleanup when done
	defer func() {
		client.RemoveContainer(docker.RemoveContainerOptions{
			ID: container.ID,
			Force: true,
		})
	}()

	err = client.StartContainer(container.ID, &docker.HostConfig{})

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	exec, err := client.CreateExec(docker.CreateExecOptions{
		Container:    container.ID,
		AttachStdin:  true,
		AttachStdout: true,
		AttachStderr: true,
		Tty:          true,
		Cmd:          []string{"/bin/sh"},
	})

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Fire up the console
	if err = dockerpty.StartExec(client, exec); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

When dockerpty.Start or dockerpty.StartExec gets called, control is yielded to the container's PTY until the container exits, or the container's PTY is closed.

This is a safe operation and all resources should be restored back to their original states.

go-dockerpty's People

Contributors

fgrehm avatar hmarr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

go-dockerpty's Issues

Feature request: support for Windows

Thanks for dockerpty, it is really, really helpful for me on OSX.
Now I'd like to use it on Windows, but when I compile for it (env GOOS=windows GOARCH=amd64 go build), I get the following error:

# project/vendor/github.com/fgrehm/go-dockerpty/term
vendor/github.com/fgrehm/go-dockerpty/term/term.go:16: undefined: Termios

since the file is defined for darwin, linux, and freebsd.

What would need to be changed for Windows?

Add feature: support param exec ID

Your repo is great and thanks to your work, I will solve my issue using pty.
But in most cases, we won't create a new docker container and exec in it. Instead, we connect to an existing container. Both act like docker exec.
This is my cases,
Use case 1: zyfdegh/local-docker-exec
Use case 2: zyfdegh/remote-docker-exec

So I think it's better to add a function which support param execId like

dockerpty.Start(client, execID, &docker.HostConfig{});

In my cases, I would call this function like this

    // create exec
    createOpts := docker.CreateExecOptions{}
    createOpts.AttachStdin = true
    createOpts.AttachStdout = true
    createOpts.AttachStderr = true
    createOpts.Tty = true
    createOpts.Cmd = []string{"sh"}
    createOpts.Container = containerId

    exec, err := client.CreateExec(createOpts)
    if err != nil {
        log.Println("create exec error: %v\n", err)
                return
    }
    dockerpty.Start(client, exec.ID, &docker.HostConfig{});

In this way, we can connect to a local or remote docker container.
API reference: https://docs.docker.com/engine/reference/api/docker_remote_api_v1.23/#/exec-create

Cannot pipe stdout

Using the following code:

package main

import (
  "fmt"

  "github.com/fgrehm/go-dockerpty"
  "github.com/fsouza/go-dockerclient"
)

func main() {
  c, err := docker.NewClient("unix:///var/run/docker.sock")
  if err != nil {
    fmt.Printf("Error creating docker client: %v", err)
  }

  container, err := c.CreateContainer(
    docker.CreateContainerOptions{
      Config: &docker.Config{
        Image: "busybox",
        Cmd:   []string{"ifconfig"},
        Tty:   true,
      },
    },
  )
  if err != nil {
    fmt.Printf("Error creating container: %v", err)
  }
  err = dockerpty.Start(c, container, &docker.HostConfig{})
  if err != nil {
    fmt.Printf("Error starting container: %v", err)
  }
}

and executing it:

$ go run main.go 
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
          inet addr:172.17.0.3  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:90 (90.0 B)  TX bytes:90 (90.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

$ go run main.go  | tee /tmp/test.log 
Error starting container: inappropriate ioctl for device

Is there a way to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.