|
| 1 | +#!/usr/bin/env Rscript |
| 2 | +# Copyright (c) 2019 Intel Corporation |
| 3 | +# |
| 4 | +# SPDX-License-Identifier: Apache-2.0 |
| 5 | + |
| 6 | +# Display details for the 'Nodes within Kubernetes cluster'. |
| 7 | + |
| 8 | +suppressMessages(suppressWarnings(library(tidyr))) # for gather(). |
| 9 | +library(tibble) |
| 10 | +suppressMessages(suppressWarnings(library(plyr))) # rbind.fill |
| 11 | + # So we can plot multiple graphs |
| 12 | +library(gridExtra) # together. |
| 13 | +suppressMessages(suppressWarnings(library(ggpubr))) # for ggtexttable. |
| 14 | +suppressMessages(library(jsonlite)) # to load the data. |
| 15 | + |
| 16 | +# A list of all the known results files we might find the information inside. |
| 17 | +resultsfiles=c( |
| 18 | + "k8s-scaling.json" |
| 19 | + ) |
| 20 | + |
| 21 | +stats=c() |
| 22 | +stats_names=c() |
| 23 | +max_char_name_node=18 |
| 24 | + |
| 25 | +# list for each dirstats |
| 26 | +dirstats_list=list() |
| 27 | +j=1 |
| 28 | + |
| 29 | +# For each set of results |
| 30 | +for (currentdir in resultdirs) { |
| 31 | + dirstats=c() |
| 32 | + for (resultsfile in resultsfiles) { |
| 33 | + fname=paste(inputdir, currentdir, resultsfile, sep="/") |
| 34 | + if ( !file.exists(fname)) { |
| 35 | + next |
| 36 | + } |
| 37 | + |
| 38 | + # Derive the name from the test result dirname |
| 39 | + datasetname=basename(currentdir) |
| 40 | + |
| 41 | + # Import the data |
| 42 | + fdata=fromJSON(fname) |
| 43 | + |
| 44 | + if (length(fdata$'kubectl-version') != 0 ) { |
| 45 | + numnodes= nrow(fdata$'kubectl-get-nodes'$items) |
| 46 | + for (i in 1:numnodes) { |
| 47 | + node_i=fdata$'kubectl-get-nodes'$items[i,] |
| 48 | + node_info=fdata$'socketsPerNode'[i,] |
| 49 | + |
| 50 | + # Substring node name so it fits properly into final table |
| 51 | + node_name=node_i$metadata$name |
| 52 | + if ( nchar(node_name) >= max_char_name_node) { |
| 53 | + dirstats=tibble("Node \nname"=as.character(substring(node_name, 1, max_char_name_node))) |
| 54 | + } else { |
| 55 | + dirstats=tibble("Node \nname"=as.character(node_name)) |
| 56 | + } |
| 57 | + |
| 58 | + dirstats=cbind(dirstats, "CPUs"=as.character(node_i$status$capacity$cpu)) |
| 59 | + dirstats=cbind(dirstats, "Memory"=as.character(node_i$status$capacity$memory)) |
| 60 | + dirstats=cbind(dirstats, "Max \nPods"=as.character(node_i$status$capacity$pods)) |
| 61 | + dirstats=cbind(dirstats, "Count \nsockets"=as.character(node_info$num_sockets)) |
| 62 | + dirstats=cbind(dirstats, "Have \nhypervisor"=as.character(node_info$hypervisor)) |
| 63 | + |
| 64 | + dirstats=cbind(dirstats, "kernel"=as.character(node_i$status$nodeInfo$kernelVersion)) |
| 65 | + dirstats=cbind(dirstats, "OS"=as.character(node_i$status$nodeInfo$osImage)) |
| 66 | + dirstats=cbind(dirstats, "Test"=as.character(datasetname)) |
| 67 | + |
| 68 | + dirstats_list[[j]]=dirstats |
| 69 | + j=j+1 |
| 70 | + } |
| 71 | + complete_data = do.call(rbind, dirstats_list) |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + if ( length(complete_data) == 0 ) { |
| 76 | + warning(paste("No valid data found for directory ", currentdir)) |
| 77 | + } |
| 78 | + |
| 79 | + # use plyr rbind.fill so we can combine disparate version info frames |
| 80 | + stats=rbind.fill(stats, complete_data) |
| 81 | + stats_names=rbind(stats_names, datasetname) |
| 82 | +} |
| 83 | +# Build us a text table of numerical results |
| 84 | +# Set up as left hand justify, so the node data indent renders. |
| 85 | +tablefontsize=8 |
| 86 | +tbody.style = tbody_style(hjust=0, x=0.1, size=tablefontsize) |
| 87 | +stats_plot = suppressWarnings(ggtexttable(data.frame(complete_data, check.names=FALSE), |
| 88 | + theme=ttheme(base_size=tablefontsize, tbody.style=tbody.style), |
| 89 | + rows=NULL)) |
| 90 | + |
| 91 | +# It may seem odd doing a grid of 1x1, but it should ensure we get a uniform format and |
| 92 | +# layout to match the other charts and tables in the report. |
| 93 | +master_plot = grid.arrange(stats_plot, |
| 94 | + nrow=1, |
| 95 | + ncol=1 ) |
0 commit comments