// RemoveInstanceFromDiscovery removes an instance from etcd discovery.
func RemoveInstanceFromDiscovery(i swarmtypes.Instance) error {
	etcdMemberName, err := ssh.GetEtcd2MemberName(i.PublicIPAddress)
	if err != nil {
		return errgo.Mask(err)
	}
	// Not a quorum member
	if etcdMemberName == "" {
		return nil
	}

	discoveryUrl, err := ssh.GetEtcdDiscoveryUrl(i.PublicIPAddress)
	if err != nil {
		return errgo.Mask(err)
	}

	machineUrl := discoveryUrl + "/" + etcdMemberName
	req, err := http.NewRequest("DELETE", machineUrl, nil)
	if err != nil {
		return errgo.Mask(err)
	}

	_, err = http.DefaultClient.Do(req)
	if err != nil {
		return errgo.Mask(err)
	}
	return nil
}
Example #2
0
func runKillInstance(args []string) (exit int) {
	if len(args) != 2 {
		return exitError("wrong number of arguments. Usage: kocho kill-instance <swarm> <instance>")
	}
	swarmName := args[0]
	instanceID := args[1]

	s, err := swarmService.Get(swarmName, swarm.AWS)
	if err != nil {
		return exitError(fmt.Sprintf("couldn't get instances of swarm: %s", swarmName), err)
	}

	instances, err := s.GetInstances()
	if err != nil {
		return exitError(err)
	}

	killableInstance, err := swarmtypes.FindInstanceById(instances, instanceID)
	if err != nil {
		return exitError(errgo.WithCausef(err, nil, "failed to find provided instance: %s", instanceID))
	}

	runningInstances := swarmtypes.FilterInstanceById(instances, instanceID)
	if len(runningInstances) == 0 {
		return exitError(errgo.Newf("no more instances left in swarm %s. Cannot update Fleet DNS entry", swarmName))
	}

	if !ignoreQuorumCheck {
		etcdQuorumID, err := ssh.GetEtcd2MemberName(killableInstance.PublicIPAddress)
		if err != nil {
			return exitError(errgo.WithCausef(err, nil, "ssh: failed to check quorum member list: %v", err))
		}

		if etcdQuorumID != "" {
			return exitError(errgo.Newf("Instance %s seems to be part of the etcd quorum. Please remove it beforehand. See %s", killableInstance.Id, etcdDocsLink))
		}
	}

	if err = s.KillInstance(killableInstance); err != nil {
		return exitError(errgo.WithCausef(err, nil, "failed to kill instance: %s", instanceID))
	}

	if changed, err := dns.Update(dnsService, viperConfig.getDNSNamingPattern(), s, runningInstances); err != nil {
		return exitError(errgo.WithCausef(err, nil, "failed to update dns records"))
	} else if !changed {
		return exitError(errgo.Newf("DNS not changed. Couldn't find valid publid DNS name"))
	}

	fmt.Printf(killInstanceSuccessMessage, killableInstance.Id, etcdDocsLink)

	fireNotification()

	return 0
}