package main import ( "errors" "sync" ) var( containers = []*ChallengeContainer{} containerStartLock sync.Mutex containerStopLock sync.Mutex ) // Checks if the given container name is already running func isChallengeContainerRunning(name string) (bool) { for _, c := range containers { if c.Challenge.Name == name { return true } } return false } // Starts the given container. Thread-safe! func startChallengeContainer(c Challenge) (*ChallengeContainer, error) { // Lock procedure to avoid race conditions containerStartLock.Lock() defer containerStartLock.Unlock() if(isChallengeContainerRunning(c.Name)) { return nil, errors.New("Container already running") } cc := ChallengeContainer{Challenge: &c} address, containerID, err := cc.startContainer() if err != nil { return nil, err } cc.IP = address cc.ContainerID = containerID // Add container to list containers = append(containers, &cc) return &cc, nil } // Stops the given container. Thread-safe! func stopChallengeContainer(name string) { containerStopLock.Lock() defer containerStopLock.Unlock() for index, c := range containers { if c.Challenge.Name == name { c.stopContainer() containers = append(containers[:index], containers[index+1:]...) return } } } // Stops all containers. Thread-safe! func stopAllChallengeContainers() { containerStopLock.Lock() defer containerStopLock.Unlock() for _, c := range containers { c.stopContainer() } } // Returns the address for the given container, if there is a container with this name running func getAddressForChallengeContainer(container string) (address string) { for _, c := range containers { if c.Challenge.Container == container { return c.IP } } return "" }