func (client *DockerClient) Unbind(br brokerapi.BindingRequest) error { cId, imageName := client.persister.GetContainerIdAndImageName(br.InstanceId) if cId == "" { return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeGone, "Failed to find the Instance in the Database"}) } var err error defer func() { err = client.persister.DeleteServiceBinding(br.InstanceId, br.BindingId) if err != nil { err = brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, "Failed to delete service binding (" + err.Error() + ")"}) } }() imagedefinition := client.brokerconfig.GetImageDefinition(imageName) if len(imagedefinition.DashBoardUrl) > 0 || len(imagedefinition.Credentials) > 0 { return nil } serviceurl := client.persister.GetServiceUrl("container_id='" + cId + "'") dockerExec := CommandExecutors[client.ServiceAgent.ExecCommand] if dockerExec == nil { return errors.New("No Executor specified") } dockerExec = dockerExec.Init(client, cId, imagedefinition) _, err = dockerExec.Unbind(serviceurl) if err != nil { return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } return nil }
func (am *AgentManager) GetServiceAgent(instanceid string) (brokerapi.BrokerService, error) { var brokerservice brokerapi.BrokerService var err error if len(instanceid) == 0 { //use DISPATCHER to pick the ServiceAgent from persister brokerservice, err = am.Dispatcher.NewBrokerService() if err != nil { return nil, err } } else { //look for service agent that holds this instance serviceagent, err := am.config.Persister.GetServiceAgentFromInstance("cf_instance_id='" + instanceid + "'") log.Println("GetServiceAgentFromInstance cf_instance_id='" + instanceid + "'",serviceagent) if err != nil { return nil, brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeGone,"Failed to find the service instance ("+err.Error()+")"}) } serviceagents, err := am.config.Persister.GetServiceAgentList("docker_host='" + serviceagent + "'") log.Println("GetServiceAgentList host='" + serviceagent + "'",serviceagents) if len(serviceagents) == 0 { return nil, brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeGone, "Handler: can't find agent - assume its already gone"}) } if err != nil { return nil, brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeGone, err.Error()}) } brokerservice, err = NewDockerClient(serviceagents[0],am.config) } //handler should recycle this dockerclient, may be we should deref at the end of handler code ot simply call obj.close()? return brokerservice, err }
func (client *DockerClient) Deprovision(pr brokerapi.ProvisioningRequest) error { cId, imageName := client.persister.GetContainerIdAndImageName(pr.InstanceId) if cId == "" { return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeGone, "Failed to find the Instance in the Database"}) } imagedefinition := client.brokerconfig.GetImageDefinition(imageName) defer func() { //TODO remove the reserved port binding for this container, we may check multitenancy here _, _, pb, _ := client.persister.GetPortBindings("docker_host='" + client.ServiceAgent.DockerHost + "'") service_port := client.persister.GetServicePort(pr.InstanceId) pb = DeleteItem(pb, service_port) client.persister.WritePortBinding(pb, "docker_host='"+client.ServiceAgent.DockerHost+"'") client.persister.DeleteServiceInstance(pr.InstanceId) }() var err error if len(imagedefinition.DashBoardUrl) == 0 && len(imagedefinition.Credentials) == 0 { dockerExec := CommandExecutors[client.ServiceAgent.ExecCommand] if dockerExec == nil { log.Println("No Executor specified") } dockerExec = dockerExec.Init(client, cId, imagedefinition) response, err := dockerExec.Deprovision() if err != nil { log.Println("Error occurred running deprovision script ", err) } log.Println("deprovision response is ", response) } if client.shouldRemoveContainer(imagedefinition) { log.Println("Stopping container:", cId) err = client.StopContainer(cId, 0) if err != nil { log.Println("Error stopping container ", err) return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } log.Println("Removing container:", cId) err = client.RemoveContainer(cId) if err != nil { log.Println("Error Removing container ", err) return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } } return err }
func (cm *BrokerConfiguration) AddOrUpdateImageDefinition(catalog string, img brokerapi.ImageDefinition) error { service_id := cm.Persister.GetServiceId(catalog) if service_id < 0 { return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, "Catalog is not Supported from the client"}) } return cm.writeImageConf(service_id, img) }
func (client *DockerClient) Bind(br brokerapi.BindingRequest) (string, brokerapi.Credentials, string, error) { cId, imageName := client.persister.GetContainerIdAndImageName(br.InstanceId) log.Println("Found container id for ", br.InstanceId, " and the value is ", cId, imageName) imagedefinition := client.brokerconfig.GetImageDefinition(imageName) //write the binding to table client.persister.AddServiceBinding(br.InstanceId, br.BindingId, br.AppId, time.Now()) creds := make(brokerapi.Credentials) var err error if len(imagedefinition.DashBoardUrl) > 0 || len(imagedefinition.Credentials) > 0 { for k, v := range imagedefinition.Credentials { creds[k] = v } } else { dockerExec := CommandExecutors[client.ServiceAgent.ExecCommand] if dockerExec == nil { return "", nil, "", errors.New("No Executor specified") } dockerExec = dockerExec.Init(client, cId, imagedefinition) creds, err = dockerExec.Bind() if err != nil { return "", nil, "", brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } log.Println("bind response is ", creds) } client.mapServerUrl(creds, cId) return "credentials", creds, "unknown", err }
func (cm *BrokerConfiguration) AddOrUpdateCertificates(certs brokerapi.BrokerCerts) error { if cm.Persister.HasEntry("brokercertificates", "serviceagent='"+certs.Host+"'") { return brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, "Certificate Exists for this host" + certs.Host}) } return cm.Persister.AddBrokerCertsConf(certs.Host, certs.ClientCert, certs.ClientKey, certs.CA) }
func (client *DockerClient) Provision(pr brokerapi.ProvisioningRequest) (string, error) { imageName := pr.ServiceId log.Println("Looking for image: ", imageName) image, err := FindImage(*client, imageName) if err != nil { return "", brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } log.Println("Image:", imageName, "info:", image.Id, "tags:", image.RepoTags) imagerepo := strings.Split(image.RepoTags[0], ":")[0] config := ContainerConfig{AttachStdout: false, AttachStdin: false, Image: imagerepo, Hostname: pr.InstanceId} imagedefinition := client.brokerconfig.GetImageDefinition(imagerepo) var cId, containername, service_port_str string var service_port, host_port int var dashurl string containername = pr.InstanceId if needNewContainer(imagedefinition) { log.Println("Creating container:") cId, err = config.CreateContainer(*client, pr.InstanceId) if err != nil { log.Println("creating container caused error ", err) if err == ErrConflict { //see if this is the container created earlier but failed later, we can reuse the container ci, err2 := client.InspectContainer(pr.InstanceId) containername = ci.Name cId = ci.Id err = err2 } } ii, err := client.InspectImage(imagerepo) if err != nil { log.Println("Inspect image caused ", err) return "", brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } hostConfig := &HostConfig{PublishAllPorts: true, NetworkMode: "bridge"} pb_min, pb_max, pb, err := client.persister.GetPortBindings("docker_host='" + client.ServiceAgent.DockerHost + "'") if err != nil || pb_min == 0 || pb_max == 0 { log.Println("Unable to assign a port, port binding not configured(uses default port binding) or error occured ", err) } else { hostConfig.PortBindings = make(map[string][]PortBinding) //normally expected to have one port binding for k := range ii.ContainerConfig.ExposedPorts { next_port := FindNextNum(pb, pb_min, pb_max) pb = append(pb, next_port) service_port_str = strings.Split(k, "/")[0] service_port, _ = strconv.Atoi(service_port_str) host_port = next_port log.Println("Mapping ports ", service_port, " to host port ", host_port) hostConfig.PortBindings[k] = []PortBinding{PortBinding{HostPort: strconv.Itoa(next_port)}} } client.persister.WritePortBinding(pb, "docker_host='"+client.ServiceAgent.DockerHost+"'") } log.Println("Starting container:", containername) err = client.StartContainer(cId, hostConfig) if err != nil { log.Println("StartContainer caused ", err) return "", brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } } else { log.Println("Using existing container", imagedefinition.Containername) if imagedefinition.Numinstances == 0 { //Srini we need to get container id from the name by storing it in our DB //for now I will just use id for testing containername = imagedefinition.Containername } else { containername = imagedefinition.Containername } cId = imagedefinition.Containername //TODO we need to get this info service_port = 0 host_port = 0 } var provision_response map[string]interface{} if len(imagedefinition.DashBoardUrl) > 0 || len(imagedefinition.Credentials) > 0 { provision_response = imagedefinition.DashBoardUrl } else { dockerExec := CommandExecutors[client.ServiceAgent.ExecCommand] if dockerExec == nil { return "", errors.New("No Executor specified") } dockerExec = dockerExec.Init(client, cId, imagedefinition) provision_response, err = dockerExec.(DockerExec).Provision() if err != nil { return "", brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, err.Error()}) } } client.mapServerUrl(provision_response, cId) if val, ok := provision_response["dashboard_url"]; ok { //dashurl is needed by the defer statement dashurl = val.(string) } else { dashurl, _ = marshalMapToBytes(provision_response) } err = client.persister.AddServiceInstance(imageName, service_port, host_port, dashurl, cId, client.ServiceAgent.DockerHost, containername, imageName, pr, time.Now()) return dashurl, err }
func (client *DockerClient) Catalog() (brokerapi.Catalog, error) { return brokerapi.Catalog{}, brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, "Catalog is not Supported from the client"}) }