package main import ( "github.com/docker/docker/api/types" "time" ) const( vpnHostNetworkName = "vpnhostnet" ) var ( containerNetworkID string vpnHostNetworkID string ) func setupNetwork(networkName string, internalNetwork bool) (string, error) { setupContext() setupDockerCLI() // Cleanup old network(s) with that name err := deleteNetwork(networkName) if err != nil { return "", err } // create our new network response, err := dockerCli.NetworkCreate(dockerCtx, networkName, types.NetworkCreate{ Internal: internalNetwork, }) if err != nil { return "", err } return response.ID, nil } func deleteNetwork(networkName string) (error) { // try to cleanup old instances of that network // BUT we need to get the ID used on the old network, and we only have the name of the network // so we get a list of all networks and skip through that array...: networks, err := dockerCli.NetworkList(dockerCtx, types.NetworkListOptions{}) // TODO: we sure as hell can filter that with NetworkListOptions! if err != nil { return err } // Iterate over all networks for _, network := range networks { if network.Name == networkName { // Found a network with that name // We need to stop all containers attached to it before we can remove the network // Get all containers attached to the network resource, err := dockerCli.NetworkInspect(dockerCtx, network.ID, types.NetworkInspectOptions{}) if err != nil { return err } // Loop over containers attached to that network and stop them timeout := time.Second for _, container := range resource.Containers { // Stop container dockerCli.ContainerStop(dockerCtx, container.EndpointID, &timeout) time.Sleep(timeout) // We ignore the err return variable here. // It may happen that this container is already stopped, but is still part of the network // TODO: Inspect the container to check that - we don't want to ignore errors! } // Now we can remove the network err = dockerCli.NetworkRemove(dockerCtx, network.ID) if err != nil { return err } } } return nil }