diff --git a/Dockerfile b/Dockerfile
index 93fe7db..24473b3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -43,7 +43,7 @@ COPY confs/redis/redis.conf /etc/redis/redis.conf
# Configure Nginx and KubeInvaders conf
RUN sed -i.bak 's/listen\(.*\)80;/listen 8081;/' /etc/nginx/conf.d/default.conf
-RUN mkdir /usr/local/openresty/nginx/conf/kubeinvaders
+RUN mkdir -p /usr/local/openresty/nginx/conf/kubeinvaders/data
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY nginx/KubeInvaders.conf /etc/nginx/conf.d/KubeInvaders.conf
RUN chmod g+rwx /var/cache/nginx /var/run /var/log/nginx /etc/nginx/conf.d
@@ -58,6 +58,7 @@ COPY scripts/chaos-node.lua /usr/local/openresty/nginx/conf/kubeinvaders/chaos-n
COPY scripts/chaos-containers.lua /usr/local/openresty/nginx/conf/kubeinvaders/chaos-containers.lua
COPY scripts/programming_mode.lua /usr/local/openresty/nginx/conf/kubeinvaders/programming_mode.lua
COPY scripts/config_kubeinv.lua /usr/local/openresty/lualib/config_kubeinv.lua
+COPY scripts/data/codenames.txt /usr/local/openresty/nginx/conf/kubeinvaders/data/codenames.txt
# Copy Python helpers
COPY scripts/programming_mode /opt/programming_mode/
@@ -70,4 +71,4 @@ EXPOSE 8080
ENV PATH=/usr/local/openresty/nginx/sbin:$PATH
COPY ./entrypoint.sh /
RUN chmod a+rwx ./entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
\ No newline at end of file
+ENTRYPOINT ["/entrypoint.sh"]
diff --git a/html5/index.html b/html5/index.html
index 803996d..bc38f40 100644
--- a/html5/index.html
+++ b/html5/index.html
@@ -338,17 +338,21 @@
diff --git a/html5/kubeinvaders.js b/html5/kubeinvaders.js
index df4f275..40786e4 100644
--- a/html5/kubeinvaders.js
+++ b/html5/kubeinvaders.js
@@ -82,6 +82,11 @@ var namespacesJumpStaus = 'Disabled';
var latest_preset_name = "";
var latest_preset_lang = "";
+var codename = getCodeName();
+const codename_regex = /chaos-codename:\ [a-zA-Z_]*/g;
+const chaos_job_regex = /chaos_jobs_status.*/g;
+var codename_configured = false;
+var chaos_jobs_status = new Map();
function isJsonString(str) {
try {
@@ -92,11 +97,26 @@ function isJsonString(str) {
return true;
}
+function getCodeName() {
+ var oReq = new XMLHttpRequest();
+ oReq.onreadystatechange = function () {
+ if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
+ codename = this.responseText.trim();
+ if (codename == "") {
+ $('#alert_placeholder').replaceWith(alert_div + 'Error getting codename from backend. ');
+ codename = "error_fix_getcodename_from_backend";
+ }
+ }
+ };;
+ oReq.open("GET", "https://" + clu_endpoint + "/codename");
+ oReq.send();
+}
+
function loadSavedPreset(tool, lang, defaultpreset) {
var oReq = new XMLHttpRequest();
oReq.onreadystatechange = function () {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
- console.log("response of loadSavedPreset: ||" + this.responseText + "||");
+ //console.log("response of loadSavedPreset: ||" + this.responseText + "||");
if (this.responseText.trim() != "nil") {
$("#currentLoadTest").val(this.responseText.trim());
} else {
@@ -114,7 +134,7 @@ function savePreset(action) {
presetLang = latest_preset_lang;
presetName = latest_preset_name;
- console.log("Saving preset. name:" + presetName + ", lang:" + presetName + ", body: " + presetBody);
+ //console.log("Saving preset. name:" + presetName + ", lang:" + presetName + ", body: " + presetBody);
var oReq = new XMLHttpRequest();
oReq.open("POST", "https://" + clu_endpoint + "/chaos/loadpreset/save?name=" + presetName + "&lang=" + presetLang, true);
@@ -123,12 +143,13 @@ function savePreset(action) {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200 && action == "apply") {
// console.log(this.responseText);
// $('#alert_placeholder').replaceWith(this.responseText);
- presetBody = $('#chaosProgramTextArea').text(`jobs:
- ${presetName}:
+ presetBody = $('#chaosProgramTextArea').val(`chaos-codename: ${codename}\njobs:
+ ${presetName}-job:
additional-labels:
- created-by: kubeinvaders
- lang: ${presetLang}
- type: loadtest
+ chaos-controller: kubeinvaders
+ chaos-lang: ${presetLang}
+ chaos-type: loadtest
+ chaos-codename: ${codename}
image: docker.io/luckysideburn/chaos-exec:v1.0.0
command: bash
args:
@@ -136,8 +157,8 @@ function savePreset(action) {
- ${presetLang}
- http://kubeinvaders:8080/${presetLang}_${presetName}
experiments:
-- name: ${presetName}
- job: ${presetName}
+- name: ${presetName}-exp
+ job: ${presetName}-job
loop: 5`);
}
};;
@@ -154,30 +175,44 @@ experiments:
function drawChaosProgramFlow() {
var chaosProgram = "";
chaosProgram = $('#chaosProgramTextArea').text();
- var oReq = new XMLHttpRequest();
+ // var chaosProgramWithCodename = chaosProgram.replace('CODENAME_PLACEHOLDER', codename);
+ // console.log(chaosProgramWithCodename);
+ // $('#chaosProgramTextArea').val(chaosProgramWithCodename);
+
+ var oReq = new XMLHttpRequest();
oReq.open("POST", "https://" + clu_endpoint + "/chaos/programs/json-flow", true);
oReq.onreadystatechange = function () {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
- // console.log(this.responseText);
if (isJsonString(this.responseText)){
var flow = JSON.parse(this.responseText);
- //console.log(flow)
var flow_html = "";
-
let i = 0;
+ var times = "";
+ $('#chaosProgramFlow').html("");
while (i < flow["experiments"].length) {
- flow_html = flow_html + '
' + flow["experiments"][i]["name"] + '(x' + flow["experiments"][i]["loop"] +')
'
- if (i < flow["experiments"].length - 1 ) {
- flow_html = flow_html + '
'
+ if (flow["experiments"][i]["loop"] == 1){
+ times = "once";
+ }
+ else if (flow["experiments"][i]["loop"] == 2) {
+ times = "twice"
+ }
+ else {
+ times = "times"
+ }
+
+ flow_html = flow_html + 'Do ' + flow["experiments"][i]["name"] + ' ' + flow["experiments"][i]["loop"] + ' ' + times + '
';
+ search_job = codename + ":" + flow["experiments"][i]["name"]
+ //console.log("Search " + search_job);
+ for (let [key, value] of chaos_jobs_status) {
+ if (key.search(search_job)) {
+ flow_html = flow_html + '[' + key.split(":")[2] + '] Status: ' + value + '
';
+ }
}
i++;
}
-
- //console.log("FLOWHTML" + flow_html);
-
$('#chaosProgramFlow').html(flow_html);
}
else {
@@ -231,6 +266,13 @@ function getMetrics() {
else if (metric[0] == "pods_not_running_on_selected_ns") {
$('#pods_not_running_on').text(metric[1]);
}
+ else if (metric[0].match(chaos_job_regex)) {
+ metrics_split = metric[0].split(":");
+ chaos_jobs_status.set(metrics_split[1] + ":" + metrics_split[2] + ":" + metrics_split[3], metric[1]);
+ // for (let [key, value] of chaos_jobs_status) {
+ // console.log(key + " = " + value);
+ // }
+ }
else if (metric[0] == "current_chaos_job_pod") {
$('#current_chaos_job_pod').text(metric[1]);
}
@@ -373,6 +415,11 @@ function setChaosContainer() {
function runChaosProgram() {
+ chaosProgram = $('#chaosProgramTextArea').val();
+ chaosProgramWithCodename = chaosProgram.replace(codename_regex, "chaos-codename: " + codename);
+ $('#chaosProgramTextArea').val(chaosProgramWithCodename);
+ codename_configured = true;
+
var now = new Date().toLocaleString().replace(',','')
$('#alert_placeholder4').replaceWith(alert_div + 'Chaos Program launched at ' + now + ' ');
@@ -882,6 +929,14 @@ window.setInterval(function setAliens() {
}, 1000)
window.setInterval(function backgroundTasks() {
+
+ if (!codename_configured) {
+ chaosProgram = $('#chaosProgramTextArea').val();
+ chaosProgramWithCodename = chaosProgram.replace(codename_regex, "chaos-codename: " + codename);
+ $('#chaosProgramTextArea').val(chaosProgramWithCodename);
+ codename_configured = true;
+ }
+
if (game_mode_switch || programming_mode_switch) {
getMetrics()
}
diff --git a/nginx/KubeInvaders.conf b/nginx/KubeInvaders.conf
index 3c1a8de..211b11c 100644
--- a/nginx/KubeInvaders.conf
+++ b/nginx/KubeInvaders.conf
@@ -70,6 +70,54 @@ server {
}
}
+ location /codename {
+ content_by_lua_block {
+ local open = io.open
+
+ local function read_rand_line_from_file(path)
+ local word_array_index = 0
+ local word_array = {}
+ local file = open(path, "rb") -- r read mode and b binary mode
+
+ if not file then return nil end
+ local content = file:read "*a" -- *a or *all reads the whole file
+ file:close()
+
+ for word in string.gmatch(content, "%S+") do
+ word_array[word_array_index] = word
+ word_array_index = word_array_index + 1
+ end
+
+ while (type(rand) ~= "number")
+ do
+ math.randomseed(os.clock()*100000000000)
+ rand = math.random(0, word_array_index - 1)
+ end
+
+ return word_array[rand]
+ end
+
+ local random_word = read_rand_line_from_file("/usr/local/openresty/nginx/conf/kubeinvaders/data/codenames.txt")
+ local redis = require "resty.redis"
+ local red = redis:new()
+ local okredis, errredis = red:connect("unix:/tmp/redis.sock")
+
+ ngx.header['Access-Control-Allow-Origin'] = '*'
+ ngx.header['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
+ ngx.header['Access-Control-Allow-Headers'] = 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'
+ ngx.header['Access-Control-Expose-Headers'] = 'Content-Length,Content-Range';
+
+ while (red:get("programming_mode_codename:" .. random_word) == nil)
+ do
+ random_word = read_rand_line_from_file("/usr/local/openresty/nginx/conf/kubeinvaders/data/codenames.txt")
+ end
+
+ red:set("programming_mode_codename:" .. random_word, "active")
+ ngx.say(random_word)
+
+ }
+ }
+
location /metrics {
default_type text/html;
content_by_lua_block {
@@ -222,7 +270,7 @@ server {
ngx.log(ngx.ERR, "[programming_mode_diagram] write temp file " .. filename)
- yamlfile = io.open(filename, "w")
+ local yamlfile = io.open(filename, "w")
yamlfile:write(data)
yamlfile:close()
diff --git a/scripts/data/codenames.txt b/scripts/data/codenames.txt
new file mode 100644
index 0000000..78b5595
--- /dev/null
+++ b/scripts/data/codenames.txt
@@ -0,0 +1,266 @@
+actinium
+alligator
+alpaca
+aluminum
+americium
+ant
+antelope
+antimony
+ape
+argon
+armadillo
+arsenic
+astatine
+baboon
+badger
+barium
+bat
+bear
+beaver
+bee
+beetle
+berkelium
+beryllium
+bigfoot
+bismuth
+bohrium
+boron
+bromine
+buffalo
+burro
+butterfly
+cadmium
+calcium
+californium
+camel
+carabao
+carbon
+caribou
+cat
+cattle
+cerium
+cesium
+cheetah
+chimpanzee
+chinchilla
+chlorine
+chromium
+cicada
+clam
+cobalt
+cockroach
+cod
+copernicium
+copper
+coyote
+crab
+cricket
+crocodile
+crow
+curium
+darmstadtium
+deer
+dinosaur
+dog
+dolphin
+donkey
+dragon
+dubnium
+duck
+dysprosium
+eagle
+eel
+einsteinium
+elephant
+elk
+erbium
+europium
+fermium
+ferret
+fish
+flerovium
+fluorine
+fly
+fox
+francium
+frog
+gadolinium
+gallium
+gerbil
+germanium
+giraffe
+gnat
+gnu
+goat
+gold
+goldfish
+goose
+gorilla
+grasshopper
+hafnium
+hamster
+hare
+hassium
+hedgehog
+helium
+herring
+hippopotamus
+holmium
+hornet
+horse
+hound
+hydrogen
+hyena
+impala
+indium
+insect
+iodine
+iridium
+iron
+jackal
+jellyfish
+kangaroo
+koala
+kraken
+krypton
+lanthanum
+lawrencium
+lead
+leopard
+lion
+lithium
+livermorium
+lizard
+llama
+locust
+louse
+lutetium
+macaw
+magnesium
+mallard
+mammoth
+manatee
+manganese
+marten
+meitnerium
+mendelevium
+mercury
+mink
+minnow
+mole
+molybdenum
+monkey
+moose
+moscovium
+mosquito
+mouse
+mule
+muskrat
+neodymium
+neon
+neptunium
+nessie
+nickel
+nihonium
+ninja
+niobium
+nitrogen
+nobelium
+oganesson
+osmium
+otter
+ox
+oxygen
+oyster
+palladium
+panda
+phosphorus
+pig
+pirate
+platinum
+platypus
+plutonium
+polonium
+porcupine
+porpoise
+potassium
+praseodymium
+promethium
+protactinium
+pug
+rabbit
+raccoon
+radium
+radon
+rat
+raven
+reindeer
+rhenium
+rhinoceros
+rhodium
+robot
+roentgenium
+rubidium
+ruthenium
+rutherfordium
+salmon
+samarium
+samurai
+sardine
+scandium
+scorpion
+seaborgium
+seal
+selenium
+serval
+shark
+sheep
+silicon
+silver
+skunk
+snail
+snake
+sodium
+spider
+squirrel
+strontium
+sulfur
+swan
+tantalum
+technetium
+tellurium
+tennessine
+terbium
+termite
+thallium
+thorium
+thulium
+tiger
+tin
+titanium
+toad
+trout
+tungsten
+turtle
+unicorn
+uranium
+vanadium
+wallaby
+walrus
+wasp
+weasel
+whale
+wildebeest
+wolf
+wombat
+woodchuck
+worm
+xenon
+yak
+yellowjacket
+ytterbium
+yttrium
+zebra
+zinc
+zirconium
+zombie
diff --git a/scripts/logs_loop/start.py b/scripts/logs_loop/start.py
index 167f1cc..7d3f948 100644
--- a/scripts/logs_loop/start.py
+++ b/scripts/logs_loop/start.py
@@ -200,8 +200,9 @@ while True:
for pod in final_pod_list:
container_list = []
for container in pod.spec.containers:
- if re.search(f"{containers_re}", container.name):
- container_list.append(container.name)
+ if "containers_re" in locals() or "containers_re" in globals():
+ if re.search(f"{containers_re}", container.name):
+ container_list.append(container.name)
for container in container_list:
if webtail_switch or (pod.metadata.labels.get('approle') != None and pod.metadata.labels['approle'] == 'chaosnode' and pod.status.phase != "Pending"):
diff --git a/scripts/metrics_loop/start.py b/scripts/metrics_loop/start.py
index 735e833..e4260b2 100644
--- a/scripts/metrics_loop/start.py
+++ b/scripts/metrics_loop/start.py
@@ -30,16 +30,16 @@ def create_container(image, name, command, args):
return container
-def create_pod_template(pod_name, container):
+def create_pod_template(pod_name, container, job_name):
pod_template = client.V1PodTemplateSpec(
spec=client.V1PodSpec(restart_policy="Never", containers=[container]),
- metadata=client.V1ObjectMeta(name=pod_name, labels={"pod_name": pod_name, "approle": "chaosnode"}),
+ metadata=client.V1ObjectMeta(name=pod_name, labels={"pod-name-prefix": pod_name, "approle": "chaosnode", "job-name": job_name}),
)
return pod_template
def create_job(job_name, pod_template):
- metadata = client.V1ObjectMeta(name=job_name, labels={"job_name": job_name, "approle": "chaosnode"})
+ metadata = client.V1ObjectMeta(name=job_name, labels={"job-name": job_name, "approle": "chaosnode"})
job = client.V1Job(
api_version="batch/v1",
@@ -85,4 +85,10 @@ while True:
if pod.metadata.labels.get('approle') != None and pod.metadata.labels['approle'] == 'chaosnode':
if pod.status.phase == "Pending" or pod.status.phase == "Running":
r.incr('current_chaos_job_pod')
+ if pod.metadata.labels.get('chaos-codename') != None:
+ codename = pod.metadata.labels.get('chaos-codename')
+ job_name = pod.metadata.labels.get('job-name')
+ exp_name = pod.metadata.labels.get('experiment-name')
+ r.set(f"chaos_jobs_status:{codename}:{exp_name}:{job_name}", pod.status.phase)
+
time.sleep(1)
diff --git a/scripts/programming_mode/start.py b/scripts/programming_mode/start.py
index f3717e0..3a3d4ee 100644
--- a/scripts/programming_mode/start.py
+++ b/scripts/programming_mode/start.py
@@ -27,8 +27,8 @@ def create_container(image, name, command, args):
return container
-def create_pod_template(pod_name, additional_labels, container):
- pod_labels = { "app": "kubeinvaders", "pod_name": pod_name, "approle": "chaosnode" }
+def create_pod_template(pod_name, additional_labels, container, exp_name):
+ pod_labels = {"app": "kubeinvaders", "approle": "chaosnode", "experiment-name": exp_name}
pod_labels.update(additional_labels)
pod_template = client.V1PodTemplateSpec(
spec=client.V1PodSpec(restart_policy="Never", containers=[container]),
@@ -38,7 +38,7 @@ def create_pod_template(pod_name, additional_labels, container):
return pod_template
def create_job(job_name, pod_template):
- metadata = client.V1ObjectMeta(name=job_name, labels={"job_name": job_name, "approle": "chaosnode"})
+ metadata = client.V1ObjectMeta(name=job_name, labels={"job-name": job_name, "approle": "chaosnode"})
job = client.V1Job(
api_version="batch/v1",
@@ -100,13 +100,13 @@ for exp in parsed_yaml["experiments"]:
letters = string.ascii_lowercase
rand_suffix = ''.join(random.choice(letters) for i in range(5))
- job_name = f"{exp['name']}-{rand_suffix}"
+ job_name = f"{exp['job']}-{rand_suffix}"
if 'additional-labels' in job_attrs:
logging.info(f"additional-labels = {job_attrs['additional-labels']}")
- pod_template = create_pod_template(exp["name"], job_attrs['additional-labels'], container)
+ pod_template = create_pod_template(f"{exp['name']}-exec", job_attrs['additional-labels'], container, exp["name"])
else:
- pod_template = create_pod_template(exp["name"], {}, container)
+ pod_template = create_pod_template(f"{exp['name']}-exec", {}, container, exp["name"])
logging.info(f"Creating job {job_name}")
job_def = create_job(job_name, pod_template)
@@ -117,6 +117,10 @@ for exp in parsed_yaml["experiments"]:
logging.info(e)
quit()
+ if 'additional-labels' in job_attrs and 'chaos-codename' in job_attrs['additional-labels']:
+ codename = job_attrs['additional-labels']['chaos-codename']
+ r.set(f"chaos_jobs_status:{codename}:{exp['name']}:{exp['job']}", "Created")
+
if r.exists('chaos_node_jobs_total') == 1:
r.incr('chaos_node_jobs_total')
else: