diff --git a/Docs/ServerImplementation.md b/Docs/ServerImplementation.md index 0f38281..8e63354 100644 --- a/Docs/ServerImplementation.md +++ b/Docs/ServerImplementation.md @@ -159,6 +159,31 @@ it does not utilize server resources when it is not being used, or the task that To run this function all that is needed is the docker container ID. If the function is successful it returns a string that says success. +### Ports json file +This file will help map internal ports inside a container to external ports inside a container. A common example +would be the SSH port which is port 22 inside the docker container and is mapped to random TCP port outside container +so that any external machines can directly connect into the container. The below representation mentions of where +the ports.json file is located and also the format of that file. +``` +|_ + |_ Dockerfile + |_ description.txt + |_ ports.json // The ports file +``` +Format of the ports.json file +``` +{ + "Port": [ + { + "PortName": "", + "InternalPort": , + "Type": "", + "Description": "" + }, ... n + ] +} +``` + diff --git a/client/container.go b/client/container.go index 3698854..b76508e 100644 --- a/client/container.go +++ b/client/container.go @@ -128,18 +128,18 @@ func ViewContainers(IP string)(*docker.DockerContainers, error){ } // PrintStartContainer Prints results Generated container -func PrintStartContainer(d *docker.DockerVM){ - fmt.Println("ID : " + fmt.Sprint(d.ID)) - fmt.Println("SSH port: " + fmt.Sprint(d.SSHPort)) - fmt.Println("SSH username: " + fmt.Sprint(d.SSHUsername)) - fmt.Println("SSH password: " + fmt.Sprint(d.SSHPassword)) - fmt.Println("VNC port: " + fmt.Sprint(d.VNCPort)) - fmt.Println("VNC password: " + fmt.Sprint(d.VNCPassword)) - fmt.Println("Ports Open (All TCP ports):") - for i := range d.Ports { - fmt.Println(d.Ports[i]) - } -} +//func PrintStartContainer(d *docker.DockerVM){ +// fmt.Println("ID : " + fmt.Sprint(d.ID)) +// fmt.Println("SSH port: " + fmt.Sprint(d.SSHPort)) +// fmt.Println("SSH username: " + fmt.Sprint(d.SSHUsername)) +// fmt.Println("SSH password: " + fmt.Sprint(d.SSHPassword)) +// fmt.Println("VNC port: " + fmt.Sprint(d.VNCPort)) +// fmt.Println("VNC password: " + fmt.Sprint(d.VNCPassword)) +// fmt.Println("Ports Open (All TCP ports):") +// for i := range d.Ports { +// fmt.Println(d.Ports[i]) +// } +//} // TODO implementation using RPC calls diff --git a/main.go b/main.go index 69e850a..2d5718d 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,7 @@ import ( ) // VERSION specifies the version of the platform -var VERSION = "beta-1.0.0" +var VERSION = "1.0.0" var mode string // Varaibles if mode is client diff --git a/server/docker/containers/docker-ubuntu-sshd/ports.json b/server/docker/containers/docker-ubuntu-sshd/ports.json new file mode 100644 index 0000000..fe41888 --- /dev/null +++ b/server/docker/containers/docker-ubuntu-sshd/ports.json @@ -0,0 +1,10 @@ +{ + "Port": [ + { + "PortName": "SSH", + "InternalPort": 22, + "Type": "tcp", + "Description": "SSH Port" + } + ] +} \ No newline at end of file diff --git a/server/docker/containers/ubuntuvnc/Dockerfile b/server/docker/containers/ubuntuvnc/Dockerfile new file mode 100644 index 0000000..d253d87 --- /dev/null +++ b/server/docker/containers/ubuntuvnc/Dockerfile @@ -0,0 +1,61 @@ +# ----------------------------------------------------------------------------- +# This is base image of Ubuntu LTS with SSHD service. +# +# Authors: Art567 +# Updated: Sep 20th, 2015 +# Require: Docker (http://www.docker.io/) +# ----------------------------------------------------------------------------- + + +# Base system is the latest LTS version of Ubuntu. +# from consol/ubuntu-xfce-vnc + +# due to dependency issues vnc is still work in progress +from dorowu/ubuntu-desktop-lxde-vnc + +# Switch to root user to install additional software +USER 0 + + +# Make sure we don't get notifications we can't answer during building. +env DEBIAN_FRONTEND noninteractive + + +# Prepare scripts and configs +add ./scripts/start /start + + +# Download and install everything from the repos. +run apt-get -q -y update; apt-get -q -y upgrade && \ + apt-get -q -y install sudo openssh-server && \ + mkdir /var/run/sshd + + +# Set root password +run echo 'root:password' >> /root/passwdfile + + +# Create user and it's password +run useradd -m -G sudo master && \ + echo 'master:password' >> /root/passwdfile + + +# Apply root password +run chpasswd -c SHA512 < /root/passwdfile && \ + rm /root/passwdfile + + +# Port 22 is used for ssh +expose 22 + + +# Assign /data as static volume. +volume ["/data"] + + +# Fix all permissions +run chmod +x /start + + +# Starting sshd +cmd ["/start"] diff --git a/server/docker/containers/ubuntuvnc/README.md b/server/docker/containers/ubuntuvnc/README.md new file mode 100644 index 0000000..ee62e54 --- /dev/null +++ b/server/docker/containers/ubuntuvnc/README.md @@ -0,0 +1,72 @@ +Ubuntu LTS with SSH (Docker) +========= + +A Docker file to build a [docker.io] base container with Ubuntu LTS and a sshd service +[docker.io]: http://docker.io +Nice and easy way to get any server up and running using docker + + +Instructions +----------- + - Install Docker first. + Read [installation instructions] (http://docs.docker.io/en/latest/installation/). + + + - Clone this repository: + + `$ git clone https://github.com/art567/docker-ubuntu-sshd.git` + + + - Enter local directory: + + `$ cd docker-ubuntu-sshd` + + - Change passwords in Dockerfile: + + `$ vi Dockerfile` + + - Build the container: + + `$ sudo docker build -t art567/ubuntu .` + + + - Run the container: + + `$ sudo docker run -d=true --name=ubuntu --restart=always -p=2222:22 -v=/opt/data:/data art567/ubuntu /start` + + + - Your container will start and bind ssh to 2222 port. + + + - Find your local IP Address: + + `$ ifconfig` + + + - Connect to the SSH server: + + `$ ssh root@ -p 2222` + + + - If you don't want to deal with root: + + `$ ssh master@ -p 2222` + + +**VERY IMPORTANT!!!** +----------- + + **Don't forget to change passwords in Dockerfile before building image!** + + +Versions +----------- +Some branches represents Ubuntu versions. + +Branch `master` is always represented by latest Ubuntu LTS + + For example: + - 12.04 - Ubuntu 12.04 LTS + - 14.04 - Ubuntu 14.04 LTS + - 16.04 - Ubuntu 16.04 LTS + diff --git a/server/docker/containers/ubuntuvnc/description.txt b/server/docker/containers/ubuntuvnc/description.txt new file mode 100644 index 0000000..dc5b3fa --- /dev/null +++ b/server/docker/containers/ubuntuvnc/description.txt @@ -0,0 +1 @@ +Simple Ubuntu 20.04 image \ No newline at end of file diff --git a/server/docker/containers/ubuntuvnc/scripts/start b/server/docker/containers/ubuntuvnc/scripts/start new file mode 100644 index 0000000..5286196 --- /dev/null +++ b/server/docker/containers/ubuntuvnc/scripts/start @@ -0,0 +1,11 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# docker-ubuntu-sshd /start script +# +# Authors: Art567 +# Updated: Sep 20th, 2015 +# ----------------------------------------------------------------------------- + + +# Run OpenSSH server in daemon mode +/usr/sbin/sshd -D diff --git a/server/docker/docker.go b/server/docker/docker.go index 3a69429..7a20ebc 100644 --- a/server/docker/docker.go +++ b/server/docker/docker.go @@ -22,15 +22,12 @@ import ( ) type DockerVM struct { - SSHPort int `json:"SSHPort"` SSHUsername string `json:"SSHUsername"` SSHPassword string `json:"SSHPassword"` - VNCPort int `json:"VNCPort"` - VNCPassword string `json:"VNCPassword"` ID string `json:"ID"` TagName string `json:"TagName"` ImagePath string `json:"ImagePath"` - Ports []int `json:"OpenPorts"` + Ports Ports `json:"Ports"` GPU string `json:"GPU"` } @@ -43,6 +40,17 @@ type DockerContainer struct { ContainerDescription string `json:"ContainerDescription"` } +type Ports struct { + PortSet []Port `json:"Port"` +} +type Port struct { + PortName string `json:"PortName"` + InternalPort int `json:"InternalPort"` + Type string `json:"Type"` + ExternalPort int `json:"ExternalPort"` + Description string `json:"Description"` +} + type ErrorLine struct { Error string `json:"error"` ErrorDetail ErrorDetail `json:"errorDetail"` @@ -54,29 +62,17 @@ type ErrorDetail struct { var dockerRegistryUserID = "" +// BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external +// ports func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerVM,error) { //Docker Struct Variable var RespDocker *DockerVM = new(DockerVM) - // Count: 2 allocated ports for VNC and SSH + other ports - // to open - count := NumPorts + 2 - - // Gets 2 TCP ports empty - Ports, err := freeport.GetFreePorts(count) - if err != nil { - return nil,err - } - - for i := 2; i < count; i++ { - RespDocker.Ports = append(RespDocker.Ports, Ports[i]) - } - // Sets if GPU is selected or not RespDocker.GPU = GPU // Sets Free port to Struct - RespDocker.SSHPort = Ports[0] + //RespDocker.SSHPort = Ports[0] //RespDocker.VNCPort = Ports[1] // Sets appropriate username and password to the // variables in the struct @@ -113,6 +109,39 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV } } + PortsInformation, err := OpenPortsFile(RespDocker.ImagePath + "/ports.json") + if err != nil { + return nil, err + } + + // Number of perts we want to open + number of ports required inside the + // docker container + count := NumPorts + len(PortsInformation.PortSet) + // Creates number of ports + OpenPorts, err := freeport.GetFreePorts(count) + if err != nil { + return nil,err + } + // Allocate external ports to ports available in the ports.json file + for i := range PortsInformation.PortSet { + PortsInformation.PortSet[i].ExternalPort = OpenPorts[i] + } + //Length of Ports allocated from thr port file + portFileLength := len(PortsInformation.PortSet) + // Allocate New ports the user wants to generate + for i := 0; i < NumPorts; i++ { + var TempPort Port + TempPort.PortName = "AutoGen Port" + TempPort.Type = "tcp" + TempPort.InternalPort = OpenPorts[portFileLength + i] + TempPort.ExternalPort = OpenPorts[portFileLength + i] + TempPort.Description = "Auto generated TCP port" + //Append temp port to port information + PortsInformation.PortSet = append(PortsInformation.PortSet, TempPort) + } + // Setting ports to the docker VM struct + RespDocker.Ports = *PortsInformation + // Gets docker information from env variables cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { @@ -190,12 +219,12 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{ // Port forwarding for VNC and SSH ports PortForwarding := nat.PortMap{ - "22/tcp": []nat.PortBinding{ - { - HostIP: "0.0.0.0", - HostPort: fmt.Sprint(d.SSHPort), - }, - }, + //"22/tcp": []nat.PortBinding{ + // { + // HostIP: "0.0.0.0", + // HostPort: fmt.Sprint(d.SSHPort), + // }, + //}, //"6901/tcp": []nat.PortBinding{ // { // HostIP: "0.0.0.0", @@ -204,9 +233,9 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{ //}, } - for i := range d.Ports { - - Port, err := nat.NewPort("tcp",fmt.Sprint(d.Ports[i])) + for i := range d.Ports.PortSet { + // Parameters "tcp or udp", external port + Port, err := nat.NewPort(d.Ports.PortSet[i].Type,fmt.Sprint(d.Ports.PortSet[i].InternalPort)) if err != nil { return err } @@ -217,7 +246,7 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{ PortForwarding[Port] = []nat.PortBinding{ { HostIP: "0.0.0.0", - HostPort: fmt.Sprint(d.Ports[i]), + HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort), }, } } @@ -253,9 +282,9 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{ d.ID = id var cmd bytes.Buffer - cmd.WriteString("docker run -d=true --name="+ id +" --restart=always --gpus all -p " + fmt.Sprint(d.VNCPort) + ":" + "6901 " + "-p " + fmt.Sprint(d.SSHPort) + ":" + "22 ") - for i := range d.Ports { - cmd.WriteString("-p " + fmt.Sprint(d.Ports[i]) + ":" + fmt.Sprint(d.Ports[i]) + " ") + cmd.WriteString("docker run -d=true --name="+ id +" --restart=always --gpus all ") + for i := range d.Ports.PortSet { + cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ") } cmd.WriteString("-v=/opt/data:/data "+ d.TagName +" /start > /dev/null") //"-v=/opt/data:/data p2p-ubuntu /start > /dev/null" @@ -355,4 +384,19 @@ func print(rd io.Reader) error { } return nil +} + +func OpenPortsFile(filename string) (*Ports, error) { + buf, err := ioutil.ReadFile(filename) + if err != nil { + return nil, err + } + + c := &Ports{} + err = json.Unmarshal(buf, c) + if err != nil { + return nil, fmt.Errorf("in file %q: %v", filename, err) + } + + return c, nil } \ No newline at end of file