cluster/lib/cluster/runner.rb in sct-0.1.35 vs cluster/lib/cluster/runner.rb in sct-1.0.0

- old
+ new

@@ -1,343 +1,73 @@ module Cluster - class Runner + class Runner - def start - SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on - - existing_cluster = cluster_exists? - - start_cluster - - 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 - create_keycloak_database_user - run_command "kubectl apply -f ~/development/spend-cloud/k8s/keycloak-server.yml" - wait_for_pods - run_command "kubectl apply -f ~/development/spend-cloud/k8s/" - end - - post_start + def run command, options = {} + begin + if !system command, options + raise command.red end + rescue Interrupt + # user pressed Ctrl+C, do nothing + end + end - def stop - run_command "minikube stop" - end + def run_dc command, options = {} + run "docker-compose -f ~/development/spend-cloud/docker-compose.yml #{command}", options + end - def restart - SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on + def start args, options + if options.pull + run_dc "pull" + end - stop - start - end + if options.build + run_dc "build #{options.pull ? "--pull" : ""}" + end - def delete - run_command "minikube delete" - end + run_dc "up --detach" - def reset - SctCore::Helper.ensure_windows_administrator # "sct hostfile" will need it later on + if options.pull or options.build + system "docker image prune -f" + end - delete - start - end + UI.success("\nāœ”ļø You can visit your environment at šŸ‘‰ https://spend-cloud.dev.spend.cloud šŸ‘Œ") + end - def status - print_contexts - print_minikube_status + def stop + run_dc "down --remove-orphans" + end - 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 restart + run_dc "restart" + end - def update_config - run_command "kubectl config use-context minikube" + def delete + run_dc "down --remove-orphans -v" + end - 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 reset args, options + delete + start args, options + end - def apply_deployments - run_command "kubectl apply -f ~/development/spend-cloud/k8s/" - end + def pull + run_dc "pull" + run "docker image prune -f" + end + def status + run_dc "ps" + end - def cluster_exists? - if system "minikube status", { out: "/dev/null" } - # cluster exists and is running - return true - end + def logs args, options + command = "logs" - if $?.exitstatus == 85 - # cluster does not exist - return false - end + command << " --follow" if options.f or options.follow + command << " --timestamps" if options.t or options.timestamps + command << " --tail #{options.tail}" if options.tail - # cluster exists but is stopped - return true - end - - def start_cluster - if SctCore::Helper.operatingSystem == SctCore::Helper::MAC_OS - run_command "minikube start --driver=hyperkit --vm=true --cpus=$(sysctl -n hw.ncpu) --memory=8G" - else - run_command "minikube start --driver=docker --cpus=$(cat /proc/cpuinfo | grep processor | wc -l) --memory=3G" - end - update_config - end - - def post_start - wait_for_pods - copy_proactive_accounts_file - if SctCore::Helper.operatingSystem == SctCore::Helper::UBUNTU - UI.success("\nAdding SSH tunnel to port 443!") - run_command "sudo ssh -f -N -i $(minikube ssh-key) docker@$(minikube ip) -L 443:127.0.0.1:443" - end -# 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.dev.spend.cloud šŸ‘Œ") - end - - def enable_addons - enable_addon "registry-creds" - enable_addon "ingress" - end - - def enable_addon(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]}" - end - - def wait_for_pods - UI.important("Waiting for pods to become ready...") - - previous_lines = 0 - - while ! pods.all? { |pod| pod[:ready] } - pods_status_lines = get_pods_status.to_s.lines.map { |line| line.chomp } - - current_lines = pods_status_lines.length - - line_difference = current_lines - previous_lines - - 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 - - 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 - - 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 - - previous_lines = current_lines - - sleep 5 - end - - previous_lines.times do - print "\033[1A\033[K" # move the cursor up a line and clear the line - end - - UI.success("Pods are now ready.") - end - - def deployments(namespace = "default") - output = `kubectl get deployments -n #{namespace}` - - # 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] - - { - name: name - } - end - end - - def pods(namespace = "default") - output = `kubectl get pods -n #{namespace}` - - # 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] - ready = columns[1].split("/").reduce { |l, r| l == r } - replicas = columns[1] - status = columns[2] - - { - name: name, - ready: ready, - replicas: replicas, - status: status - } - end - 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 - UI.important("Waiting for Google Cloud Registry secret to become available...") - - while ! `kubectl get secrets`.include? "gcr-secret" - sleep 5 - end - - UI.success("Google Cloud Registry secret is now available.") - end - - def wait_for_ingress_ip - UI.important("Waiting for ingress IP to become available...") - - while `kubectl describe ingress | grep "Address" | awk '{print $2}'`.empty? - sleep 5 - end - - UI.success("Ingress IP is now available.") - end - - def print_contexts - output = `kubectl config get-contexts` - - lines = output.split "\n" - lines = lines[1..-1] - - rows = lines.map do |line| - columns = line.split(" ") - - current_context = columns[0] == "*" ? "Yes".green : "No".red - - [columns[2], current_context] - end - - 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 = `minikube status` - - lines = output.split "\n" - - rows = lines.map do |line| - columns = line.split(" ") - - [columns[0][0..-2], columns[1]] - end - end - - def print_pods_status(namespace = "default") - output = get_pods_status(namespace) - - puts output if output - end - - def get_pods_status(namespace = "default") - rows = pods(namespace).map do |pod| - status = pod[:status] - replicas = pod[:replicas] - - [ - pod[:name], - status == "Running" ? status.green : status.red, - pod[:ready] ? replicas.green : replicas.red - ] - end - - if rows.empty? - return - end - - return Terminal::Table.new title: "Pods (namespace: #{namespace})".green, headings: ['Name', 'Status', 'Replicas ready'], rows: rows - end - - def copy_proactive_accounts_file - container_name = "proactive-config" - pod_id = pods().select {|pod| pod[:name].start_with?(container_name)}.first[:name] - - begin - UI.important("Checking ProActive accounts file...") - run_command "kubectl exec #{pod_id} -- test -e /data/proactive_accounts.ini", [:out, :err] => File::NULL - rescue => e - UI.important("Copying ProActive accounts file to deployments...") - src_path = "#{Dir.home()}/development/spend-cloud/k8s/conf/proactive_accounts.ini" - command = "kubectl cp #{src_path} #{pod_id}:/data/proactive_accounts.ini -c #{container_name}" - run_command command - end - - UI.success("ProActive accounts file is available") - end - - def create_keycloak_database_user - container_name = "mysql-service" - pod_id = pods().select {|pod| pod[:name].start_with?(container_name)}.first[:name] - - UI.important("Creating keycloak user") - create_user = 'CREATE USER "keycloak"@"%" IDENTIFIED BY "keycloak";' - run_command "kubectl exec #{pod_id} -- mysql -e '#{create_user}' >> /dev/null" - - UI.important("Creating keycloak database") - create_database = "CREATE DATABASE keycloak CHARACTER SET utf8 COLLATE UTF8_UNICODE_CI;" - run_command "kubectl exec #{pod_id} -- mysql -e '#{create_database}' >> /dev/null" - - UI.important("Granting privileges to keycloak user") - grant_privileges = 'GRANT ALL PRIVILEGES ON keycloak.* TO "keycloak"@"%";' - run_command "kubectl exec #{pod_id} -- mysql -e '#{grant_privileges}' >> /dev/null" - end - - def run_command command, options = {} - if ! system command, options - raise command.red - end - end + run_dc "#{command} #{args.join " "}" end + + end end