1
0
mirror of https://github.com/rancher/rke.git synced 2025-04-28 03:31:24 +00:00
rke/hosts/hosts.go

178 lines
4.6 KiB
Go
Raw Normal View History

2017-10-29 09:45:21 +00:00
package hosts
import (
"fmt"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/rancher/rke/docker"
"github.com/rancher/rke/k8s"
2017-12-05 16:55:58 +00:00
"github.com/rancher/types/apis/management.cattle.io/v3"
2017-11-13 21:28:38 +00:00
"github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/client-go/kubernetes"
)
2017-10-29 09:45:21 +00:00
type Host struct {
2017-12-05 16:55:58 +00:00
v3.RKEConfigNode
DClient *client.Client
IsControl bool
IsWorker bool
2017-10-29 09:45:21 +00:00
}
const (
ToCleanEtcdDir = "/var/lib/etcd"
ToCleanSSLDir = "/etc/kubernetes/ssl"
ToCleanCNIConf = "/etc/cni"
ToCleanCNIBin = "/opt/cni"
ToCleanCalicoRun = "/var/run/calico"
CleanerContainerName = "kube-cleaner"
CleanerImage = "alpine:latest"
)
func (h *Host) CleanUpAll() error {
// the only supported removal for etcd dir is in rke remove
toCleanPaths := []string{
ToCleanEtcdDir,
ToCleanSSLDir,
ToCleanCNIConf,
ToCleanCNIBin,
ToCleanCalicoRun,
}
return h.CleanUp(toCleanPaths)
}
func (h *Host) CleanUpWorkerHost(controlRole string) error {
if h.IsControl {
logrus.Infof("[hosts] Host [%s] is already a controlplane host, skipping cleanup.", h.Address)
return nil
}
toCleanPaths := []string{
ToCleanSSLDir,
ToCleanCNIConf,
ToCleanCNIBin,
ToCleanCalicoRun,
}
return h.CleanUp(toCleanPaths)
}
func (h *Host) CleanUpControlHost(workerRole string) error {
if h.IsWorker {
logrus.Infof("[hosts] Host [%s] is already a worker host, skipping cleanup.", h.Address)
return nil
}
toCleanPaths := []string{
ToCleanSSLDir,
ToCleanCNIConf,
ToCleanCNIBin,
ToCleanCalicoRun,
}
return h.CleanUp(toCleanPaths)
}
func (h *Host) CleanUp(toCleanPaths []string) error {
logrus.Infof("[hosts] Cleaning up host [%s]", h.Address)
imageCfg, hostCfg := buildCleanerConfig(h, toCleanPaths)
2017-11-28 17:45:24 +00:00
logrus.Infof("[hosts] Running cleaner container on host [%s]", h.Address)
if err := docker.DoRunContainer(h.DClient, imageCfg, hostCfg, CleanerContainerName, h.Address, CleanerContainerName); err != nil {
return err
}
if err := docker.WaitForContainer(h.DClient, CleanerContainerName); err != nil {
return err
}
2017-11-28 17:45:24 +00:00
logrus.Infof("[hosts] Removing cleaner container on host [%s]", h.Address)
if err := docker.RemoveContainer(h.DClient, h.Address, CleanerContainerName); err != nil {
return err
}
2017-11-28 17:45:24 +00:00
logrus.Infof("[hosts] Successfully cleaned up host [%s]", h.Address)
return nil
}
func DeleteNode(toDeleteHost *Host, kubeClient *kubernetes.Clientset, hasAnotherRole bool) error {
if hasAnotherRole {
logrus.Infof("[hosts] host [%s] has another role, skipping delete from kubernetes cluster", toDeleteHost.Address)
return nil
}
2017-11-28 17:45:24 +00:00
logrus.Infof("[hosts] Cordoning host [%s]", toDeleteHost.Address)
if _, err := k8s.GetNode(kubeClient, toDeleteHost.HostnameOverride); err != nil {
if apierrors.IsNotFound(err) {
logrus.Warnf("[hosts] Can't find node by name [%s]", toDeleteHost.Address)
return nil
}
return err
}
if err := k8s.CordonUncordon(kubeClient, toDeleteHost.HostnameOverride, true); err != nil {
return err
}
2017-11-28 17:45:24 +00:00
logrus.Infof("[hosts] Deleting host [%s] from the cluster", toDeleteHost.Address)
if err := k8s.DeleteNode(kubeClient, toDeleteHost.HostnameOverride); err != nil {
return err
}
2017-11-28 17:45:24 +00:00
logrus.Infof("[hosts] Successfully deleted host [%s] from the cluster", toDeleteHost.Address)
return nil
}
func GetToDeleteHosts(currentHosts, configHosts []*Host) []*Host {
toDeleteHosts := []*Host{}
for _, currentHost := range currentHosts {
found := false
for _, newHost := range configHosts {
2017-11-28 17:45:24 +00:00
if currentHost.Address == newHost.Address {
found = true
2017-10-29 09:45:21 +00:00
}
}
if !found {
toDeleteHosts = append(toDeleteHosts, currentHost)
2017-10-29 09:45:21 +00:00
}
}
return toDeleteHosts
}
func IsHostListChanged(currentHosts, configHosts []*Host) bool {
changed := false
for _, host := range currentHosts {
found := false
for _, configHost := range configHosts {
2017-11-28 17:45:24 +00:00
if host.Address == configHost.Address {
found = true
2017-11-28 17:45:24 +00:00
break
}
}
if !found {
return true
}
}
for _, host := range configHosts {
found := false
for _, currentHost := range currentHosts {
2017-11-28 17:45:24 +00:00
if host.Address == currentHost.Address {
found = true
2017-11-28 17:45:24 +00:00
break
}
}
if !found {
return true
}
}
return changed
2017-10-29 09:45:21 +00:00
}
func buildCleanerConfig(host *Host, toCleanDirs []string) (*container.Config, *container.HostConfig) {
cmd := append([]string{"rm", "-rf"}, toCleanDirs...)
imageCfg := &container.Config{
Image: CleanerImage,
Cmd: cmd,
}
bindMounts := []string{}
for _, vol := range toCleanDirs {
bindMounts = append(bindMounts, fmt.Sprintf("%s:%s", vol, vol))
}
hostCfg := &container.HostConfig{
Binds: bindMounts,
}
return imageCfg, hostCfg
}