From ebfac2321f44550a05081aa50f4002a82218b100 Mon Sep 17 00:00:00 2001 From: Akilan Date: Wed, 17 Feb 2021 21:41:26 +0400 Subject: [PATCH] added docker python code for virtualization --- .gitignore | 4 +- Makefile | 13 ++- go.mod | 4 +- go.sum | 2 + .../containers/docker-ubuntu-sshd/Dockerfile | 5 +- server/docker/docker.go | 94 +++++++++++++++++++ server/docker/docker_vm.py | 81 ++++++++++++++++ .../{kill-continers.sh => kill-containers.sh} | 0 server/docker/requirements.txt | 2 + 9 files changed, 199 insertions(+), 6 deletions(-) create mode 100644 server/docker/docker_vm.py rename server/docker/{kill-continers.sh => kill-containers.sh} (100%) create mode 100644 server/docker/requirements.txt diff --git a/.gitignore b/.gitignore index d4f1a15..7fc4b64 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ vendor/ bin/ -p2p-rendering/ \ No newline at end of file +p2p-rendering/ +./main +server/docker/__pycache__ \ No newline at end of file diff --git a/Makefile b/Makefile index 8263bd3..b09dcb8 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,17 @@ +SHELL := /bin/bash + build: - go build -o bin/main main.go + go build -o main main.go run: go run main.go +set_virtualenv: + virtualenv p2p-rendering + +install_docker_requirements: + source p2p-rendering/bin/activate && pip install -r server/docker/requirements.txt + + dockerproc: - ADMIN_USER=admin ADMIN_PASSWORD=admin docker-compose -f server/docker/dockprom/docker-compose.yml up -d \ No newline at end of file + ADMIN_USER=admin ADMIN_PASSWORD=admin docker-compose -f server/docker/dockprom/docker-compose.yml up -d \ No newline at end of file diff --git a/go.mod b/go.mod index 436812b..9aeb3d7 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,8 @@ require ( github.com/christophwitzko/go-curl v0.0.0-20171216141518-4203158d6acb github.com/containerd/containerd v1.4.3 // indirect github.com/docker/distribution v2.7.1+incompatible // indirect - github.com/docker/docker v20.10.2+incompatible - github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible + github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 // indirect github.com/fsouza/go-dockerclient v1.7.0 // indirect github.com/gin-gonic/gin v1.6.3 diff --git a/go.sum b/go.sum index 7ee1629..0187063 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= +github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible h1:lwpV3629md5omgAKjxPWX17shI7vMRpE3nyb9WHn8pA= github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.2+incompatible h1:vFgEHPqWBTp4pTjdLwjAA4bSo3gvIGOYwuJTlEjVBCw= github.com/docker/docker v20.10.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= diff --git a/server/docker/containers/docker-ubuntu-sshd/Dockerfile b/server/docker/containers/docker-ubuntu-sshd/Dockerfile index df97b2c..b9ed6f9 100644 --- a/server/docker/containers/docker-ubuntu-sshd/Dockerfile +++ b/server/docker/containers/docker-ubuntu-sshd/Dockerfile @@ -8,7 +8,10 @@ # Base system is the latest LTS version of Ubuntu. -from ubuntu +from consol/ubuntu-xfce-vnc + +# Switch to root user to install additional software +USER 0 # Make sure we don't get notifications we can't answer during building. diff --git a/server/docker/docker.go b/server/docker/docker.go index 97e954b..d9def16 100644 --- a/server/docker/docker.go +++ b/server/docker/docker.go @@ -8,9 +8,16 @@ import ( "bytes" "os" "archive/tar" + "log" + "fmt" "github.com/docker/docker/api/types" "github.com/docker/docker/client" + + natting "github.com/docker/go-connections/nat" + "github.com/docker/docker/api/types/container" + network "github.com/docker/docker/api/types/network" + "github.com/docker/docker/api/types" ) @@ -40,6 +47,15 @@ func RunVM()(interface{},error) { // TODO Run contianer + imagename := "ubuntu" + containername := "test1" + portopening := "1003" + inputEnv := []string{fmt.Sprintf("LISTENINGPORT=%s", portopening)} + err = RunContainer(client, imagename, containername, portopening, inputEnv) + if err != nil { + return nil,err + } + sshreturn := new(SSHreturn) sshreturn.Port = "1003" @@ -51,6 +67,7 @@ func RunVM()(interface{},error) { } // Taken from (https://medium.com/@Frikkylikeme/controlling-docker-with-golang-code-b213d9699998) +// Builds local docker image func BuildImage(client *client.Client, tags []string, dockerfile string) error{ ctx := context.Background() @@ -120,3 +137,80 @@ func BuildImage(client *client.Client, tags []string, dockerfile string) error{ return nil } + + +// Taken from (https://medium.com/@Frikkylikeme/controlling-docker-with-golang-code-b213d9699998) +// Runs Docker image +func RunContainer(client *client.Client, imagename string, containername string, port string, inputEnv []string) error { + // Define a PORT opening + newport, err := natting.NewPort("tcp", port) + if err != nil { + fmt.Println("Unable to create docker port") + return err + } + + // Configured hostConfig: + // https://godoc.org/github.com/docker/docker/api/types/container#HostConfig + hostConfig := &container.HostConfig{ + PortBindings: natting.PortMap{ + newport: []natting.PortBinding{ + { + HostIP: "0.0.0.0", + HostPort: port, + }, + }, + }, + RestartPolicy: container.RestartPolicy{ + Name: "always", + }, + LogConfig: container.LogConfig{ + Type: "json-file", + Config: map[string]string{}, + }, + } + + // Define Network config (why isn't PORT in here...?: + // https://godoc.org/github.com/docker/docker/api/types/network#NetworkingConfig + networkConfig := &network.NetworkingConfig{ + EndpointsConfig: map[string]*network.EndpointSettings{}, + } + gatewayConfig := &network.EndpointSettings{ + Gateway: "gatewayname", + } + networkConfig.EndpointsConfig["bridge"] = gatewayConfig + + // Define ports to be exposed (has to be same as hostconfig.portbindings.newport) + exposedPorts := map[natting.Port]struct{}{ + newport: struct{}{}, + } + + // Configuration + // https://godoc.org/github.com/docker/docker/api/types/container#Config + config := &container.Config{ + Image: imagename, + Env: inputEnv, + ExposedPorts: exposedPorts, + Hostname: fmt.Sprintf("%s-hostnameexample", imagename), + } + + // Creating the actual container. This is "nil,nil,nil" in every example. + cont, err := client.ContainerCreate( + context.Background(), + config, + hostConfig, + networkConfig, + containername, + ) + + if err != nil { + log.Println(err) + return err + } + + // Run the actual container + client.ContainerStart(context.Background(), cont.ID, types.ContainerStartOptions{}) + log.Printf("Container %s is created", cont.ID) + + + return nil +} diff --git a/server/docker/docker_vm.py b/server/docker/docker_vm.py new file mode 100644 index 0000000..4c0fc8f --- /dev/null +++ b/server/docker/docker_vm.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 + +''' +FUTURE RELEASE TO BE CONVERTED TO GO LANG +''' + +import click +import sys +import docker +import socket +import uuid +import os + +# ----------------------------------------------- CLI flags -------------------------------------------------------- + +@click.command() +@click.option("--createvm", is_flag=True, help="Creates docker default VM") + +# ------------------------------------------------------------------------------------------------------------------- +# -------------------------------------- Actions when flags are called ---------------------------------------------- + +def main(createvm): + + # creates docker virtual machine + if createvm: + name = str(uuid.uuid4()) + build_run_contianer(name) + + else: + ctx = click.get_current_context() + click.echo(ctx.get_help()) + +# ------------------------------------------------------------------------------------------------------------------- +# ------------------------------------------ build and run Contianer ------------------------------------------------ + +def build_run_contianer(name): + # Get docker information from environment variables + client = docker.from_env() + + image_path = "./server/docker/containers/docker-ubuntu-sshd/" + tag_name = "p2p-ubuntu" + free_port = str(get_free_tcp_port()) + + # Change to JSON response + vnc_free_port = str(get_free_tcp_port()) + + # Check if image is already exists (If already exists then delete and rebuild) + try: + client.images.get(tag_name) + print("------ Image exists (Running Docker container " + name + ") --------") + + # Run the docker continer + # Running interactive version until log files for results are created + os.system("docker run -d=true --name="+ name +" --restart=always -p 6901:6901 -p "+ free_port +":22 -v=/opt/data:/data "+ tag_name +" /start") + + except: + print("------ Image does not exists (building " + name + " and running image) ---------") + + # client.images.build(path=framework_image_path,tag=tag_name,rm=True) + os.system("docker build -t " + tag_name + " " + image_path) + + print("------ Running Docker contianer " + name + " ---------") + # Run the docker continer + # Running interactive version until log files for results are created + os.system("docker run -d=true --name="+ name +" --restart=always -p 6901:6901 -p "+ free_port +":22 -v=/opt/data:/data "+ tag_name +" /start") + +# ------------------------------------------------------------------------------------------------------------------- +# ------------------------------------------ Get free TCP port ------------------------------------------------------ + +def get_free_tcp_port(): + tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + tcp.bind(('', 0)) + addr, port = tcp.getsockname() + tcp.close() + return port + + +# ------------------------------------------------------------------------------------------------------------------- + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/server/docker/kill-continers.sh b/server/docker/kill-containers.sh similarity index 100% rename from server/docker/kill-continers.sh rename to server/docker/kill-containers.sh diff --git a/server/docker/requirements.txt b/server/docker/requirements.txt new file mode 100644 index 0000000..6bdc9c9 --- /dev/null +++ b/server/docker/requirements.txt @@ -0,0 +1,2 @@ +click +docker \ No newline at end of file