diff --git a/docker/prepare.go b/docker/prepare.go index e15d863..8b919aa 100644 --- a/docker/prepare.go +++ b/docker/prepare.go @@ -6,7 +6,6 @@ import ( "fmt" "io" "net/http" - "strings" "time" "github.com/docker/docker/api/types/mount" @@ -29,6 +28,7 @@ func prepare(w http.ResponseWriter, r *http.Request){ var bodyDecoded struct{ ServiceId string `json:"serviceId"` + VolumeId string `json:"volumeId"` }; err = json.Unmarshal(rawBody, &bodyDecoded); @@ -50,7 +50,6 @@ func prepare(w http.ResponseWriter, r *http.Request){ maxConcurrent := uint64(1); totalCompletions := uint64(1); - targetVolumes := strings.Split(labels["blazena.volumes"], ","); targetNode := labels["blazena.node"]; helperCommand := `apk add openssh rsync && \ ssh-keygen -t ed25519 -f /host_key && \ @@ -58,50 +57,58 @@ func prepare(w http.ResponseWriter, r *http.Request){ echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIByYbl8vu946LPycSO5pBohq3vMvvl+wX7snu1Bqpd7p test" > /root/.ssh/authorized_keys && \ /usr/sbin/sshd -h /host_key -p 22 -D`; - for _, targetVolume := range targetVolumes{ - _, err := ApiClient.ServiceCreate(context.Background(), swarm.ServiceSpec{ - Annotations: swarm.Annotations{ - Labels: map[string]string{"blazena.helper": "true"}, + _, err = ApiClient.ServiceCreate(context.Background(), swarm.ServiceSpec{ + Annotations: swarm.Annotations{ + Labels: map[string]string{"blazena.helper": "true"}, + }, + Mode: swarm.ServiceMode{ + ReplicatedJob: &swarm.ReplicatedJob{ + MaxConcurrent: &maxConcurrent, + TotalCompletions: &totalCompletions, }, - Mode: swarm.ServiceMode{ - ReplicatedJob: &swarm.ReplicatedJob{ - MaxConcurrent: &maxConcurrent, - TotalCompletions: &totalCompletions, - }, - }, - TaskTemplate: swarm.TaskSpec{ - ContainerSpec: &swarm.ContainerSpec{ - Image: "docker.io/library/alpine:latest", - Command: []string{"sh", "-c", helperCommand}, - Mounts: []mount.Mount{ - mount.Mount{ - Source: targetVolume, - Target: "/volume", - Type: "volume", - }, - }, - }, - Placement: &swarm.Placement{ - Constraints: []string{"node.hostname=="+targetNode}, - }, - }, - EndpointSpec: &swarm.EndpointSpec{ - Ports: []swarm.PortConfig{ - swarm.PortConfig{ - Protocol: swarm.PortConfigProtocolTCP, - TargetPort: uint32(22), - PublishedPort: uint32(2222), - PublishMode: swarm.PortConfigPublishModeHost, + }, + TaskTemplate: swarm.TaskSpec{ + ContainerSpec: &swarm.ContainerSpec{ + Image: "docker.io/library/alpine:latest", + Command: []string{"sh", "-c", helperCommand}, + Mounts: []mount.Mount{ + mount.Mount{ + Source: bodyDecoded.VolumeId, + Target: "/volume", + Type: "volume", }, }, }, - }, swarm.ServiceCreateOptions{}); + Placement: &swarm.Placement{ + Constraints: []string{"node.hostname=="+targetNode}, + }, + }, + EndpointSpec: &swarm.EndpointSpec{ + Ports: []swarm.PortConfig{ + swarm.PortConfig{ + Protocol: swarm.PortConfigProtocolTCP, + TargetPort: uint32(22), + PublishedPort: uint32(2222), + PublishMode: swarm.PortConfigPublishModeHost, + }, + }, + }, + }, swarm.ServiceCreateOptions{}); - if err != nil { - panic("Failed to create helper service."+ err.Error()); - } - - fmt.Fprint(w, bodyDecoded.ServiceId); + if err != nil { + panic("Failed to create helper service."+ err.Error()); } + + fmt.Fprint(w, bodyDecoded.ServiceId); } + +func contains(slice []string, str string) bool { + for _, s := range slice { + if s == str { + return true + } + } + return false +} + diff --git a/host/host.go b/host/host.go index 2b86034..cc6be9e 100644 --- a/host/host.go +++ b/host/host.go @@ -39,16 +39,22 @@ func Run(Config cfg.Config) { createStorageContainer(Config, DockerClient); - // services := getServices(Config); - // - // for _, service := range services { - // if !prepareService(Config, service) {continue} - // - // os.Exit(0); - // - // } + services := getServices(Config); + + for _, service := range services { + for _, volume := range service.VolumeNames{ + fmt.Println("Preparing: " + service.ServiceId + " volume: " + volume); + if !prepareService(Config, service, volume) {continue} + fmt.Println("Done!"); + time.Sleep(5*time.Second); + fmt.Println("Cleaning Up: " + service.ServiceId + " volume: " + volume); + cleanupService(Config, service); + fmt.Println("Done!"); + + + } + } - time.Sleep(30*time.Second); DockerClient.ContainerRemove(context.Background(), "BlazenaStorage", container.RemoveOptions{ Force: true, @@ -79,7 +85,7 @@ func getServices(Config cfg.Config)[]aService{ return services; } -func prepareService(Config cfg.Config, service aService) bool{ +func prepareService(Config cfg.Config, service aService, targetVolume string) bool{ _, ok := Config.Nodes[service.Node]; if !ok { fmt.Println("Node", service.Node, "refferenced in", service.ServiceId ,"service does not exists!"); @@ -88,8 +94,10 @@ func prepareService(Config cfg.Config, service aService) bool{ var body struct{ ServiceId string `json:"serviceId"` - } = struct{ServiceId string "json:\"serviceId\""}{ + VolumeId string `json:"volumeId"` + } = struct{ServiceId string "json:\"serviceId\""; VolumeId string "json:\"volumeId\""}{ ServiceId: service.ServiceId, + VolumeId: targetVolume, } bodyEncoded, err := json.Marshal(body); @@ -116,9 +124,48 @@ func prepareService(Config cfg.Config, service aService) bool{ return true; } +func cleanupService(Config cfg.Config, service aService)bool{ + _, ok := Config.Nodes[service.Node]; + if !ok { + fmt.Println("Node", service.Node, "refferenced in", service.ServiceId ,"service does not exists!"); + return false; + } + + var body struct{ + ServiceId string `json:"serviceId"` + VolumeId string `json:"volumeId"` + } = struct{ServiceId string "json:\"serviceId\""; VolumeId string "json:\"volumeId\""}{ + ServiceId: service.ServiceId, + } + + bodyEncoded, err := json.Marshal(body); + + if err != nil { + panic("Failed to marshal body."+ err.Error()); + } + + rq, err := http.NewRequest("POST", Config.DockerManagerBaseUrl + "/cleanup", bytes.NewBuffer(bodyEncoded)); + + if err != nil{ + panic("Failed to create http request"+ err.Error()); + } + + rq.Header.Set("Authorization", "Bearer "+ token); + rq.Close = true; + rs, err := http.DefaultClient.Do(rq); + defer rs.Body.Close(); + + if err != nil{ + panic("Failed to send http request"+ err.Error()); + } + + return true; + +} + func createStorageContainer(Config cfg.Config, DockerClient *client.Client){ cr, err := DockerClient.ContainerCreate(context.Background(), &container.Config{ - Image: "docker.io/library/alpine:3", + Image: "docker.io/library/alpine:3.3", Labels: map[string]string{ "blazena.storage": "true", },