cluster/lib/cluster/runner.rb in sct-0.1.28 vs cluster/lib/cluster/runner.rb in sct-0.1.29
- old
+ new
@@ -1,120 +1,159 @@
module Cluster
class Runner
- def launch
- return UI.error("SCT has not been initialized. Run 'sct init' first.") unless SctCore::Config.exists
+ def start
+ SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on
+
+ existing_cluster = cluster_exists?
+
start_cluster
- 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"
+
+ if existing_cluster
+ run_command "kubectl rollout restart -n kube-system deployment registry-creds"
+ run_command "kubectl rollout status -n kube-system deployment registry-creds"
+ else
+ create_secrets
+ enable_addons
+ 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/"
+ end
+
post_start
end
+ def stop
+ run_command "minikube stop"
+ end
+
+ def restart
+ SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on
+
+ stop
+ start
+ end
+
+ def delete
+ run_command "minikube delete"
+ end
+
+ def reset
+ SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on
+
+ delete
+ start
+ end
+
+ def status
+ print_contexts
+ print_minikube_status
+
+ if get_minikube_status.find_all { |status| status[1] == 'Stopped' }.count == 0
+ print_pods_status("kube-system")
+ print_pods_status
+ else
+ UI.important("Please check your minikube status. If all services are stopped you should start the minikube first.")
+ end
+ end
+
+ def update_config
+ 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 rollout restart -n kube-system deployment coredns"
+ run_command "kubectl rollout status -n kube-system deployment coredns"
+ end
+
+ def apply_deployments
+ run_command "kubectl apply -f ~/development/spend-cloud/k8s/"
+ end
+
+
+ def cluster_exists?
+ if system "minikube status", { out: "/dev/null" }
+ # cluster exists and is running
+ return true
+ end
+
+ if $?.exitstatus == 85
+ # cluster does not exist
+ return false
+ end
+
+ # cluster exists but is stopped
+ return true
+ end
+
def start_cluster
if SctCore::Helper.operatingSystem == SctCore::Helper::MAC_OS
- run_command "#{SctCore::Helper.minikube} start --cpus=$(sysctl -n hw.ncpu) --memory=8G"
+ run_command "minikube start --driver=docker --cpus=$(sysctl -n hw.ncpu) --memory=8G"
else
- run_command "#{SctCore::Helper.minikube} start --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=10G"
+ run_command "minikube start --driver=docker --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=3G"
end
- run_command "#{SctCore::Helper.minikube} ssh -- 'sudo su -c \"echo 10048576 > /proc/sys/fs/inotify/max_user_watches\"'"
update_config
end
def post_start
wait_for_pods
run_command "sudo sct hostfile"
+ run_command "minikube tunnel &", { out: "/dev/null", err: "/dev/null" } if SctCore::Helper::is_windows? # leave this running detached forever in the background
UI.success("\nāļø You can visit your environment at š https://spend-cloud.spend.cloud.local š")
end
- def down
- run_command "#{SctCore::Helper.minikube} stop"
- end
-
- def reset
- run_command "#{SctCore::Helper.minikube} delete"
- start_cluster
- create_secrets
- enable_addons
- 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 enable_addons
enable_addon "registry-creds"
enable_addon "ingress"
end
def enable_addon(addon)
- run_command "#{SctCore::Helper.minikube} addons enable #{addon}"
+ run_command "minikube addons enable #{addon}"
deployment = deployments("kube-system").find { |deployment| deployment[:name].include? addon }
- run_command "kubectl rollout status -n kube-system deployment/#{deployment[:name]}"
+ run_command "kubectl rollout status -n kube-system deployment #{deployment[:name]}"
end
def wait_for_pods
UI.important("Waiting for pods to become ready...")
- while ! pods.all? { |pod| pod[:status] == "Running" }
- delete_stalled_pods
+ previous_lines = 0
- sleep 5
- end
+ while ! pods.all? { |pod| pod[:ready] }
+ pods_status_lines = get_pods_status.to_s.lines.map { |line| line.chomp }
- UI.success("Pods are now ready.")
- end
+ current_lines = pods_status_lines.length
- def delete_stalled_pods(feedback: false)
+ line_difference = current_lines - previous_lines
- return UI.success("No stalled pods found") unless !pods.to_a.empty?
+ if line_difference < 0 # there are now less lines than before
+ line_difference.abs.times do
+ print "\033[1A\033[K" # move the cursor up a line and clear the line
+ end
- stalled_pods = pods.select { |pod| pod[:stalled] }
+ print "\033[#{current_lines}A" # move the cursor all the way up to the start of the table
+ elsif previous_lines > 0
+ print "\033[#{previous_lines}A" # move the cursor all the way up to the start of the table
+ end
- if stalled_pods.empty?
- UI.success("There are no stalled pods.") if feedback
- else
- run_command "kubectl delete pods #{stalled_pods.map { |pod| pod[:name] } .join(" ")}"
- end
- end
-
- def delete_all_pods
- run_command "kubectl delete pods --all"
- end
-
- def delete_pods(args)
- run_command "kubectl delete pods #{args.join(" ")}"
- end
-
- def apply_pods
- run_command "kubectl apply -f ~/development/spend-cloud/k8s/"
- end
-
- def update_config
- if SctCore::Helper.operatingSystem == SctCore::Helper::WINDOWS
- windows_home_path = SctCore::Helper.windowsHomePath
- kube_file_path = windows_home_path+"/.kube/config"
-
- if !File.exists?(kube_file_path)
- return UI.error("#{kube_file_path} doesn't exist")
+ pods_status_lines.each do |line|
+ print "#{line}\033[K#{$/}" # print the content of the line, clear remaining characters and add a new line
end
- run_command "sed -e 's~\\\\~/~g' -e 's~C:~/mnt/c~g' < #{kube_file_path} > ~/.kube/minikube-config"
+ previous_lines = current_lines
- UI.success("#{kube_file_path} copied to ~/.kube/minikube-config")
+ sleep 5
end
- run_command "kubectl config use-context minikube"
+ previous_lines.times do
+ print "\033[1A\033[K" # move the cursor up a line and clear the line
+ end
- run_command "kubectl replace -n kube-system -f #{File.expand_path('resources/corefile.yml', __dir__)}"
- old_list = pods("kube-system").map { |pod| pod[:name] if pod[:name].start_with? "coredns" }.compact
- run_command "kubectl delete pod -n kube-system #{old_list.join(" ")}" unless old_list.to_a.empty?
- run_command "kubectl rollout status -n kube-system deployment/coredns"
+ UI.success("Pods are now ready.")
end
def deployments(namespace = "default")
output = `kubectl get deployments -n #{namespace}`
@@ -148,17 +187,19 @@
# get name and status of each pod
lines.map do |line|
columns = line.split(" ")
name = columns[0]
+ ready = columns[1].split("/").reduce { |l, r| l == r }
+ replicas = columns[1]
status = columns[2]
- stalled = status == "ErrImagePull" || status == "ImagePullBackOff"
{
name: name,
- status: status,
- stalled: stalled
+ ready: ready,
+ replicas: replicas,
+ status: status
}
end
end
def create_secrets
@@ -191,22 +232,10 @@
end
UI.success("Ingress IP is now available.")
end
- def status
- print_contexts
- print_minikube_status
-
- if get_minikube_status.find_all { |status| status[1] == 'Stopped' }.count == 0
- print_pods_status("kube-system")
- print_pods_status
- else
- UI.important("Please check your minikube status. If all services are stopped you should start the minikube first.")
- end
- end
-
def print_contexts
output = `kubectl config get-contexts`
lines = output.split "\n"
lines = lines[1..-1]
@@ -221,16 +250,15 @@
puts Terminal::Table.new title: "Contexts".green, headings: ['Cluster', 'Using context'], rows: rows
end
def print_minikube_status
-
puts Terminal::Table.new title: "Minikube status".green, headings: ['Name', 'Status'], rows: get_minikube_status
end
def get_minikube_status
- output = `#{SctCore::Helper.minikube} status`
+ output = `minikube status`
lines = output.split "\n"
rows = lines.map do |line|
columns = line.split(" ")
@@ -238,28 +266,35 @@
[columns[0][0..-2], columns[1]]
end
end
def print_pods_status(namespace = "default")
+ output = get_pods_status(namespace)
- pods_list = pods(namespace)
+ puts output if output
+ end
- if pods_list.to_a.empty?
- return
- end
+ def get_pods_status(namespace = "default")
+ rows = pods(namespace).map do |pod|
+ status = pod[:status]
+ replicas = pod[:replicas]
- rows = pods_list.map do |pod|
[
pod[:name],
- pod[:status] == "Running" ? pod[:status].green : pod[:status].red
+ status == "Running" ? status.green : status.red,
+ pod[:ready] ? replicas.green : replicas.red
]
end
- puts Terminal::Table.new title: "Pods (namespace: #{namespace})".green, headings: ['Name', 'Status'], rows: rows
+ if rows.empty?
+ return
+ end
+
+ return Terminal::Table.new title: "Pods (namespace: #{namespace})".green, headings: ['Name', 'Status', 'Replicas ready'], rows: rows
end
- def run_command command
- if ! system command
+ def run_command command, options = {}
+ if ! system command, options
raise command.red
end
end
end
end