lib/sct/commands/cluster.rb in sct-0.1.14 vs lib/sct/commands/cluster.rb in sct-0.1.15
- old
+ new
@@ -3,15 +3,15 @@
module Sct
class ClusterCommand
IS_PUBLIC_COMMAND = true
- SYNTAX = 'sct cluster up | sct cluster down | sct cluster reset | sct cluster update-config'
- SUMMARY = 'Starts/stops/resets or updates the config of the minikube cluster.'
- EXAMPLE = 'sct cluster up | sct cluster down | sct cluster reset | sct cluster update-config'
- EXAMPLE_DESCRIPTION = 'Starts/stops/resets or updates the config of the minikube cluster.'
- DESCRIPTION = "sct cluster allows you to start, stop, reset or update the config of the Spend Cloud minikube cluster."
+ SYNTAX = 'sct cluster up | sct cluster down | sct cluster setup | sct cluster reset | sct cluster update-config | sct cluster delete-stalled-pods'
+ SUMMARY = 'Perform actions on the minikube cluster.'
+ EXAMPLE = 'sct cluster up | sct cluster down | sct cluster setup | sct cluster reset | sct cluster update-config | sct cluster delete-stalled-pods'
+ EXAMPLE_DESCRIPTION = 'Perform actions on the minikube cluster.'
+ DESCRIPTION = "sct cluster allows you to start, stop, setup/reset, update the config, or delete the stalled pods of the Spend Cloud minikube cluster."
OPTIONS = []
def execute(args, options)
return puts "SCT has not been initialized. Run 'sct init' first.".red unless Sct::Config.exists
@@ -21,89 +21,169 @@
up
when "down"
down
when "update-config"
update_config
- when "reset"
+ when "setup", "reset"
reset
+ when "delete-stalled-pods"
+ delete_stalled_pods(feedback: true)
else
- puts "Unknown or missing argument. Please run 'sct cluster up','sct cluster down' or 'sct cluster update-config'".red
+ puts "Unknown or missing argument. Please run 'sct cluster up', 'sct cluster down', 'sct cluster setup', 'sct cluster reset', 'sct cluster update-config', or 'sct cluster delete-stalled-pods'.".red
end
end
def up
start
- system "kubectl delete pod -n kube-system $(kubectl get pods -n kube-system | grep registry-creds | awk '{print $1}')"
- system "kubectl rollout status -n kube-system deployment/registry-creds"
+ run_command "kubectl delete pod -n kube-system #{pods("kube-system").map { |pod| pod[:name] if pod[:name].start_with? "registry-creds" } .compact.join(" ")}"
+ run_command "kubectl rollout status -n kube-system deployment/registry-creds"
post_start
end
def down
- system "#{minikube} stop"
+ run_command "#{minikube} stop"
end
+ def reset
+ run_command "#{minikube} delete"
+ start
+ create_secrets
+ run_command "#{minikube} addons enable registry-creds"
+ run_command "#{minikube} addons enable ingress"
+ run_command "kubectl rollout status -n kube-system deployment/registry-creds"
+ run_command "kubectl rollout status -n kube-system deployment/nginx-ingress-controller"
+ wait_for_gcr_secret
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/ingress.yml"
+ wait_for_ingress_ip
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/dependencies.yml"
+ wait_for_pods
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/"
+ post_start
+ end
+
def update_config
if Sct::Helpers.operatingSystem == Sct::Helpers::WINDOWS
windows_home_path = Sct::Helpers.windowsHomePath
kube_file_path = windows_home_path+"/.kube/config"
if !File.exists?(kube_file_path)
return puts "#{kube_file_path} doesn't exist".red
end
- system("sed -e 's~\\\\~/~g' -e 's~C:~/mnt/c~g' < #{kube_file_path} > ~/.kube/minikube-config")
+ run_command "sed -e 's~\\\\~/~g' -e 's~C:~/mnt/c~g' < #{kube_file_path} > ~/.kube/minikube-config"
puts "#{kube_file_path} copied to ~/.kube/minikube-config".green
end
- system "kubectl config use-context minikube"
+ run_command "kubectl config use-context minikube"
+
+ run_command "kubectl replace -n kube-system -f #{File.expand_path('../../../resources/corefile.yml', __dir__)}"
+ run_command "kubectl delete pod -n kube-system #{pods("kube-system").map { |pod| pod[:name] if pod[:name].start_with? "coredns" } .compact.join(" ")}"
+ run_command "kubectl rollout status -n kube-system deployment/coredns"
end
- def reset
- system "#{minikube} delete"
- start
- system "kubectl create secret generic gcloud-credentials --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\""
- system "kubectl create secret generic -n kube-system registry-creds-dpr --from-literal DOCKER_PRIVATE_REGISTRY_PASSWORD=changeme --from-literal DOCKER_PRIVATE_REGISTRY_SERVER=changeme --from-literal DOCKER_PRIVATE_REGISTRY_USER=changeme"
- system "kubectl patch secret -n kube-system registry-creds-dpr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"dpr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
- system "kubectl create secret generic -n kube-system registry-creds-ecr --from-literal AWS_ACCESS_KEY_ID=changeme --from-literal AWS_SECRET_ACCESS_KEY=changeme --from-literal AWS_SESSION_TOKEN=\"\" --from-literal aws-account=changeme --from-literal aws-assume-role=changeme --from-literal aws-region=changeme"
- system "kubectl patch secret -n kube-system registry-creds-ecr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"ecr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
- system "kubectl create secret generic -n kube-system registry-creds-gcr --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\" --from-literal=gcrurl=\"https://eu.gcr.io\""
- system "kubectl patch secret -n kube-system registry-creds-gcr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"gcr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
- system "kubectl create secret generic -n kube-system registry-creds-acr --from-literal ACR_PASSWORD=changeme --from-literal ACR_CLIENT_ID=changeme --from-literal ACR_URL=changeme"
- system "kubectl patch secret -n kube-system registry-creds-acr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"acr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
- system "#{minikube} addons enable registry-creds"
- system "#{minikube} addons enable ingress"
- system "kubectl rollout status -n kube-system deployment/registry-creds"
- system "kubectl rollout status -n kube-system deployment/nginx-ingress-controller"
- wait_for_gcr_secret
- system "kubectl apply -f ~/development/spend-cloud/k8s/"
- post_start
+ def delete_stalled_pods(feedback: false)
+ stalled_pods = pods.select { |pod| pod[:stalled] }
+
+ if stalled_pods.empty?
+ puts "There are no stalled pods.".green if feedback
+ else
+ run_command "kubectl delete pods #{stalled_pods.map { |pod| pod[:name] } .join(" ")}"
+ end
end
def start
- system "#{minikube} start --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=16G"
- system "#{minikube} ssh -- 'sudo su -c \"echo 10048576 > /proc/sys/fs/inotify/max_user_watches\"'"
+ if Sct::Helpers.operatingSystem == Sct::Helpers::MAC_OS
+ run_command "#{minikube} start --cpus=$(sysctl -n hw.ncpu) --memory=8G"
+ else
+ run_command "#{minikube} start --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=10G"
+ end
+ run_command "#{minikube} ssh -- 'sudo su -c \"echo 10048576 > /proc/sys/fs/inotify/max_user_watches\"'"
update_config
end
def post_start
- system "kubectl rollout status deployment/spend-cloud-api"
- system "sudo sct hostfile"
- puts "\nāļø You can visit your environment at š https://spend-cloud.spend.cloud.local š (might still take a few minutes)"
+ wait_for_pods
+ run_command "sudo sct hostfile"
+ puts "\nāļø You can visit your environment at š https://spend-cloud.spend.cloud.local š"
end
+ def create_secrets
+ run_command "kubectl create secret generic gcloud-credentials --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\""
+ run_command "kubectl create secret generic -n kube-system registry-creds-dpr --from-literal DOCKER_PRIVATE_REGISTRY_PASSWORD=changeme --from-literal DOCKER_PRIVATE_REGISTRY_SERVER=changeme --from-literal DOCKER_PRIVATE_REGISTRY_USER=changeme"
+ run_command "kubectl patch secret -n kube-system registry-creds-dpr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"dpr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
+ run_command "kubectl create secret generic -n kube-system registry-creds-ecr --from-literal AWS_ACCESS_KEY_ID=changeme --from-literal AWS_SECRET_ACCESS_KEY=changeme --from-literal AWS_SESSION_TOKEN=\"\" --from-literal aws-account=changeme --from-literal aws-assume-role=changeme --from-literal aws-region=changeme"
+ run_command "kubectl patch secret -n kube-system registry-creds-ecr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"ecr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
+ run_command "kubectl create secret generic -n kube-system registry-creds-gcr --from-file=\"$(echo ~)/.config/gcloud/application_default_credentials.json\" --from-literal=gcrurl=\"https://eu.gcr.io\""
+ run_command "kubectl patch secret -n kube-system registry-creds-gcr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"gcr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
+ run_command "kubectl create secret generic -n kube-system registry-creds-acr --from-literal ACR_PASSWORD=changeme --from-literal ACR_CLIENT_ID=changeme --from-literal ACR_URL=changeme"
+ run_command "kubectl patch secret -n kube-system registry-creds-acr -p='{\"metadata\": {\"labels\": { \"app\": \"registry-creds\", \"cloud\": \"acr\", \"kubernetes.io/minikube-addons\": \"registry-creds\"}}}'"
+ end
+
def wait_for_gcr_secret
puts "Waiting for Google Cloud Registry secret to become available...".yellow
- while true
- secrets = `kubectl get secrets`
+ while ! `kubectl get secrets`.include? "gcr-secret"
+ sleep 5
+ end
- if secrets.include? "gcr-secret"
- puts "Google Cloud Registry secret is now available.".green
- break
- else
- sleep 1
- end
+ puts "Google Cloud Registry secret is now available.".green
+ end
+
+ def wait_for_ingress_ip
+ puts "Waiting for ingress IP to become available...".yellow
+
+ while `kubectl describe ingress | grep "Address" | awk '{print $2}'`.empty?
+ sleep 5
+ end
+
+ puts "Ingress IP is now available.".green
+ end
+
+ def wait_for_pods
+ puts "Waiting for pods to become ready...".yellow
+
+ while ! pods.all? { |pod| pod[:status] == "Running" }
+ delete_stalled_pods
+
+ sleep 5
+ end
+
+ puts "Pods are now ready.".green
+ end
+
+ def pods(namespace = nil)
+ if namespace
+ output = `kubectl get pods -n #{namespace}`
+ else
+ output = `kubectl get pods`
+ end
+
+ # split output lines
+ lines = output.split "\n"
+
+ # exclude first line (table header)
+ lines = lines[1..-1]
+
+ # get name and status of each pod
+ lines.map do |line|
+ columns = line.split(" ")
+
+ name = columns[0]
+ status = columns[2]
+ stalled = status == "ErrImagePull" || status == "ImagePullBackOff"
+
+ {
+ name: name,
+ status: status,
+ stalled: stalled
+ }
+ end
+ end
+
+ def run_command command
+ if ! system command
+ raise command.red
end
end
def minikube
if Sct::Helpers.operatingSystem == Sct::Helpers::WINDOWS