Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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)
}
Example #5
0
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
}
Example #6
0
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)
}
Example #7
0
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
}
Example #8
0
func (client *DockerClient) Catalog() (brokerapi.Catalog, error) {
	return brokerapi.Catalog{}, brokerapi.BrokerServiceError(&CFError{brokerapi.ErrCodeOther, "Catalog is not Supported from the client"})
}