123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- package docker
- import (
- "errors"
- "strings"
- "bitbucket.org/robert2206/automation/modules/settings"
- docker "github.com/fsouza/go-dockerclient"
- )
- var (
- // errorContainerRemove is a dispatched error when container cannot be removed
- errorContainerRemove = errors.New("container cannot be removed")
- // errorContainerNotFound is a error dispatched when container cannot be found
- errorContainerNotFound = errors.New("container cannot be found")
- )
- // Image represent a docker image
- type Image struct {
- ID string
- Tag string
- Size int64
- }
- // Network represent a network ip used by docker
- type Network struct {
- ID string
- IP string
- }
- // Port represent a port user by docker container
- type Port struct {
- IP string
- Type string
- PublicPort int64
- PrivatePort int64
- }
- // Container represent docker container
- type Container struct {
- ID string
- Name string
- Image string
- State string
- Ports []*Port
- Networks map[string]*Network
- }
- // Create a container
- func Create(name string, image string) (*Container, error) {
- cli, err := getDockerClient()
- if err != nil {
- return nil, err
- }
- ctr, err := cli.CreateContainer(docker.CreateContainerOptions{
- Name: name,
- Config: &docker.Config{
- Image: image,
- Memory: 102400,
- MemorySwap: 102400,
- },
- })
- if err != nil {
- return nil, err
- }
- return &Container{
- ID: ctr.ID,
- Name: ctr.Name,
- Image: ctr.Image,
- State: ctr.State.Status,
- }, nil
- }
- // Remove a container
- func Remove(idOrName string) error {
- cli, err := getDockerClient()
- if err != nil {
- return err
- }
- ctr := GetContainer(idOrName)
- if ctr == nil {
- return errorContainerRemove
- }
- return cli.RemoveContainer(docker.RemoveContainerOptions{
- ID: ctr.ID,
- RemoveVolumes: true,
- })
- }
- // Start container
- func Start(idOrName string) error {
- cli, err := getClientFor(idOrName)
- if err != nil {
- return err
- }
- return cli.StartContainer(idOrName, nil)
- }
- // Restart container
- func Restart(idOrName string) error {
- cli, err := getClientFor(idOrName)
- if err != nil {
- return err
- }
- return cli.RestartContainer(idOrName, 3)
- }
- // Stop container
- func Stop(idOrName string) error {
- cli, err := getClientFor(idOrName)
- if err != nil {
- return err
- }
- return cli.StopContainer(idOrName, 3)
- }
- // GetAllImages returns all docker images
- func GetAllImages() ([]*Image, error) {
- cli, err := getDockerClient()
- if err != nil {
- return nil, err
- }
- imgs, err := cli.ListImages(docker.ListImagesOptions{
- All: true,
- })
- if err != nil {
- return nil, err
- }
- results := make([]*Image, len(imgs))
- for i, img := range imgs {
- results[i] = &Image{
- ID: img.ID,
- Tag: img.RepoTags[0],
- Size: img.Size,
- }
- }
- return results, nil
- }
- // GetAllContainers returns all docker containers
- func GetAllContainers() ([]*Container, error) {
- cli, err := getDockerClient()
- if err != nil {
- return nil, err
- }
- ctrs, err := cli.ListContainers(docker.ListContainersOptions{
- All: true,
- })
- if err != nil {
- return nil, err
- }
- results := make([]*Container, len(ctrs))
- for i, ctr := range ctrs {
- results[i] = &Container{
- ID: ctr.ID,
- Name: ctr.Names[0],
- Image: ctr.Image,
- State: ctr.State,
- Ports: func() []*Port {
- prts := make([]*Port, len(ctr.Ports))
- for j, prt := range ctr.Ports {
- prts[j] = &Port{
- IP: prt.IP,
- Type: prt.Type,
- PublicPort: prt.PublicPort,
- PrivatePort: prt.PrivatePort,
- }
- }
- return prts
- }(),
- Networks: func() map[string]*Network {
- netws := make(map[string]*Network, len(ctr.Networks.Networks))
- for k, netw := range ctr.Networks.Networks {
- netws[k] = &Network{
- ID: netw.NetworkID,
- IP: netw.IPAddress,
- }
- }
- return netws
- }(),
- }
- }
- return results, nil
- }
- // GetContainer return container matched by id or name
- func GetContainer(idOrName string) *Container {
- ctrs, err := GetAllContainers()
- if err != nil {
- return nil
- }
- return func() *Container {
- for _, ctr := range ctrs {
- if ctr.ID == idOrName || ctr.Name == idOrName {
- return ctr
- }
- }
- return nil
- }()
- }
- // GetAllPublicPorts get all public exposed ports
- func GetAllPublicPorts() ([]int64, error) {
- ctrs, err := GetAllContainers()
- if err != nil {
- return nil, err
- }
- return func() []int64 {
- var prts []int64
- for _, ctr := range ctrs {
- for _, ptr := range ctr.Ports {
- prts = append(prts, ptr.PublicPort)
- }
- }
- return prts
- }(), nil
- }
- // GetNetwork get network used by container
- func GetNetwork(idOrName string) (map[string]Network, error) {
- ctr := GetContainer(idOrName)
- if ctr == nil {
- return nil, errorContainerNotFound
- }
- return nil, nil
- }
- // GetPrivateIP get private ip used by container
- func GetPrivateIP(idOrName string) {
- }
- func getClientFor(idOrName string) (*docker.Client, error) {
- err := checkIdOrName(idOrName)
- if err != nil {
- return nil, err
- }
- cli, err := getDockerClient()
- if err != nil {
- return nil, err
- }
- return cli, nil
- }
- func checkIdOrName(idOrName string) error {
- if len(strings.TrimSpace(idOrName)) == 0 {
- return errors.New("container id or name not provided")
- }
- return nil
- }
- func getDockerClient() (*docker.Client, error) {
- endpoint := settings.Ctx.DockerSockDir
- if strings.HasSuffix(endpoint, ".sock") {
- endpoint = strings.Join([]string{"unix:", endpoint}, "/")
- }
- return docker.NewClient(endpoint)
- }
|