Skip to content
This repository has been archived by the owner on Aug 12, 2024. It is now read-only.

Commit

Permalink
hackathon beacons work
Browse files Browse the repository at this point in the history
Signed-off-by: Gaetan de Villele <[email protected]>
  • Loading branch information
gdevillele committed Mar 5, 2016
1 parent 1d621e7 commit 6e2f0d6
Show file tree
Hide file tree
Showing 5 changed files with 438 additions and 111 deletions.
226 changes: 132 additions & 94 deletions go/src/goproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ import (
// remote API
var dockerClient *dockerclient.DockerClient

// version of the docker daemon which is exposing the remote API
// version of the docker daemon goproxy is connected to
var dockerDaemonVersion string

//
type CPUStats struct {
TotalUsage uint64
SystemUsage uint64
Expand All @@ -40,6 +41,7 @@ type CPUStats struct {
// docker daemon through the docker remote API
var previousCPUStats map[string]*CPUStats = make(map[string]*CPUStats)

// main function of goproxy
func main() {

// goproxy is executed as a short lived process to send a request to the
Expand All @@ -60,6 +62,8 @@ func main() {
return
}

logrus.Println("[goproxy] starting dockercraft goproxy daemon...")

// init docker client object
var err error
dockerClient, err = dockerclient.NewDockerClient("unix:///var/run/docker.sock", nil)
Expand Down Expand Up @@ -90,105 +94,143 @@ func main() {

// eventCallback receives and handles the docker events
func eventCallback(event *dockerclient.Event, ec chan error, args ...interface{}) {
logrus.Debugln("--\n%+v", *event)

id := event.ID

switch event.Status {
case "create":
logrus.Debugln("create event")

repo, tag := splitRepoAndTag(event.From)
containerName := "<name>"
containerInfo, err := dockerClient.InspectContainer(id)
if err != nil {
logrus.Print("InspectContainer error:", err.Error())
} else {
containerName = containerInfo.Name
}

data := url.Values{
"action": {"createContainer"},
"id": {id},
"name": {containerName},
"imageRepo": {repo},
"imageTag": {tag}}

CuberiteServerRequest(data)

case "start":
logrus.Debugln("start event")

repo, tag := splitRepoAndTag(event.From)
containerName := "<name>"
containerInfo, err := dockerClient.InspectContainer(id)
if err != nil {
logrus.Print("InspectContainer error:", err.Error())
} else {
containerName = containerInfo.Name
}

data := url.Values{
"action": {"startContainer"},
"id": {id},
"name": {containerName},
"imageRepo": {repo},
"imageTag": {tag}}

// Monitor stats
dockerClient.StartMonitorStats(id, statCallback, nil)
CuberiteServerRequest(data)

case "stop":
// die event is enough
// http://docs.docker.com/reference/api/docker_remote_api/#docker-events

case "restart":
// start event is enough
// http://docs.docker.com/reference/api/docker_remote_api/#docker-events

case "kill":
// die event is enough
// http://docs.docker.com/reference/api/docker_remote_api/#docker-events

case "die":
logrus.Debugln("die event")

// same as stop event
repo, tag := splitRepoAndTag(event.From)
containerName := "<name>"
containerInfo, err := dockerClient.InspectContainer(id)
if err != nil {
logrus.Print("InspectContainer error:", err.Error())
} else {
containerName = containerInfo.Name
// logrus.Println("[goproxy] [event] ----- event -----")
// logrus.Println("[goproxy] [event] | type :", event.Type)
// logrus.Println("[goproxy] [event] | action:", event.Action)

// handle different kind of events
switch event.Type {
case "container":
// TODO: gdevillele: maybe check for "event.Action" instead of
// "event.Status" for event of type "container"
switch event.Status {
case "create":
// logrus.Println("[goproxy] [event received] create")
// get container ID
containerId := event.ID
repo, tag := splitRepoAndTag(event.From)
containerName := "<name>"
containerInfo, err := dockerClient.InspectContainer(containerId)
if err != nil {
logrus.Print("InspectContainer error:", err.Error())
} else {
containerName = containerInfo.Name
}
data := url.Values{
"action": {"createContainer"},
"id": {containerId},
"name": {containerName},
"imageRepo": {repo},
"imageTag": {tag}}
CuberiteServerRequest(data)
case "start":
// logrus.Println("[goproxy] [event received] start")
// get container ID
containerId := event.ID
repo, tag := splitRepoAndTag(event.From)
containerName := "<name>"
containerInfo, err := dockerClient.InspectContainer(containerId)
if err != nil {
logrus.Print("InspectContainer error:", err.Error())
} else {
containerName = containerInfo.Name
}
data := url.Values{
"action": {"startContainer"},
"id": {containerId},
"name": {containerName},
"imageRepo": {repo},
"imageTag": {tag}}
// Monitor stats
dockerClient.StartMonitorStats(containerId, statCallback, nil)
CuberiteServerRequest(data)
case "stop":
// die event is enough
// http://docs.docker.com/reference/api/docker_remote_api/#docker-events
case "restart":
// start event is enough
// http://docs.docker.com/reference/api/docker_remote_api/#docker-events
case "kill":
// die event is enough
// http://docs.docker.com/reference/api/docker_remote_api/#docker-events
case "die":
// logrus.Println("[goproxy] [event received] die")
// same as stop event
// get container ID
containerId := event.ID
repo, tag := splitRepoAndTag(event.From)
containerName := "<name>"
containerInfo, err := dockerClient.InspectContainer(containerId)
if err != nil {
logrus.Print("InspectContainer error:", err.Error())
} else {
containerName = containerInfo.Name
}
data := url.Values{
"action": {"stopContainer"},
"id": {containerId},
"name": {containerName},
"imageRepo": {repo},
"imageTag": {tag}}
CuberiteServerRequest(data)
case "destroy":
// logrus.Println("[goproxy] [event received] destroy")
// get container ID
containerId := event.ID
data := url.Values{
"action": {"destroyContainer"},
"id": {containerId},
}
CuberiteServerRequest(data)
}
// TODO: gdevillele: disable network events for now
case "network":
switch event.Action {
case "connect":
// a container has been connected to a network

// id of the network
networkID := event.Actor.ID
// name of network
networkName := event.Actor.Attributes["name"]
// type of network
networkType := event.Actor.Attributes["type"]
// id of container affected
containerID := event.Actor.Attributes["container"]

// TODO: gdevillele: clean this
if networkName == "bridge" || networkName == "none" || networkName == "host" {
// those are default network values
// we do nothing for now
return
}

data := url.Values{
"action": {"stopContainer"},
"id": {id},
"name": {containerName},
"imageRepo": {repo},
"imageTag": {tag}}

CuberiteServerRequest(data)

case "destroy":
logrus.Debugln("destroy event")
logrus.Println("[goproxy] [event] ----- custom network connect -----")
logrus.Println("[goproxy] [event] | networkID:", networkID)
logrus.Println("[goproxy] [event] | networkName:", networkName)
logrus.Println("[goproxy] [event] | networkType:", networkType)
logrus.Println("[goproxy] [event] | containerID:", containerID)

data := url.Values{
"action": {"destroyContainer"},
"id": {id},
// send a HTTP request to the Cuberite server
data := url.Values{
"action": {"network_connect"},
"networkId": {networkID},
"networkName": {networkName},
"networkType": {networkType},
"containerId": {containerID},
}
CuberiteServerRequest(data)
}

CuberiteServerRequest(data)
}
}

// statCallback receives the stats (cpu & ram) from containers and send them to
// the cuberite server
func statCallback(id string, stat *dockerclient.Stats, ec chan error, args ...interface{}) {

// TODO: gdevillele: re-activate stats later
return

// logrus.Debugln("STATS", id, stat)
// logrus.Debugln("---")
// logrus.Debugln("cpu :", float64(stat.CpuStats.CpuUsage.TotalUsage)/float64(stat.CpuStats.SystemUsage))
Expand Down Expand Up @@ -244,32 +286,28 @@ func execCmd(w http.ResponseWriter, r *http.Request) {
// listContainers handles and reply to http requests having the path "/containers"
func listContainers(w http.ResponseWriter, r *http.Request) {

// answer right away to avoid dead locks in LUA
// answer right away to avoid deadlocks in LUA
io.WriteString(w, "OK")

go func() {
containers, err := dockerClient.ListContainers(true, false, "")

if err != nil {
logrus.Println(err.Error())
return
}

images, err := dockerClient.ListImages(true)

if err != nil {
logrus.Println(err.Error())
return
}

for i := 0; i < len(containers); i++ {

id := containers[i].Id
info, _ := dockerClient.InspectContainer(id)
name := info.Name[1:]
imageRepo := ""
imageTag := ""

for _, image := range images {
if image.Id == info.Image {
if len(image.RepoTags) > 0 {
Expand Down
5 changes: 5 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ goproxy &> /srv/world/goproxy_out &

# start Minecraft C++ server
cd /srv/world

# GOPROXY DEVELOPMENT: start cuberite as a daemon
#../cuberite_server/Cuberite -d
../cuberite_server/Cuberite

/bin/bash
41 changes: 36 additions & 5 deletions world/Plugins/Docker/container.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ CONTAINER_STOPPED = 2
-- the Minecraft world
function NewContainer()
c = {
-- attributes
displayed = false,
x = 0,
z = 0,
Expand All @@ -19,18 +20,31 @@ function NewContainer()
imageRepo="",
imageTag="",
running=false,
networks={}, -- array of network objects
-- methods
init=Container.init,
setInfos=Container.setInfos,
destroy=Container.destroy,
display=Container.display,
updateMemSign=Container.updateMemSign,
updateCPUSign=Container.updateCPUSign,
addGround=Container.addGround
addGround=Container.addGround,
connectNetwork=Container.connectNetwork
}
return c
end

Container = {displayed = false, x = 0, z = 0, name="",id="",imageRepo="",imageTag="",running=false}
Container = {
displayed = false,
x = 0,
z = 0,
name="",
id="",
imageRepo="",
imageTag="",
running=false,
networks={}
}

-- Container:init sets Container's position
function Container:init(x,z)
Expand Down Expand Up @@ -152,20 +166,17 @@ function Container:display(running)
setBlock(UpdateQueue,self.x+1,GROUND_LEVEL+3,self.z+1,E_BLOCK_LEVER,9)
end


-- remove button

setBlock(UpdateQueue,self.x+2,GROUND_LEVEL + 3,self.z + 2,E_BLOCK_WALLSIGN,E_META_CHEST_FACING_XM)
updateSign(UpdateQueue,self.x+2,GROUND_LEVEL + 3,self.z + 2,"","REMOVE","---->","",2)

setBlock(UpdateQueue,self.x+2,GROUND_LEVEL+3,self.z+3,E_BLOCK_STONE_BUTTON,E_BLOCK_BUTTON_XM)


-- door
-- Cuberite bug with Minecraft 1.8 apparently, doors are not displayed correctly
-- setBlock(UpdateQueue,self.x+2,GROUND_LEVEL+2,self.z,E_BLOCK_WOODEN_DOOR,E_META_CHEST_FACING_ZM)


for px=self.x, self.x+3
do
for pz=self.z, self.z+4
Expand Down Expand Up @@ -213,3 +224,23 @@ function Container:addGround()
end
end
end

-- Container:connectNetwork
function Container:connectNetwork(network)
-- check if the container is already connected to this network
found = false
for i=1, table.getn(self.networks) do
if self.networks[i].id == network.id then
found = true
break
end
end
if found == false then
-- TODO: gdevillele: support multiple networks per container
LOG("[CONTAINER] [connectNetwork] container is connected to a new network")
table.insert(self.networks, network)
setBlock(UpdateQueue, self.x+3, GROUND_LEVEL+5, self.z, E_BLOCK_WOOL, E_META_WOOL_RED)
else
-- container already know it is connected to this network, we do noting
end
end
Loading

0 comments on commit 6e2f0d6

Please sign in to comment.