From 63f0f8774b7903f46d18b80f6b3348490fa2e109 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Fri, 21 May 2021 16:11:00 -0700 Subject: [PATCH 001/122] Create script to collect log data. --- hack/test-flake-chart/collect_data.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 hack/test-flake-chart/collect_data.sh diff --git a/hack/test-flake-chart/collect_data.sh b/hack/test-flake-chart/collect_data.sh new file mode 100755 index 0000000000..1707ab3028 --- /dev/null +++ b/hack/test-flake-chart/collect_data.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Create temp path for partial data (storing everything but the commit date.) +PARTIAL_DATA_PATH=$(mktemp) +# Write +echo "Partial path: $PARTIAL_DATA_PATH" 1>&2 + +# Print header. +printf "Commit Hash,Commit Date,Environment,Test,Status\n" + +# 1) "cat" together all summary files. +# 2) Turn each test in each summary file to a CSV line containing its commit hash, environment, test, and status. +# 3) Copy partial data to $PARTIAL_DATA_PATH to join with date later. +# 4) Extract only commit hash for each row +# 5) Make the commit hashes unique (we assume that gsutil cats files from the same hash next to each other). +# Also force buffering to occur per line so remainder of pipe can continue to process. +# 6) Execute git log for each commit to get the date of each. +# 7) Join dates with test data. +gsutil cat gs://minikube-builds/logs/master/*/*_summary.json \ +| jq -r '({commit: .Detail.Details, environment: .Detail.Name, test: .PassedTests[]?, status: "Passed"},{commit: .Detail.Details, environment: .Detail.Name, test: .FailedTests[]?, status: "Failed"},{commit: .Detail.Details, environment: .Detail.Name, test: .SkippedTests[]?, status: "Skipped"}) | .commit + "," + .environment + "," + .test + "," + .status' \ +| tee $PARTIAL_DATA_PATH \ +| sed -r -n 's/^([^,]+),.*/\1/p' \ +| stdbuf -oL -eL uniq \ +| xargs -I {} git log -1 --pretty=format:"{},%as%n" {} \ +| join -t "," - $PARTIAL_DATA_PATH From abdbfa63b60b5442a72ec1a15a12770f2d70c662 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 24 May 2021 11:15:56 -0700 Subject: [PATCH 002/122] Create initial HTML and JS for flake rate site. --- hack/test-flake-chart/flake_chart.html | 10 ++++++++++ hack/test-flake-chart/flake_chart.js | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 hack/test-flake-chart/flake_chart.html create mode 100644 hack/test-flake-chart/flake_chart.js diff --git a/hack/test-flake-chart/flake_chart.html b/hack/test-flake-chart/flake_chart.html new file mode 100644 index 0000000000..333b61f4cf --- /dev/null +++ b/hack/test-flake-chart/flake_chart.html @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js new file mode 100644 index 0000000000..274a7429b9 --- /dev/null +++ b/hack/test-flake-chart/flake_chart.js @@ -0,0 +1,18 @@ + +function displayError(message) { + console.error(message); +} + +async function init() { + const response = await fetch("content.txt"); + if (!response.ok) { + const responseText = await response.text(); + displayError(`Failed to fetch data from GCS bucket. Error: ${responseText}`); + return; + } + + const responseText = await response.text(); + console.log(responseText); +} + +init(); From b33e27243501ae755298ed15cd28bf67460fc56a Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 24 May 2021 13:20:20 -0700 Subject: [PATCH 003/122] Create basic parsing of CSV test data. --- hack/test-flake-chart/flake_chart.js | 68 ++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index 274a7429b9..f823394598 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -1,18 +1,80 @@ +// Displays an error message to the UI. Any previous message will be erased. function displayError(message) { console.error(message); } +// Creates a generator that reads the response body one line at a time. +async function* bodyByLinesIterator(response) { + // TODO: Replace this with something that actually reads the body line by line + // (since the file can be big). + const lines = (await response.text()).split("\n"); + for (let line of lines) { + // Skip any empty lines (most likely at the end). + if (line !== "") { + yield line; + } + } +} + +// Determines whether `str` matches at least one value in `enumObject`. +function isValidEnumValue(enumObject, str) { + for (const enumKey in enumObject) { + if (enumObject[enumKey] === str) { + return true; + } + } + return false; +} + +// Enum for test status. +const testStatus = { + PASSED: "Passed", + FAILED: "Failed", + SKIPPED: "Skipped" +} + async function init() { - const response = await fetch("content.txt"); + const response = await fetch("data.csv"); if (!response.ok) { const responseText = await response.text(); displayError(`Failed to fetch data from GCS bucket. Error: ${responseText}`); return; } - const responseText = await response.text(); - console.log(responseText); + const lines = bodyByLinesIterator(response); + // Consume the header to ensure the data has the right number of fields. + const header = (await lines.next()).value; + if (header.split(",").length != 5) { + displayError(`Fetched CSV data contains wrong number of fields. Expected: 5. Actual Header: "${header}"`); + return; + } + + const testData = []; + for await (const line of lines) { + const splitLine = line.split(","); + if (splitLine.length != 5) { + console.warn(`Found line with wrong number of fields. Actual: ${splitLine.length} Expected: 5. Line: "${line}"`); + continue; + } + if (!isValidEnumValue(testStatus, splitLine[4])) { + console.warn(`Invalid test status provided. Actual: ${splitLine[4]} Expected: One of ${Object.values(testStatus).join(", ")}`); + continue; + } + testData.push({ + commit: splitLine[0], + date: new Date(splitLine[1]), + environment: splitLine[2], + name: splitLine[3], + status: splitLine[4] + }); + } + if (testData.length == 0) { + displayError("Fetched CSV data is empty or poorly formatted."); + return; + } + + console.log(testData); } init(); From b45b4c9a0bdb6ffb2fe945a5557b2fac2f033678 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 25 May 2021 13:19:03 -0700 Subject: [PATCH 004/122] Include Google Charts. Refactor to wait for Google Charts and test data loading at the same time. --- hack/test-flake-chart/flake_chart.html | 1 + hack/test-flake-chart/flake_chart.js | 27 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/hack/test-flake-chart/flake_chart.html b/hack/test-flake-chart/flake_chart.html index 333b61f4cf..5299da4a13 100644 --- a/hack/test-flake-chart/flake_chart.html +++ b/hack/test-flake-chart/flake_chart.html @@ -1,6 +1,7 @@ + diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index f823394598..08fc48ec0d 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -34,20 +34,18 @@ const testStatus = { SKIPPED: "Skipped" } -async function init() { +async function loadTestData() { const response = await fetch("data.csv"); if (!response.ok) { const responseText = await response.text(); - displayError(`Failed to fetch data from GCS bucket. Error: ${responseText}`); - return; + throw `Failed to fetch data from GCS bucket. Error: ${responseText}`; } const lines = bodyByLinesIterator(response); // Consume the header to ensure the data has the right number of fields. const header = (await lines.next()).value; if (header.split(",").length != 5) { - displayError(`Fetched CSV data contains wrong number of fields. Expected: 5. Actual Header: "${header}"`); - return; + throw `Fetched CSV data contains wrong number of fields. Expected: 5. Actual Header: "${header}"`; } const testData = []; @@ -70,10 +68,25 @@ async function init() { }); } if (testData.length == 0) { - displayError("Fetched CSV data is empty or poorly formatted."); + throw "Fetched CSV data is empty or poorly formatted."; + } + return testData; +} + +async function init() { + google.charts.load('current', {'packages': ['corechart']}); + let testData; + try { + // Wait for Google Charts to load, and for test data to load. + // Only store the test data (at index 1) into `testData`. + testData = (await Promise.all([ + new Promise(resolve => google.charts.setOnLoadCallback(resolve)), + loadTestData() + ]))[1]; + } catch(err) { + displayError(err); return; } - console.log(testData); } From 328d54ef639decece23e59da61116738d36526a7 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 25 May 2021 16:20:56 -0700 Subject: [PATCH 005/122] Create first flake rate chart. --- hack/test-flake-chart/flake_chart.html | 2 +- hack/test-flake-chart/flake_chart.js | 71 ++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/hack/test-flake-chart/flake_chart.html b/hack/test-flake-chart/flake_chart.html index 5299da4a13..f39859daff 100644 --- a/hack/test-flake-chart/flake_chart.html +++ b/hack/test-flake-chart/flake_chart.html @@ -4,7 +4,7 @@ - +
diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index 08fc48ec0d..f042a2fdd1 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -74,7 +74,7 @@ async function loadTestData() { } async function init() { - google.charts.load('current', {'packages': ['corechart']}); + google.charts.load('current', { 'packages': ['corechart'] }); let testData; try { // Wait for Google Charts to load, and for test data to load. @@ -83,11 +83,76 @@ async function init() { new Promise(resolve => google.charts.setOnLoadCallback(resolve)), loadTestData() ]))[1]; - } catch(err) { + } catch (err) { displayError(err); return; } - console.log(testData); + + const data = new google.visualization.DataTable(); + data.addColumn('date', 'Date'); + data.addColumn('number', 'Flake Percentage'); + data.addColumn({ type: 'string', label: 'Commit Hash', role: 'tooltip', 'p': { 'html': true } }); + + const desiredTest = "TestFunctional/parallel/LogsCmd", desiredEnvironment = "Docker_Linux_containerd"; + + const average = arr => { + return arr.length === 0 ? 0 : arr.reduce((sum, value) => sum + value, 0) / arr.length; + }; + + const groups = + Array.from(testData + // Filter to only contain unskipped runs of the requested test and requested environment. + .filter(test => test.name === desiredTest && test.environment === desiredEnvironment && test.status !== testStatus.SKIPPED) + // Group by run date. + .reduce((groups, test) => { + // Convert Date to time number since hashing by Date does not work. + const dateValue = test.date.getTime(); + if (groups.has(dateValue)) { + groups.get(dateValue).push(test); + } else { + groups.set(dateValue, [test]); + } + return groups + }, new Map()) + // Get all entries (type of [[time number, [test]]]). + .entries() + ) + // Turn time number back to the corresponding Date. + .map(([dateValue, tests]) => ({ date: new Date(dateValue), tests })); + + data.addRows( + groups + // Sort by run date, past to future. + .sort((a, b) => a.date - b.date) + // Map each group to all variables need to format the rows. + .map(({ date, tests }) => ({ + date, // Turn time number back to corresponding date. + flakeRate: average(tests.map(test => test.status === testStatus.FAILED ? 100 : 0)), // Compute average of runs where FAILED counts as 100%. + commitHashes: tests.map(test => ({ hash: test.commit, status: test.status })) // Take all hashes and status' of tests in this group. + })) + .map(groupData => [ + groupData.date, + groupData.flakeRate, + `
+ ${groupData.date.toString()}
+ Flake Percentage: ${groupData.flakeRate.toFixed(2)}%
+ Hashes:
+ ${groupData.commitHashes.map(({ hash, status }) => ` - ${hash} (${status})`).join("
")} +
` + ]) + ); + + const options = { + title: `Flake Rate by day of ${desiredTest} on ${desiredEnvironment}`, + width: 900, + height: 500, + pointSize: 10, + pointShape: "circle", + vAxis: { minValue: 0, maxValue: 1 }, + tooltip: { trigger: "selection", isHtml: true } + }; + const chart = new google.visualization.LineChart(document.getElementById('chart_div')); + chart.draw(data, options); } init(); From 2e5ea59774fb5864dbc6cf85f2a3612473f2c694 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 26 May 2021 09:36:44 -0700 Subject: [PATCH 006/122] Refactor data cleaning. --- hack/test-flake-chart/flake_chart.js | 54 ++++++++++++++-------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index f042a2fdd1..58b119ea22 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -73,6 +73,24 @@ async function loadTestData() { return testData; } +// Computes the average of an array of numbers. +Array.prototype.average = function () { + return this.length === 0 ? 0 : this.reduce((sum, value) => sum + value, 0) / this.length; +}; + +// Groups array elements by keys obtained through `keyGetter`. +Array.prototype.groupBy = function (keyGetter) { + return Array.from(this.reduce((mapCollection, element) => { + const key = keyGetter(element); + if (mapCollection.has(key)) { + mapCollection.get(key).push(element); + } else { + mapCollection.set(key, [element]); + } + return mapCollection; + }, new Map()).values()); +}; + async function init() { google.charts.load('current', { 'packages': ['corechart'] }); let testData; @@ -95,39 +113,19 @@ async function init() { const desiredTest = "TestFunctional/parallel/LogsCmd", desiredEnvironment = "Docker_Linux_containerd"; - const average = arr => { - return arr.length === 0 ? 0 : arr.reduce((sum, value) => sum + value, 0) / arr.length; - }; - - const groups = - Array.from(testData - // Filter to only contain unskipped runs of the requested test and requested environment. - .filter(test => test.name === desiredTest && test.environment === desiredEnvironment && test.status !== testStatus.SKIPPED) - // Group by run date. - .reduce((groups, test) => { - // Convert Date to time number since hashing by Date does not work. - const dateValue = test.date.getTime(); - if (groups.has(dateValue)) { - groups.get(dateValue).push(test); - } else { - groups.set(dateValue, [test]); - } - return groups - }, new Map()) - // Get all entries (type of [[time number, [test]]]). - .entries() - ) - // Turn time number back to the corresponding Date. - .map(([dateValue, tests]) => ({ date: new Date(dateValue), tests })); + const groups = testData + // Filter to only contain unskipped runs of the requested test and requested environment. + .filter(test => test.name === desiredTest && test.environment === desiredEnvironment && test.status !== testStatus.SKIPPED) + .groupBy(test => test.date.getTime()); data.addRows( groups // Sort by run date, past to future. - .sort((a, b) => a.date - b.date) + .sort((a, b) => a[0].date - b[0].date) // Map each group to all variables need to format the rows. - .map(({ date, tests }) => ({ - date, // Turn time number back to corresponding date. - flakeRate: average(tests.map(test => test.status === testStatus.FAILED ? 100 : 0)), // Compute average of runs where FAILED counts as 100%. + .map(tests => ({ + date: tests[0].date, // Get one of the dates from the tests (which will all be the same). + flakeRate: tests.map(test => test.status === testStatus.FAILED ? 100 : 0).average(), // Compute average of runs where FAILED counts as 100%. commitHashes: tests.map(test => ({ hash: test.commit, status: test.status })) // Take all hashes and status' of tests in this group. })) .map(groupData => [ From b5151a6d89029ff5ea132d91b60411a62e8ef160 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 09:46:14 -0700 Subject: [PATCH 007/122] Add duration to data collection. --- hack/test-flake-chart/collect_data.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hack/test-flake-chart/collect_data.sh b/hack/test-flake-chart/collect_data.sh index 1707ab3028..392aeb7c9d 100755 --- a/hack/test-flake-chart/collect_data.sh +++ b/hack/test-flake-chart/collect_data.sh @@ -6,7 +6,7 @@ PARTIAL_DATA_PATH=$(mktemp) echo "Partial path: $PARTIAL_DATA_PATH" 1>&2 # Print header. -printf "Commit Hash,Commit Date,Environment,Test,Status\n" +printf "Commit Hash,Commit Date,Environment,Test,Status,Duration\n" # 1) "cat" together all summary files. # 2) Turn each test in each summary file to a CSV line containing its commit hash, environment, test, and status. @@ -17,7 +17,10 @@ printf "Commit Hash,Commit Date,Environment,Test,Status\n" # 6) Execute git log for each commit to get the date of each. # 7) Join dates with test data. gsutil cat gs://minikube-builds/logs/master/*/*_summary.json \ -| jq -r '({commit: .Detail.Details, environment: .Detail.Name, test: .PassedTests[]?, status: "Passed"},{commit: .Detail.Details, environment: .Detail.Name, test: .FailedTests[]?, status: "Failed"},{commit: .Detail.Details, environment: .Detail.Name, test: .SkippedTests[]?, status: "Skipped"}) | .commit + "," + .environment + "," + .test + "," + .status' \ +| jq -r '((.PassedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Passed"}), + (.FailedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Failed"}), + (.SkippedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: 0, status: "Skipped"})) + | .commit + "," + .environment + "," + .test + "," + .status + "," + (.duration | tostring)' \ | tee $PARTIAL_DATA_PATH \ | sed -r -n 's/^([^,]+),.*/\1/p' \ | stdbuf -oL -eL uniq \ From ae62edbd181694d4b052fb7e93142c141f84a2a7 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 10:17:29 -0700 Subject: [PATCH 008/122] Update JS to accept duration data. --- hack/test-flake-chart/flake_chart.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index 58b119ea22..462b8d8130 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -44,15 +44,15 @@ async function loadTestData() { const lines = bodyByLinesIterator(response); // Consume the header to ensure the data has the right number of fields. const header = (await lines.next()).value; - if (header.split(",").length != 5) { - throw `Fetched CSV data contains wrong number of fields. Expected: 5. Actual Header: "${header}"`; + if (header.split(",").length != 6) { + throw `Fetched CSV data contains wrong number of fields. Expected: 6. Actual Header: "${header}"`; } const testData = []; for await (const line of lines) { const splitLine = line.split(","); - if (splitLine.length != 5) { - console.warn(`Found line with wrong number of fields. Actual: ${splitLine.length} Expected: 5. Line: "${line}"`); + if (splitLine.length != 6) { + console.warn(`Found line with wrong number of fields. Actual: ${splitLine.length} Expected: 6. Line: "${line}"`); continue; } if (!isValidEnumValue(testStatus, splitLine[4])) { @@ -64,7 +64,8 @@ async function loadTestData() { date: new Date(splitLine[1]), environment: splitLine[2], name: splitLine[3], - status: splitLine[4] + status: splitLine[4], + duration: Number(splitLine[5]), }); } if (testData.length == 0) { From b55c6726ef5450090c76737c63628cbe019f49a3 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 10:18:26 -0700 Subject: [PATCH 009/122] Use URL search query to select test and environment. --- hack/test-flake-chart/flake_chart.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index 462b8d8130..43f6865669 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -92,6 +92,17 @@ Array.prototype.groupBy = function (keyGetter) { }, new Map()).values()); }; +// Parse URL search `query` into [{key, value}]. +function parseUrlQuery(query) { + if (query[0] === '?') { + query = query.substring(1); + } + return Object.fromEntries((query === "" ? [] : query.split("&")).map(element => { + const keyValue = element.split("="); + return [unescape(keyValue[0]), unescape(keyValue[1])]; + })); +} + async function init() { google.charts.load('current', { 'packages': ['corechart'] }); let testData; @@ -112,7 +123,8 @@ async function init() { data.addColumn('number', 'Flake Percentage'); data.addColumn({ type: 'string', label: 'Commit Hash', role: 'tooltip', 'p': { 'html': true } }); - const desiredTest = "TestFunctional/parallel/LogsCmd", desiredEnvironment = "Docker_Linux_containerd"; + const query = parseUrlQuery(window.location.search); + const desiredTest = query.test || "", desiredEnvironment = query.env || ""; const groups = testData // Filter to only contain unskipped runs of the requested test and requested environment. From 424c954770215e82cd42040251b4ac103d162bb4 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 11:33:22 -0700 Subject: [PATCH 010/122] Add duration to existing graph with appropriate labels. --- hack/test-flake-chart/flake_chart.js | 35 ++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index 43f6865669..8d8f0cb524 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -121,7 +121,9 @@ async function init() { const data = new google.visualization.DataTable(); data.addColumn('date', 'Date'); data.addColumn('number', 'Flake Percentage'); - data.addColumn({ type: 'string', label: 'Commit Hash', role: 'tooltip', 'p': { 'html': true } }); + data.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } }); + data.addColumn('number', 'Duration'); + data.addColumn({ type: 'string', role: 'tooltip', 'p': { 'html': true } }); const query = parseUrlQuery(window.location.search); const desiredTest = query.test || "", desiredEnvironment = query.env || ""; @@ -139,7 +141,12 @@ async function init() { .map(tests => ({ date: tests[0].date, // Get one of the dates from the tests (which will all be the same). flakeRate: tests.map(test => test.status === testStatus.FAILED ? 100 : 0).average(), // Compute average of runs where FAILED counts as 100%. - commitHashes: tests.map(test => ({ hash: test.commit, status: test.status })) // Take all hashes and status' of tests in this group. + duration: tests.map(test => test.duration).average(), // Compute average duration of runs. + commitHashes: tests.map(test => ({ // Take all hashes, statuses, and durations of tests in this group. + hash: test.commit, + status: test.status, + duration: test.duration + })) })) .map(groupData => [ groupData.date, @@ -149,17 +156,31 @@ async function init() { Flake Percentage: ${groupData.flakeRate.toFixed(2)}%
Hashes:
${groupData.commitHashes.map(({ hash, status }) => ` - ${hash} (${status})`).join("
")} - ` + `, + groupData.duration, + `
+ ${groupData.date.toString()}
+ Average Duration: ${groupData.duration.toFixed(2)}s
+ Hashes:
+ ${groupData.commitHashes.map(({ hash, duration }) => ` - ${hash} (${duration}s)`).join("
")} +
`, ]) ); const options = { - title: `Flake Rate by day of ${desiredTest} on ${desiredEnvironment}`, - width: 900, - height: 500, + title: `Flake rate and duration by day of ${desiredTest} on ${desiredEnvironment}`, + width: window.innerWidth, + height: window.innerHeight, pointSize: 10, pointShape: "circle", - vAxis: { minValue: 0, maxValue: 1 }, + series: { + 0: { targetAxisIndex: 0 }, + 1: { targetAxisIndex: 1 }, + }, + vAxes: { + 0: { title: "Flake rate", minValue: 0, maxValue: 100 }, + 1: { title: "Duration (seconds)" }, + }, tooltip: { trigger: "selection", isHtml: true } }; const chart = new google.visualization.LineChart(document.getElementById('chart_div')); From 419f2506e697d65bbf493a6c92ba390ed248ebc8 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 12:15:16 -0700 Subject: [PATCH 011/122] Add "data optimization" which treats empty fields in data.csv as equivalent to the previous entry. This optimization takes data size down from 41 MB to 16MB which is ~40% which is huge! --- hack/test-flake-chart/flake_chart.js | 5 ++++- hack/test-flake-chart/optimize_data.sh | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100755 hack/test-flake-chart/optimize_data.sh diff --git a/hack/test-flake-chart/flake_chart.js b/hack/test-flake-chart/flake_chart.js index 8d8f0cb524..e18d5389a5 100644 --- a/hack/test-flake-chart/flake_chart.js +++ b/hack/test-flake-chart/flake_chart.js @@ -49,12 +49,15 @@ async function loadTestData() { } const testData = []; + let lineData = ["", "", "", "", "", ""]; for await (const line of lines) { - const splitLine = line.split(","); + let splitLine = line.split(","); if (splitLine.length != 6) { console.warn(`Found line with wrong number of fields. Actual: ${splitLine.length} Expected: 6. Line: "${line}"`); continue; } + splitLine = splitLine.map((value, index) => value === "" ? lineData[index] : value); + lineData = splitLine; if (!isValidEnumValue(testStatus, splitLine[4])) { console.warn(`Invalid test status provided. Actual: ${splitLine[4]} Expected: One of ${Object.values(testStatus).join(", ")}`); continue; diff --git a/hack/test-flake-chart/optimize_data.sh b/hack/test-flake-chart/optimize_data.sh new file mode 100755 index 0000000000..f62cb63f3e --- /dev/null +++ b/hack/test-flake-chart/optimize_data.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +awk -F, 'BEGIN {OFS = FS} { for(i=1; i<=NF; i++) { if($i == j[i]) { $i = ""; } else { j[i] = $i; } } printf "%s\n",$0 }' From 78e98382836c8552f178f72deb0ac26d7e793f55 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 14:01:41 -0700 Subject: [PATCH 012/122] Refactor collect_data into collect_data + process_data. This allows processing data coming from other sources. --- hack/test-flake-chart/collect_data.sh | 26 +++----------------------- hack/test-flake-chart/process_data.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 23 deletions(-) create mode 100755 hack/test-flake-chart/process_data.sh diff --git a/hack/test-flake-chart/collect_data.sh b/hack/test-flake-chart/collect_data.sh index 392aeb7c9d..644c7842de 100755 --- a/hack/test-flake-chart/collect_data.sh +++ b/hack/test-flake-chart/collect_data.sh @@ -1,28 +1,8 @@ #!/bin/bash -# Create temp path for partial data (storing everything but the commit date.) -PARTIAL_DATA_PATH=$(mktemp) -# Write -echo "Partial path: $PARTIAL_DATA_PATH" 1>&2 - -# Print header. -printf "Commit Hash,Commit Date,Environment,Test,Status,Duration\n" +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) # 1) "cat" together all summary files. -# 2) Turn each test in each summary file to a CSV line containing its commit hash, environment, test, and status. -# 3) Copy partial data to $PARTIAL_DATA_PATH to join with date later. -# 4) Extract only commit hash for each row -# 5) Make the commit hashes unique (we assume that gsutil cats files from the same hash next to each other). -# Also force buffering to occur per line so remainder of pipe can continue to process. -# 6) Execute git log for each commit to get the date of each. -# 7) Join dates with test data. +# 2) Process all summary files. gsutil cat gs://minikube-builds/logs/master/*/*_summary.json \ -| jq -r '((.PassedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Passed"}), - (.FailedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Failed"}), - (.SkippedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: 0, status: "Skipped"})) - | .commit + "," + .environment + "," + .test + "," + .status + "," + (.duration | tostring)' \ -| tee $PARTIAL_DATA_PATH \ -| sed -r -n 's/^([^,]+),.*/\1/p' \ -| stdbuf -oL -eL uniq \ -| xargs -I {} git log -1 --pretty=format:"{},%as%n" {} \ -| join -t "," - $PARTIAL_DATA_PATH +| $DIR/process_data.sh diff --git a/hack/test-flake-chart/process_data.sh b/hack/test-flake-chart/process_data.sh new file mode 100755 index 0000000000..7348c1b178 --- /dev/null +++ b/hack/test-flake-chart/process_data.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Create temp path for partial data (storing everything but the commit date.) +PARTIAL_DATA_PATH=$(mktemp) +# Print the partial path for debugging/convenience. +echo "Partial path: $PARTIAL_DATA_PATH" 1>&2 + +# Print header. +printf "Commit Hash,Commit Date,Environment,Test,Status,Duration\n" + +# 1) Turn each test in each summary file to a CSV line containing its commit hash, environment, test, and status. +# 2) Copy partial data to $PARTIAL_DATA_PATH to join with date later. +# 3) Extract only commit hash for each row +# 4) Make the commit hashes unique (we assume that gsutil cats files from the same hash next to each other). +# Also force buffering to occur per line so remainder of pipe can continue to process. +# 5) Execute git log for each commit to get the date of each. +# 6) Join dates with test data. +jq -r '((.PassedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Passed"}), + (.FailedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Failed"}), + (.SkippedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: 0, status: "Skipped"})) + | .commit + "," + .environment + "," + .test + "," + .status + "," + (.duration | tostring)' \ +| tee $PARTIAL_DATA_PATH \ +| sed -r -n 's/^([^,]+),.*/\1/p' \ +| stdbuf -oL -eL uniq \ +| xargs -I {} git log -1 --pretty=format:"{},%as%n" {} \ +| join -t "," - $PARTIAL_DATA_PATH From fbf4e03eb98790d3d7dfe33610599f97a844c036 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 14:06:54 -0700 Subject: [PATCH 013/122] Add license to sh scripts. --- hack/test-flake-chart/collect_data.sh | 14 ++++++++++++++ hack/test-flake-chart/optimize_data.sh | 15 +++++++++++++++ hack/test-flake-chart/process_data.sh | 14 ++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/hack/test-flake-chart/collect_data.sh b/hack/test-flake-chart/collect_data.sh index 644c7842de..44273f6d80 100755 --- a/hack/test-flake-chart/collect_data.sh +++ b/hack/test-flake-chart/collect_data.sh @@ -1,5 +1,19 @@ #!/bin/bash +# Copyright 2018 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) # 1) "cat" together all summary files. diff --git a/hack/test-flake-chart/optimize_data.sh b/hack/test-flake-chart/optimize_data.sh index f62cb63f3e..1fd93f1901 100755 --- a/hack/test-flake-chart/optimize_data.sh +++ b/hack/test-flake-chart/optimize_data.sh @@ -1,3 +1,18 @@ #!/bin/bash +# Copyright 2018 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Take input CSV. For each field, if it is the same as the previous row, replace it with an empty string. awk -F, 'BEGIN {OFS = FS} { for(i=1; i<=NF; i++) { if($i == j[i]) { $i = ""; } else { j[i] = $i; } } printf "%s\n",$0 }' diff --git a/hack/test-flake-chart/process_data.sh b/hack/test-flake-chart/process_data.sh index 7348c1b178..f1ed764e87 100755 --- a/hack/test-flake-chart/process_data.sh +++ b/hack/test-flake-chart/process_data.sh @@ -1,5 +1,19 @@ #!/bin/bash +# Copyright 2018 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + # Create temp path for partial data (storing everything but the commit date.) PARTIAL_DATA_PATH=$(mktemp) # Print the partial path for debugging/convenience. From ef33b8661cdae8973558f2bd0d1c22e8fd45383a Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 16:12:27 -0700 Subject: [PATCH 014/122] Create new compute_flake_rate.go with basic CSV parsing. --- hack/test-flake-chart/compute_flake_rate.go | 109 ++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 hack/test-flake-chart/compute_flake_rate.go diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/test-flake-chart/compute_flake_rate.go new file mode 100644 index 0000000000..ca62639e7b --- /dev/null +++ b/hack/test-flake-chart/compute_flake_rate.go @@ -0,0 +1,109 @@ +/* +Copyright 2020 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "os" + "runtime/debug" + "strings" + "time" +) + +var ( + dataCsv = flag.String("data-csv", "", "Source data to compute flake rates on") + dateRange = flag.Uint("date-range", 5, "Number of test dates to consider when computing flake rate") +) + +func main() { + flag.Parse() + + file, err := os.Open(*dataCsv) + if err != nil { + exit("Unable to read data CSV", err) + } + + testEntries := ReadData(file) + for _, entry := range testEntries { + fmt.Printf("Name: \"%s\", Environment: \"%s\", Date: \"%v\", Status: \"%s\"\n", entry.name, entry.environment, entry.date, entry.status) + } +} + +type TestEntry struct { + name string + environment string + date time.Time + status string +} + +// Reads CSV `file` and consumes each line to be a single TestEntry. +func ReadData(file *os.File) []TestEntry { + testEntries := []TestEntry{} + + fileReader := bufio.NewReaderSize(file, 256) + previousLine := []string{"", "", "", "", "", ""} + firstLine := true + for { + lineBytes, _, err := fileReader.ReadLine() + if err != nil { + if err == io.EOF { + break + } + exit("Error reading data CSV", err) + } + line := string(lineBytes) + fields := strings.Split(line, ",") + if firstLine { + if len(fields) != 6 { + exit(fmt.Sprintf("Data CSV in incorrect format. Expected 6 columns, but got %d", len(fields)), fmt.Errorf("Bad CSV format")) + } + firstLine = false + } + for i, field := range fields { + if field == "" { + fields[i] = previousLine[i] + } + } + if len(fields) != 6 { + fmt.Printf("Found line with wrong number of columns. Expectd 6, but got %d - skipping\n", len(fields)) + continue + } + previousLine = fields + if fields[4] == "Passed" || fields[4] == "Failed" { + date, err := time.Parse("2006-01-02", fields[1]) + if err != nil { + fmt.Printf("Failed to parse date: %v\n", err) + } + testEntries = append(testEntries, TestEntry{ + name: fields[3], + environment: fields[2], + date: date, + status: fields[4], + }) + } + } + return testEntries +} + +// exit will exit and clean up minikube +func exit(msg string, err error) { + fmt.Printf("WithError(%s)=%v called from:\n%s", msg, err, debug.Stack()) + os.Exit(60) +} From de6cff23db3f753000941a7da2357557327c2e91 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 16:20:47 -0700 Subject: [PATCH 015/122] Split entries based on environment and test name. --- hack/test-flake-chart/compute_flake_rate.go | 44 ++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/test-flake-chart/compute_flake_rate.go index ca62639e7b..f62fef637d 100644 --- a/hack/test-flake-chart/compute_flake_rate.go +++ b/hack/test-flake-chart/compute_flake_rate.go @@ -41,8 +41,17 @@ func main() { } testEntries := ReadData(file) - for _, entry := range testEntries { - fmt.Printf("Name: \"%s\", Environment: \"%s\", Date: \"%v\", Status: \"%s\"\n", entry.name, entry.environment, entry.date, entry.status) + splitEntries := SplitData(testEntries) + for environment, environmentSplit := range splitEntries { + fmt.Printf("%s {\n", environment) + for test, testSplit := range environmentSplit { + fmt.Printf(" %s {\n", test) + for _, entry := range testSplit { + fmt.Printf(" Date: %v, Status: %s\n", entry.date, entry.status) + } + fmt.Printf(" }\n") + } + fmt.Printf("}\n") } } @@ -102,6 +111,37 @@ func ReadData(file *os.File) []TestEntry { return testEntries } +// Splits `testEntries` up into maps indexed first by environment and then by test. +func SplitData(testEntries []TestEntry) map[string]map[string][]TestEntry { + splitEntries := make(map[string]map[string][]TestEntry) + + for _, entry := range testEntries { + AppendEntry(splitEntries, entry.environment, entry.name, entry) + } + + return splitEntries +} + +// Appends `entry` to `splitEntries` at the `environment` and `test`. +func AppendEntry(splitEntries map[string]map[string][]TestEntry, environment, test string, entry TestEntry) { + // Lookup the environment. + environmentSplit, ok := splitEntries[environment] + if !ok { + // If the environment map is missing, make a map for this environment and store it. + environmentSplit = make(map[string][]TestEntry) + splitEntries[environment] = environmentSplit + } + + // Lookup the test. + testSplit, ok := environmentSplit[test] + if !ok { + // If the test is missing, make a slice for this test. + testSplit = make([]TestEntry, 0) + // The slice is not inserted, since it will be replaced anyway. + } + environmentSplit[test] = append(testSplit, entry) +} + // exit will exit and clean up minikube func exit(msg string, err error) { fmt.Printf("WithError(%s)=%v called from:\n%s", msg, err, debug.Stack()) From e6a553f67977856eac4ef8ae68184a55b7029131 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 1 Jun 2021 16:27:03 -0700 Subject: [PATCH 016/122] Compute flake rate of all entries split by environment and test. --- hack/test-flake-chart/compute_flake_rate.go | 40 +++++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/test-flake-chart/compute_flake_rate.go index f62fef637d..628a6efe0b 100644 --- a/hack/test-flake-chart/compute_flake_rate.go +++ b/hack/test-flake-chart/compute_flake_rate.go @@ -42,14 +42,11 @@ func main() { testEntries := ReadData(file) splitEntries := SplitData(testEntries) - for environment, environmentSplit := range splitEntries { + flakeRates := ComputeFlakeRates(splitEntries) + for environment, environmentSplit := range flakeRates { fmt.Printf("%s {\n", environment) - for test, testSplit := range environmentSplit { - fmt.Printf(" %s {\n", test) - for _, entry := range testSplit { - fmt.Printf(" Date: %v, Status: %s\n", entry.date, entry.status) - } - fmt.Printf(" }\n") + for test, flakeRate := range environmentSplit { + fmt.Printf(" %s: %f\n", test, flakeRate) } fmt.Printf("}\n") } @@ -142,6 +139,35 @@ func AppendEntry(splitEntries map[string]map[string][]TestEntry, environment, te environmentSplit[test] = append(testSplit, entry) } +// Computes the flake rates over each entry in `splitEntries`. +func ComputeFlakeRates(splitEntries map[string]map[string][]TestEntry) map[string]map[string]float32 { + flakeRates := make(map[string]map[string]float32) + for environment, environmentSplit := range splitEntries { + for test, testSplit := range environmentSplit { + failures := 0 + for _, entry := range testSplit { + if entry.status == "Failed" { + failures++ + } + } + SetValue(flakeRates, environment, test, float32(failures)/float32(len(testSplit))) + } + } + return flakeRates +} + +// Sets the `value` of keys `environment` and `test` in `flakeRates`. +func SetValue(flakeRates map[string]map[string]float32, environment, test string, value float32) { + // Lookup the environment. + environmentRates, ok := flakeRates[environment] + if !ok { + // If the environment map is missing, make a map for this environment and store it. + environmentRates = make(map[string]float32) + flakeRates[environment] = environmentRates + } + environmentRates[test] = value +} + // exit will exit and clean up minikube func exit(msg string, err error) { fmt.Printf("WithError(%s)=%v called from:\n%s", msg, err, debug.Stack()) From 60929009d6daae66405b8f5c5f2570d5b99121d6 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 2 Jun 2021 10:56:02 -0700 Subject: [PATCH 017/122] Create FilterRecentEntries to only include the last N run dates. --- hack/test-flake-chart/compute_flake_rate.go | 52 ++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/test-flake-chart/compute_flake_rate.go index 628a6efe0b..94eece1725 100644 --- a/hack/test-flake-chart/compute_flake_rate.go +++ b/hack/test-flake-chart/compute_flake_rate.go @@ -23,6 +23,7 @@ import ( "io" "os" "runtime/debug" + "sort" "strings" "time" ) @@ -42,7 +43,8 @@ func main() { testEntries := ReadData(file) splitEntries := SplitData(testEntries) - flakeRates := ComputeFlakeRates(splitEntries) + filteredEntries := FilterRecentEntries(splitEntries, *dateRange) + flakeRates := ComputeFlakeRates(filteredEntries) for environment, environmentSplit := range flakeRates { fmt.Printf("%s {\n", environment) for test, flakeRate := range environmentSplit { @@ -139,6 +141,54 @@ func AppendEntry(splitEntries map[string]map[string][]TestEntry, environment, te environmentSplit[test] = append(testSplit, entry) } +// Filters `splitEntries` to include only the most recent `date_range` dates. +func FilterRecentEntries(splitEntries map[string]map[string][]TestEntry, dateRange uint) map[string]map[string][]TestEntry { + filteredEntries := make(map[string]map[string][]TestEntry) + + for environment, environmentSplit := range splitEntries { + for test, testSplit := range environmentSplit { + dates := make([]time.Time, len(testSplit)) + for _, entry := range testSplit { + dates = append(dates, entry.date) + } + // Sort dates from future to past. + sort.Slice(dates, func(i, j int) bool { + return dates[j].Before(dates[i]) + }) + datesInRange := make([]time.Time, 0, dateRange) + var lastDate time.Time = time.Date(0, 0, 0, 0, 0, 0, 0, time.Local) + // Go through each date. + for _, date := range dates { + // If date is the same as last date, ignore it. + if date.Equal(lastDate) { + continue + } + + // Add the date. + datesInRange = append(datesInRange, date) + lastDate = date + // If the date_range has been hit, break out. + if uint(len(datesInRange)) == dateRange { + break + } + } + + for _, entry := range testSplit { + // Look for the first element <= entry.date + index := sort.Search(len(datesInRange), func(i int) bool { + return datesInRange[i].Before(entry.date) || datesInRange[i].Equal(entry.date) + }) + // If no date is <= entry.date, or the found date does not equal entry.date. + if index == len(datesInRange) || !datesInRange[index].Equal(entry.date) { + continue + } + AppendEntry(filteredEntries, environment, test, entry) + } + } + } + return filteredEntries +} + // Computes the flake rates over each entry in `splitEntries`. func ComputeFlakeRates(splitEntries map[string]map[string][]TestEntry) map[string]map[string]float32 { flakeRates := make(map[string]map[string]float32) From 9d4153f0abfc1bebecb53991e11d1dbcaa33c6e1 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 2 Jun 2021 13:40:27 -0700 Subject: [PATCH 018/122] Create test for ReadData. --- hack/test-flake-chart/compute_flake_rate.go | 2 +- .../compute_flake_rate_test.go | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 hack/test-flake-chart/compute_flake_rate_test.go diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/test-flake-chart/compute_flake_rate.go index 94eece1725..02151c6dec 100644 --- a/hack/test-flake-chart/compute_flake_rate.go +++ b/hack/test-flake-chart/compute_flake_rate.go @@ -62,7 +62,7 @@ type TestEntry struct { } // Reads CSV `file` and consumes each line to be a single TestEntry. -func ReadData(file *os.File) []TestEntry { +func ReadData(file io.Reader) []TestEntry { testEntries := []TestEntry{} fileReader := bufio.NewReaderSize(file, 256) diff --git a/hack/test-flake-chart/compute_flake_rate_test.go b/hack/test-flake-chart/compute_flake_rate_test.go new file mode 100644 index 0000000000..30210c9b88 --- /dev/null +++ b/hack/test-flake-chart/compute_flake_rate_test.go @@ -0,0 +1,87 @@ +/* +Copyright 2020 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "strings" + "testing" + "time" +) + +func simpleDate(year int, month time.Month, day int) time.Time { + return time.Date(year, month, day, 0, 0, 0, 0, time.UTC) +} + +func TestReadData(t *testing.T) { + actualData := ReadData(strings.NewReader( + `A,B,C,D,E,F + hash,2000-01-01,env1,test1,Passed,1 + hash,2001-01-01,env2,test2,Failed,1 + hash,,,test1,,1 + hash,2002-01-01,,,Passed,1 + hash,2003-01-01,env3,test3,Passed,1`, + )) + expectedData := []TestEntry{ + { + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 1), + status: "Passed", + }, + { + name: "test2", + environment: "env2", + date: simpleDate(2001, time.January, 1), + status: "Failed", + }, + { + name: "test1", + environment: "env2", + date: simpleDate(2001, time.January, 1), + status: "Failed", + }, + { + name: "test1", + environment: "env2", + date: simpleDate(2002, time.January, 1), + status: "Passed", + }, + { + name: "test3", + environment: "env3", + date: simpleDate(2003, time.January, 1), + status: "Passed", + }, + } + + for i, actual := range actualData { + if len(expectedData) <= i { + t.Errorf("Received unmatched actual element at index %d. Actual: %v", i, actual) + continue + } + expected := expectedData[i] + if actual != expected { + t.Errorf("Elements differ at index %d. Expected: %v, Actual: %v", i, expected, actual) + } + } + + if len(actualData) < len(expectedData) { + for i := len(actualData); i < len(expectedData); i++ { + t.Errorf("Missing unmatched expected element at index %d. Expected: %v", i, expectedData[i]) + } + } +} From 401bcbfe0a9dda2f1dbb0feb0a723cdbfba93426 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 2 Jun 2021 14:12:43 -0700 Subject: [PATCH 019/122] Move comparison code to its own function. --- .../compute_flake_rate_test.go | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/hack/test-flake-chart/compute_flake_rate_test.go b/hack/test-flake-chart/compute_flake_rate_test.go index 30210c9b88..8e175bfb0d 100644 --- a/hack/test-flake-chart/compute_flake_rate_test.go +++ b/hack/test-flake-chart/compute_flake_rate_test.go @@ -17,6 +17,7 @@ limitations under the License. package main import ( + "fmt" "strings" "testing" "time" @@ -26,6 +27,28 @@ func simpleDate(year int, month time.Month, day int) time.Time { return time.Date(year, month, day, 0, 0, 0, 0, time.UTC) } +func compareEntrySlices(t *testing.T, actualData, expectedData []TestEntry, extra string) { + if extra != "" { + extra = fmt.Sprintf(" (%s)", extra) + } + for i, actual := range actualData { + if len(expectedData) <= i { + t.Errorf("Received unmatched actual element at index %d%s. Actual: %v", i, extra, actual) + continue + } + expected := expectedData[i] + if actual != expected { + t.Errorf("Elements differ at index %d%s. Expected: %v, Actual: %v", i, extra, expected, actual) + } + } + + if len(actualData) < len(expectedData) { + for i := len(actualData); i < len(expectedData); i++ { + t.Errorf("Missing unmatched expected element at index %d%s. Expected: %v", i, extra, expectedData[i]) + } + } +} + func TestReadData(t *testing.T) { actualData := ReadData(strings.NewReader( `A,B,C,D,E,F @@ -68,16 +91,8 @@ func TestReadData(t *testing.T) { }, } - for i, actual := range actualData { - if len(expectedData) <= i { - t.Errorf("Received unmatched actual element at index %d. Actual: %v", i, actual) - continue - } - expected := expectedData[i] - if actual != expected { - t.Errorf("Elements differ at index %d. Expected: %v, Actual: %v", i, expected, actual) - } - } + compareEntrySlices(t, actualData, expectedData, "") +} if len(actualData) < len(expectedData) { for i := len(actualData); i < len(expectedData); i++ { From 4e9718a28b6cf68be53eaf33a9ab77cbf39c3e93 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 2 Jun 2021 14:15:25 -0700 Subject: [PATCH 020/122] Add test for SplitData. --- .../compute_flake_rate_test.go | 78 ++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/hack/test-flake-chart/compute_flake_rate_test.go b/hack/test-flake-chart/compute_flake_rate_test.go index 8e175bfb0d..13343a2995 100644 --- a/hack/test-flake-chart/compute_flake_rate_test.go +++ b/hack/test-flake-chart/compute_flake_rate_test.go @@ -94,9 +94,81 @@ func TestReadData(t *testing.T) { compareEntrySlices(t, actualData, expectedData, "") } - if len(actualData) < len(expectedData) { - for i := len(actualData); i < len(expectedData); i++ { - t.Errorf("Missing unmatched expected element at index %d. Expected: %v", i, expectedData[i]) +func compareSplitData(t *testing.T, actual, expected map[string]map[string][]TestEntry) { + for environment, actualTests := range actual { + expectedTests, environmentOk := expected[environment] + if !environmentOk { + t.Errorf("Unexpected environment %s in actual", environment) + continue + } + + for test, actualEntries := range actualTests { + expectedEntries, testOk := expectedTests[test] + if !testOk { + t.Errorf("Unexpected test %s (in environment %s) in actual", test, environment) + continue + } + + compareEntrySlices(t, actualEntries, expectedEntries, fmt.Sprintf("environment %s, test %s", environment, test)) + } + + for test := range expectedTests { + _, testOk := actualTests[test] + if !testOk { + t.Errorf("Missing expected test %s (in environment %s) in actual", test, environment) + } + } + } + + for environment := range expected { + _, environmentOk := actual[environment] + if !environmentOk { + t.Errorf("Missing expected environment %s in actual", environment) } } } + +func TestSplitData(t *testing.T) { + entry_e1_t1_1, entry_e1_t1_2 := TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 1), + status: "Passed", + }, TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 2), + status: "Passed", + } + entry_e1_t2 := TestEntry{ + name: "test2", + environment: "env1", + date: simpleDate(2000, time.January, 1), + status: "Passed", + } + entry_e2_t1 := TestEntry{ + name: "test1", + environment: "env2", + date: simpleDate(2000, time.January, 1), + status: "Passed", + } + entry_e2_t2 := TestEntry{ + name: "test2", + environment: "env2", + date: simpleDate(2000, time.January, 1), + status: "Passed", + } + actual := SplitData([]TestEntry{entry_e1_t1_1, entry_e1_t1_2, entry_e1_t2, entry_e2_t1, entry_e2_t2}) + expected := map[string]map[string][]TestEntry{ + "env1": { + "test1": {entry_e1_t1_1, entry_e1_t1_2}, + "test2": {entry_e1_t2}, + }, + "env2": { + "test1": {entry_e2_t1}, + "test2": {entry_e2_t2}, + }, + } + + compareSplitData(t, actual, expected) +} From df6f7a8485ce00305fa8cc21ea4ff395b30b433a Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 2 Jun 2021 15:48:12 -0700 Subject: [PATCH 021/122] Add test for FilterRecentEntries. --- hack/test-flake-chart/compute_flake_rate.go | 10 +- .../compute_flake_rate_test.go | 107 ++++++++++++++++++ 2 files changed, 112 insertions(+), 5 deletions(-) diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/test-flake-chart/compute_flake_rate.go index 02151c6dec..ea622a4a80 100644 --- a/hack/test-flake-chart/compute_flake_rate.go +++ b/hack/test-flake-chart/compute_flake_rate.go @@ -115,14 +115,14 @@ func SplitData(testEntries []TestEntry) map[string]map[string][]TestEntry { splitEntries := make(map[string]map[string][]TestEntry) for _, entry := range testEntries { - AppendEntry(splitEntries, entry.environment, entry.name, entry) + appendEntry(splitEntries, entry.environment, entry.name, entry) } return splitEntries } // Appends `entry` to `splitEntries` at the `environment` and `test`. -func AppendEntry(splitEntries map[string]map[string][]TestEntry, environment, test string, entry TestEntry) { +func appendEntry(splitEntries map[string]map[string][]TestEntry, environment, test string, entry TestEntry) { // Lookup the environment. environmentSplit, ok := splitEntries[environment] if !ok { @@ -182,7 +182,7 @@ func FilterRecentEntries(splitEntries map[string]map[string][]TestEntry, dateRan if index == len(datesInRange) || !datesInRange[index].Equal(entry.date) { continue } - AppendEntry(filteredEntries, environment, test, entry) + appendEntry(filteredEntries, environment, test, entry) } } } @@ -200,14 +200,14 @@ func ComputeFlakeRates(splitEntries map[string]map[string][]TestEntry) map[strin failures++ } } - SetValue(flakeRates, environment, test, float32(failures)/float32(len(testSplit))) + setValue(flakeRates, environment, test, float32(failures)/float32(len(testSplit))) } } return flakeRates } // Sets the `value` of keys `environment` and `test` in `flakeRates`. -func SetValue(flakeRates map[string]map[string]float32, environment, test string, value float32) { +func setValue(flakeRates map[string]map[string]float32, environment, test string, value float32) { // Lookup the environment. environmentRates, ok := flakeRates[environment] if !ok { diff --git a/hack/test-flake-chart/compute_flake_rate_test.go b/hack/test-flake-chart/compute_flake_rate_test.go index 13343a2995..d27fd176e9 100644 --- a/hack/test-flake-chart/compute_flake_rate_test.go +++ b/hack/test-flake-chart/compute_flake_rate_test.go @@ -172,3 +172,110 @@ func TestSplitData(t *testing.T) { compareSplitData(t, actual, expected) } + +func TestFilterRecentEntries(t *testing.T) { + entry_e1_t1_r1, entry_e1_t1_r2, entry_e1_t1_r3, entry_e1_t1_o1, entry_e1_t1_o2 := TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 4), + status: "Passed", + }, TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 3), + status: "Passed", + }, TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 3), + status: "Passed", + }, TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 2), + status: "Passed", + }, TestEntry{ + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 1), + status: "Passed", + } + entry_e1_t2_r1, entry_e1_t2_r2, entry_e1_t2_o1 := TestEntry{ + name: "test2", + environment: "env1", + date: simpleDate(2001, time.January, 3), + status: "Passed", + }, TestEntry{ + name: "test2", + environment: "env1", + date: simpleDate(2001, time.January, 2), + status: "Passed", + }, TestEntry{ + name: "test2", + environment: "env1", + date: simpleDate(2001, time.January, 1), + status: "Passed", + } + entry_e2_t2_r1, entry_e2_t2_r2, entry_e2_t2_o1 := TestEntry{ + name: "test2", + environment: "env2", + date: simpleDate(2003, time.January, 3), + status: "Passed", + }, TestEntry{ + name: "test2", + environment: "env2", + date: simpleDate(2003, time.January, 2), + status: "Passed", + }, TestEntry{ + name: "test2", + environment: "env2", + date: simpleDate(2003, time.January, 1), + status: "Passed", + } + + actualData := FilterRecentEntries(map[string]map[string][]TestEntry{ + "env1": { + "test1": { + entry_e1_t1_r1, + entry_e1_t1_r2, + entry_e1_t1_r3, + entry_e1_t1_o1, + entry_e1_t1_o2, + }, + "test2": { + entry_e1_t2_r1, + entry_e1_t2_r2, + entry_e1_t2_o1, + }, + }, + "env2": { + "test2": { + entry_e2_t2_r1, + entry_e2_t2_r2, + entry_e2_t2_o1, + }, + }, + }, 2) + + expectedData := map[string]map[string][]TestEntry{ + "env1": { + "test1": { + entry_e1_t1_r1, + entry_e1_t1_r2, + entry_e1_t1_r3, + }, + "test2": { + entry_e1_t2_r1, + entry_e1_t2_r2, + }, + }, + "env2": { + "test2": { + entry_e2_t2_r1, + entry_e2_t2_r2, + }, + }, + } + + compareSplitData(t, actualData, expectedData) +} From 65be305aab6517c7c503f1627bbf94ddca7b7052 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 2 Jun 2021 16:17:39 -0700 Subject: [PATCH 022/122] Add test for ComputeFlakeRates. --- .../compute_flake_rate_test.go | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/hack/test-flake-chart/compute_flake_rate_test.go b/hack/test-flake-chart/compute_flake_rate_test.go index d27fd176e9..22c1f6b476 100644 --- a/hack/test-flake-chart/compute_flake_rate_test.go +++ b/hack/test-flake-chart/compute_flake_rate_test.go @@ -279,3 +279,115 @@ func TestFilterRecentEntries(t *testing.T) { compareSplitData(t, actualData, expectedData) } + +func TestComputeFlakeRates(t *testing.T) { + actualData := ComputeFlakeRates(map[string]map[string][]TestEntry{ + "env1": { + "test1": { + { + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 4), + status: "Passed", + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 3), + status: "Passed", + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 3), + status: "Passed", + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 2), + status: "Passed", + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, time.January, 1), + status: "Failed", + }, + }, + "test2": { + { + name: "test2", + environment: "env1", + date: simpleDate(2001, time.January, 3), + status: "Failed", + }, { + name: "test2", + environment: "env1", + date: simpleDate(2001, time.January, 2), + status: "Failed", + }, { + name: "test2", + environment: "env1", + date: simpleDate(2001, time.January, 1), + status: "Failed", + }, + }, + }, + "env2": { + "test2": { + { + name: "test2", + environment: "env2", + date: simpleDate(2003, time.January, 3), + status: "Passed", + }, TestEntry{ + name: "test2", + environment: "env2", + date: simpleDate(2003, time.January, 2), + status: "Failed", + }, + }, + }, + }) + + expectedData := map[string]map[string]float32{ + "env1": { + "test1": 0.2, + "test2": 1, + }, + "env2": { + "test2": 0.5, + }, + } + + for environment, actualTests := range actualData { + expectedTests, environmentOk := expectedData[environment] + if !environmentOk { + t.Errorf("Unexpected environment %s in actual", environment) + continue + } + + for test, actualFlakeRate := range actualTests { + expectedFlakeRate, testOk := expectedTests[test] + if !testOk { + t.Errorf("Unexpected test %s (in environment %s) in actual", test, environment) + continue + } + + if actualFlakeRate != expectedFlakeRate { + t.Errorf("Wrong flake rate. Expected: %v, Actual: %v", expectedFlakeRate, actualFlakeRate) + } + } + + for test := range expectedTests { + _, testOk := actualTests[test] + if !testOk { + t.Errorf("Missing expected test %s (in environment %s) in actual", test, environment) + } + } + } + + for environment := range expectedData { + _, environmentOk := actualData[environment] + if !environmentOk { + t.Errorf("Missing expected environment %s in actual", environment) + } + } +} From 36a6f876009a37269223046f976f9196233d45d8 Mon Sep 17 00:00:00 2001 From: Vishal Jain Date: Sun, 16 May 2021 11:59:29 -0700 Subject: [PATCH 023/122] Added Mock of Minikube Delete Profiles Test portion. --- cmd/minikube/cmd/delete.go | 33 +++++++++++++++++++-------------- cmd/minikube/cmd/delete_test.go | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index b7c86852d3..3104e57bfb 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -87,6 +87,24 @@ func (error DeletionError) Error() string { return error.Err.Error() } +var DeleteHostAndDirectoriesGetter = func(api libmachine.API, cc *config.ClusterConfig, profileName string) error { + if err := killMountProcess(); err != nil { + out.FailureT("Failed to kill mount process: {{.error}}", out.V{"error": err}) + } + + deleteHosts(api, cc) + + // In case DeleteHost didn't complete the job. + deleteProfileDirectory(profileName) + deleteMachineDirectories(cc) + + if err := deleteConfig(profileName); err != nil { + return err + } + + return deleteContext(profileName) +} + func init() { deleteCmd.Flags().BoolVar(&deleteAll, "all", false, "Set flag to delete all profiles") deleteCmd.Flags().BoolVar(&purge, "purge", false, "Set this flag to delete the '.minikube' folder from your user directory.") @@ -282,23 +300,10 @@ func deleteProfile(ctx context.Context, profile *config.Profile) error { } } - if err := killMountProcess(); err != nil { - out.FailureT("Failed to kill mount process: {{.error}}", out.V{"error": err}) - } - - deleteHosts(api, cc) - - // In case DeleteHost didn't complete the job. - deleteProfileDirectory(profile.Name) - deleteMachineDirectories(cc) - - if err := deleteConfig(profile.Name); err != nil { + if err := DeleteHostAndDirectoriesGetter(api, cc, profile.Name); err != nil { return err } - if err := deleteContext(profile.Name); err != nil { - return err - } out.Step(style.Deleted, `Removed all traces of the "{{.name}}" cluster.`, out.V{"name": profile.Name}) return nil } diff --git a/cmd/minikube/cmd/delete_test.go b/cmd/minikube/cmd/delete_test.go index 6c6a98939f..bff1652183 100644 --- a/cmd/minikube/cmd/delete_test.go +++ b/cmd/minikube/cmd/delete_test.go @@ -17,15 +17,18 @@ limitations under the License. package cmd import ( + "fmt" "io/ioutil" "os" "path/filepath" "testing" + "github.com/docker/machine/libmachine" "github.com/google/go-cmp/cmp" "github.com/otiai10/copy" "github.com/spf13/viper" + cmdcfg "k8s.io/minikube/cmd/minikube/cmd/config" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/localpath" ) @@ -154,6 +157,17 @@ func TestDeleteProfile(t *testing.T) { } } +var DeleteHostAndDirectoriesMock = func(api libmachine.API, cc *config.ClusterConfig, profileName string) error { + return deleteContextTest() +} + +func deleteContextTest() error { + if err := cmdcfg.Unset(config.ProfileName); err != nil { + return DeletionError{Err: fmt.Errorf("unset minikube profile: %v", err), Errtype: Fatal} + } + return nil +} + func TestDeleteAllProfiles(t *testing.T) { td, err := ioutil.TempDir("", "all") if err != nil { @@ -207,6 +221,7 @@ func TestDeleteAllProfiles(t *testing.T) { } profiles := append(validProfiles, inValidProfiles...) + DeleteHostAndDirectoriesGetter = DeleteHostAndDirectoriesMock errs := DeleteProfiles(profiles) if errs != nil { From ebe03d768760a0b1a3fde74de09a3d069ef8cd1b Mon Sep 17 00:00:00 2001 From: Vishal Jain Date: Sun, 30 May 2021 20:42:33 -0700 Subject: [PATCH 024/122] Added Mock to DeleteProfile Test. --- cmd/minikube/cmd/delete_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/minikube/cmd/delete_test.go b/cmd/minikube/cmd/delete_test.go index bff1652183..c878a1a2ca 100644 --- a/cmd/minikube/cmd/delete_test.go +++ b/cmd/minikube/cmd/delete_test.go @@ -117,6 +117,7 @@ func TestDeleteProfile(t *testing.T) { t.Logf("load failure: %v", err) } + DeleteHostAndDirectoriesGetter = DeleteHostAndDirectoriesMock errs := DeleteProfiles([]*config.Profile{profile}) if len(errs) > 0 { HandleDeletionErrors(errs) From d7d3593a897eb4544bdcb6005e0ad19d7a04b95c Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 3 Jun 2021 13:33:58 -0700 Subject: [PATCH 025/122] Rewrite process_data.sh to no longer depend on git log. This now means we depend on the date being contained within the details. --- hack/test-flake-chart/process_data.sh | 28 ++++++--------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/hack/test-flake-chart/process_data.sh b/hack/test-flake-chart/process_data.sh index f1ed764e87..b3a6e26a9e 100755 --- a/hack/test-flake-chart/process_data.sh +++ b/hack/test-flake-chart/process_data.sh @@ -14,27 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Create temp path for partial data (storing everything but the commit date.) -PARTIAL_DATA_PATH=$(mktemp) -# Print the partial path for debugging/convenience. -echo "Partial path: $PARTIAL_DATA_PATH" 1>&2 - # Print header. -printf "Commit Hash,Commit Date,Environment,Test,Status,Duration\n" +printf "Commit Hash,Test Date,Environment,Test,Status,Duration\n" -# 1) Turn each test in each summary file to a CSV line containing its commit hash, environment, test, and status. -# 2) Copy partial data to $PARTIAL_DATA_PATH to join with date later. -# 3) Extract only commit hash for each row -# 4) Make the commit hashes unique (we assume that gsutil cats files from the same hash next to each other). -# Also force buffering to occur per line so remainder of pipe can continue to process. -# 5) Execute git log for each commit to get the date of each. -# 6) Join dates with test data. -jq -r '((.PassedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Passed"}), - (.FailedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Failed"}), - (.SkippedTests[]? as $name | {commit: .Detail.Details, environment: .Detail.Name, test: $name, duration: 0, status: "Skipped"})) - | .commit + "," + .environment + "," + .test + "," + .status + "," + (.duration | tostring)' \ -| tee $PARTIAL_DATA_PATH \ -| sed -r -n 's/^([^,]+),.*/\1/p' \ -| stdbuf -oL -eL uniq \ -| xargs -I {} git log -1 --pretty=format:"{},%as%n" {} \ -| join -t "," - $PARTIAL_DATA_PATH +# Turn each test in each summary file to a CSV line containing its commit hash, date, environment, test, and status. +jq -r '((.PassedTests[]? as $name | {commit: (.Detail.Details | split(":") | .[0]), date: (.Detail.Details | split(":") | .[1]), environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Passed"}), + (.FailedTests[]? as $name | {commit: (.Detail.Details | split(":") | .[0]), date: (.Detail.Details | split(":") | .[1]), environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Failed"}), + (.SkippedTests[]? as $name | {commit: (.Detail.Details | split(":") | .[0]), date: (.Detail.Details | split(":") | .[1]), environment: .Detail.Name, test: $name, duration: 0, status: "Skipped"})) + | .commit + "," + .date + "," + .environment + "," + .test + "," + .status + "," + (.duration | tostring)' From 40fdbe61ae817b8ff618321461d74059ba9315a0 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 3 Jun 2021 14:01:06 -0700 Subject: [PATCH 026/122] Allow Jenkins to append to the flake rate data. --- hack/jenkins/common.sh | 5 +++- hack/jenkins/upload_integration_report.sh | 4 +++ hack/test-flake-chart/jenkins_upload_tests.sh | 25 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100755 hack/test-flake-chart/jenkins_upload_tests.sh diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index beb58f7d08..0832b6b3e2 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -419,7 +419,7 @@ fi touch "${HTML_OUT}" touch "${SUMMARY_OUT}" -gopogh_status=$(gopogh -in "${JSON_OUT}" -out_html "${HTML_OUT}" -out_summary "${SUMMARY_OUT}" -name "${JOB_NAME}" -pr "${MINIKUBE_LOCATION}" -repo github.com/kubernetes/minikube/ -details "${COMMIT}") || true +gopogh_status=$(gopogh -in "${JSON_OUT}" -out_html "${HTML_OUT}" -out_summary "${SUMMARY_OUT}" -name "${JOB_NAME}" -pr "${MINIKUBE_LOCATION}" -repo github.com/kubernetes/minikube/ -details "${COMMIT}:$(date +%Y-%m-%d)") || true fail_num=$(echo $gopogh_status | jq '.NumberOfFail') test_num=$(echo $gopogh_status | jq '.NumberOfTests') pessimistic_status="${fail_num} / ${test_num} failures" @@ -441,6 +441,9 @@ if [ -z "${EXTERNAL}" ]; then gsutil -qm cp "${HTML_OUT}" "gs://${JOB_GCS_BUCKET}.html" || true echo ">> uploading ${SUMMARY_OUT}" gsutil -qm cp "${SUMMARY_OUT}" "gs://${JOB_GCS_BUCKET}_summary.json" || true + if [[ "${MINIKUBE_LOCATION}" == "master" ]]; then + ./test-flake-chart/jenkins_upload_tests.sh "${SUMMARY_OUT}" + fi else # Otherwise, put the results in a predictable spot so the upload job can find them REPORTS_PATH=test_reports diff --git a/hack/jenkins/upload_integration_report.sh b/hack/jenkins/upload_integration_report.sh index 04e24df09e..ddf9a6cee6 100644 --- a/hack/jenkins/upload_integration_report.sh +++ b/hack/jenkins/upload_integration_report.sh @@ -47,3 +47,7 @@ gsutil -qm cp "${HTML_OUT}" "gs://${JOB_GCS_BUCKET}.html" || true SUMMARY_OUT="$ARTIFACTS/summary.txt" echo ">> uploading ${SUMMARY_OUT}" gsutil -qm cp "${SUMMARY_OUT}" "gs://${JOB_GCS_BUCKET}_summary.json" || true + +if [[ "${MINIKUBE_LOCATION}" == "master" ]]; then + ./test-flake-chart/jenkins_upload_tests.sh "${SUMMARY_OUT}" +fi diff --git a/hack/test-flake-chart/jenkins_upload_tests.sh b/hack/test-flake-chart/jenkins_upload_tests.sh new file mode 100755 index 0000000000..e609893b80 --- /dev/null +++ b/hack/test-flake-chart/jenkins_upload_tests.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -x -o pipefail + +if [ "$#" -ne 1 ]; then + echo "Wrong number of arguments. Usage: jenkins_upload_tests.sh " 1>&2 + exit 1 +fi + +TMP_DATA=$(mktemp) + +# Use the gopogh summary, process it, optimize the data, remove the header, and store. +<"$1" ./test-flake-chart/process_data.sh \ + | ./test-flake-chart/optimize_data.sh \ + | sed "1d" > $TMP_DATA + +GCS_TMP="gs://minikube-flake-rate/$(basename "$TMP_DATA")" + +# Copy data to append to GCS +gsutil cp $TMP_DATA $GCS_TMP +# Append data to existing data. +gsutil compose gs://minikube-flake-rate/data.csv $GCS_TMP gs://minikube-flake-rate/data.csv +# Clear all the temp stuff. +rm $TMP_DATA +gsutil rm $GCS_TMP From d245cfcdf7e8d5238462557962dbf9630ed630e6 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 3 Jun 2021 14:12:03 -0700 Subject: [PATCH 027/122] Move all flake rate files to Jenkins to allow auto-upload. --- hack/{ => jenkins}/test-flake-chart/collect_data.sh | 0 hack/{ => jenkins}/test-flake-chart/compute_flake_rate.go | 0 hack/{ => jenkins}/test-flake-chart/compute_flake_rate_test.go | 0 hack/{ => jenkins}/test-flake-chart/flake_chart.html | 0 hack/{ => jenkins}/test-flake-chart/flake_chart.js | 0 hack/{ => jenkins}/test-flake-chart/jenkins_upload_tests.sh | 0 hack/{ => jenkins}/test-flake-chart/optimize_data.sh | 0 hack/{ => jenkins}/test-flake-chart/process_data.sh | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename hack/{ => jenkins}/test-flake-chart/collect_data.sh (100%) rename hack/{ => jenkins}/test-flake-chart/compute_flake_rate.go (100%) rename hack/{ => jenkins}/test-flake-chart/compute_flake_rate_test.go (100%) rename hack/{ => jenkins}/test-flake-chart/flake_chart.html (100%) rename hack/{ => jenkins}/test-flake-chart/flake_chart.js (100%) rename hack/{ => jenkins}/test-flake-chart/jenkins_upload_tests.sh (100%) rename hack/{ => jenkins}/test-flake-chart/optimize_data.sh (100%) rename hack/{ => jenkins}/test-flake-chart/process_data.sh (100%) diff --git a/hack/test-flake-chart/collect_data.sh b/hack/jenkins/test-flake-chart/collect_data.sh similarity index 100% rename from hack/test-flake-chart/collect_data.sh rename to hack/jenkins/test-flake-chart/collect_data.sh diff --git a/hack/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go similarity index 100% rename from hack/test-flake-chart/compute_flake_rate.go rename to hack/jenkins/test-flake-chart/compute_flake_rate.go diff --git a/hack/test-flake-chart/compute_flake_rate_test.go b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go similarity index 100% rename from hack/test-flake-chart/compute_flake_rate_test.go rename to hack/jenkins/test-flake-chart/compute_flake_rate_test.go diff --git a/hack/test-flake-chart/flake_chart.html b/hack/jenkins/test-flake-chart/flake_chart.html similarity index 100% rename from hack/test-flake-chart/flake_chart.html rename to hack/jenkins/test-flake-chart/flake_chart.html diff --git a/hack/test-flake-chart/flake_chart.js b/hack/jenkins/test-flake-chart/flake_chart.js similarity index 100% rename from hack/test-flake-chart/flake_chart.js rename to hack/jenkins/test-flake-chart/flake_chart.js diff --git a/hack/test-flake-chart/jenkins_upload_tests.sh b/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh similarity index 100% rename from hack/test-flake-chart/jenkins_upload_tests.sh rename to hack/jenkins/test-flake-chart/jenkins_upload_tests.sh diff --git a/hack/test-flake-chart/optimize_data.sh b/hack/jenkins/test-flake-chart/optimize_data.sh similarity index 100% rename from hack/test-flake-chart/optimize_data.sh rename to hack/jenkins/test-flake-chart/optimize_data.sh diff --git a/hack/test-flake-chart/process_data.sh b/hack/jenkins/test-flake-chart/process_data.sh similarity index 100% rename from hack/test-flake-chart/process_data.sh rename to hack/jenkins/test-flake-chart/process_data.sh From cec82877d86a3299ba3258b75222121f9756e2a1 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 3 Jun 2021 14:25:04 -0700 Subject: [PATCH 028/122] Format flake rates into CSV containing environment, test, and flake rate. --- hack/jenkins/test-flake-chart/compute_flake_rate.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index ea622a4a80..55f81bae15 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -45,12 +45,11 @@ func main() { splitEntries := SplitData(testEntries) filteredEntries := FilterRecentEntries(splitEntries, *dateRange) flakeRates := ComputeFlakeRates(filteredEntries) + fmt.Println("Environment,Test,Flake Rate") for environment, environmentSplit := range flakeRates { - fmt.Printf("%s {\n", environment) for test, flakeRate := range environmentSplit { - fmt.Printf(" %s: %f\n", test, flakeRate) + fmt.Printf("%s,%s,%f\n", environment, test, flakeRate) } - fmt.Printf("}\n") } } From 934ac1f109326e7bf8b7228f087bb99e1691fe4e Mon Sep 17 00:00:00 2001 From: JacekDuszenko Date: Fri, 4 Jun 2021 00:05:37 +0100 Subject: [PATCH 029/122] add json deserialization to embed-certs from global config --- pkg/minikube/config/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index aee9b1ac28..274d5d3e83 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -34,7 +34,7 @@ type Profile struct { type ClusterConfig struct { Name string KeepContext bool // used by start and profile command to or not to switch kubectl's current context - EmbedCerts bool // used by kubeconfig.Setup + EmbedCerts bool `json:"embed-certs"` // used by kubeconfig.Setup MinikubeISO string // ISO used for VM-drivers. KicBaseImage string // base-image used for docker/podman drivers. Memory int From 03b793c7d040dbffa2a608d8b0f2e833e94d9137 Mon Sep 17 00:00:00 2001 From: Vishal Jain Date: Wed, 2 Jun 2021 20:00:45 -0700 Subject: [PATCH 030/122] Fix names. --- cmd/minikube/cmd/delete.go | 4 ++-- cmd/minikube/cmd/delete_test.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index 3104e57bfb..ec657fe817 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -87,7 +87,7 @@ func (error DeletionError) Error() string { return error.Err.Error() } -var DeleteHostAndDirectoriesGetter = func(api libmachine.API, cc *config.ClusterConfig, profileName string) error { +var hostAndDirsDeleter = func(api libmachine.API, cc *config.ClusterConfig, profileName string) error { if err := killMountProcess(); err != nil { out.FailureT("Failed to kill mount process: {{.error}}", out.V{"error": err}) } @@ -300,7 +300,7 @@ func deleteProfile(ctx context.Context, profile *config.Profile) error { } } - if err := DeleteHostAndDirectoriesGetter(api, cc, profile.Name); err != nil { + if err := hostAndDirsDeleter(api, cc, profile.Name); err != nil { return err } diff --git a/cmd/minikube/cmd/delete_test.go b/cmd/minikube/cmd/delete_test.go index c878a1a2ca..fff2ffabf8 100644 --- a/cmd/minikube/cmd/delete_test.go +++ b/cmd/minikube/cmd/delete_test.go @@ -117,7 +117,7 @@ func TestDeleteProfile(t *testing.T) { t.Logf("load failure: %v", err) } - DeleteHostAndDirectoriesGetter = DeleteHostAndDirectoriesMock + hostAndDirsDeleter = hostAndDirsDeleterMock errs := DeleteProfiles([]*config.Profile{profile}) if len(errs) > 0 { HandleDeletionErrors(errs) @@ -158,7 +158,7 @@ func TestDeleteProfile(t *testing.T) { } } -var DeleteHostAndDirectoriesMock = func(api libmachine.API, cc *config.ClusterConfig, profileName string) error { +var hostAndDirsDeleterMock = func(api libmachine.API, cc *config.ClusterConfig, profileName string) error { return deleteContextTest() } @@ -222,7 +222,7 @@ func TestDeleteAllProfiles(t *testing.T) { } profiles := append(validProfiles, inValidProfiles...) - DeleteHostAndDirectoriesGetter = DeleteHostAndDirectoriesMock + hostAndDirsDeleter = hostAndDirsDeleterMock errs := DeleteProfiles(profiles) if errs != nil { From b7a6dd0b5e141bcf33df6a0f0042746a837509a9 Mon Sep 17 00:00:00 2001 From: JacekDuszenko Date: Sat, 5 Jun 2021 23:52:40 +0100 Subject: [PATCH 031/122] implement embed certs global config as EmbedCerts --- cmd/minikube/cmd/config/config.go | 2 +- cmd/minikube/cmd/root.go | 1 + cmd/minikube/cmd/start.go | 1 - pkg/minikube/config/config.go | 2 ++ pkg/minikube/config/types.go | 2 +- site/content/en/docs/commands/config.md | 2 +- 6 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/minikube/cmd/config/config.go b/cmd/minikube/cmd/config/config.go index 8ef3630915..bc9c5d6d84 100644 --- a/cmd/minikube/cmd/config/config.go +++ b/cmd/minikube/cmd/config/config.go @@ -172,7 +172,7 @@ var settings = []Setting{ setMap: SetMap, }, { - name: "embed-certs", + name: config.EmbedCerts, set: SetBool, }, { diff --git a/cmd/minikube/cmd/root.go b/cmd/minikube/cmd/root.go index cfcd7f0276..b702496a6c 100644 --- a/cmd/minikube/cmd/root.go +++ b/cmd/minikube/cmd/root.go @@ -301,6 +301,7 @@ func setupViper() { viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) viper.AutomaticEnv() + viper.RegisterAlias(config.EmbedCerts, embedCerts) viper.SetDefault(config.WantUpdateNotification, true) viper.SetDefault(config.ReminderWaitPeriodInHours, 24) viper.SetDefault(config.WantReportError, false) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 0d4f574e29..bd0c4f162d 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -169,7 +169,6 @@ func runStart(cmd *cobra.Command, args []string) { out.WarningT("Profile name '{{.name}}' is not valid", out.V{"name": ClusterFlagValue()}) exit.Message(reason.Usage, "Only alphanumeric and dashes '-' are permitted. Minimum 2 characters, starting with alphanumeric.") } - existing, err := config.Load(ClusterFlagValue()) if err != nil && !config.IsNotExist(err) { kind := reason.HostConfigLoad diff --git a/pkg/minikube/config/config.go b/pkg/minikube/config/config.go index f194099266..22e99f1e3b 100644 --- a/pkg/minikube/config/config.go +++ b/pkg/minikube/config/config.go @@ -58,6 +58,8 @@ const ( AddonRegistries = "addon-registries" // AddonListFlag represents the key for addons parameter AddonListFlag = "addons" + // EmbedCerts represents the config for embedding certificates in kubeconfig + EmbedCerts = "EmbedCerts" ) var ( diff --git a/pkg/minikube/config/types.go b/pkg/minikube/config/types.go index 274d5d3e83..aee9b1ac28 100644 --- a/pkg/minikube/config/types.go +++ b/pkg/minikube/config/types.go @@ -34,7 +34,7 @@ type Profile struct { type ClusterConfig struct { Name string KeepContext bool // used by start and profile command to or not to switch kubectl's current context - EmbedCerts bool `json:"embed-certs"` // used by kubeconfig.Setup + EmbedCerts bool // used by kubeconfig.Setup MinikubeISO string // ISO used for VM-drivers. KicBaseImage string // base-image used for docker/podman drivers. Memory int diff --git a/site/content/en/docs/commands/config.md b/site/content/en/docs/commands/config.md index 51ff431b20..16f8f5a382 100644 --- a/site/content/en/docs/commands/config.md +++ b/site/content/en/docs/commands/config.md @@ -41,7 +41,7 @@ Configurable fields: * hyperv-virtual-switch * disable-driver-mounts * cache - * embed-certs + * EmbedCerts * native-ssh ```shell From a80f3bc5aead4e45f19c94419c8ebb9ce6a48c3e Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 13:49:05 -0700 Subject: [PATCH 032/122] Add license to upload_tests script. --- .../test-flake-chart/jenkins_upload_tests.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh b/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh index e609893b80..28db50692f 100755 --- a/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh +++ b/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh @@ -1,5 +1,19 @@ #!/bin/bash +# Copyright 2018 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + set -x -o pipefail if [ "$#" -ne 1 ]; then From 9e7f1ebbf07bfcf8d9b2199cd7b8de6a2e5bb841 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 13:49:40 -0700 Subject: [PATCH 033/122] Make computing flake rates print out percentages (with fixed 2 decimal precision) rather than floats. --- hack/jenkins/test-flake-chart/compute_flake_rate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index 55f81bae15..4f71aa3cf5 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -48,7 +48,7 @@ func main() { fmt.Println("Environment,Test,Flake Rate") for environment, environmentSplit := range flakeRates { for test, flakeRate := range environmentSplit { - fmt.Printf("%s,%s,%f\n", environment, test, flakeRate) + fmt.Printf("%s,%s,%.2f\n", environment, test, flakeRate*100) } } } From 501b238841278647eb940562838dc4dc90ce4c50 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 14:09:32 -0700 Subject: [PATCH 034/122] Use "set -eu -o pipefail" for all scripts. Previously failing commands in scripts wouldn't make them actually fail. Now it does! --- hack/jenkins/test-flake-chart/jenkins_upload_tests.sh | 2 +- hack/jenkins/test-flake-chart/optimize_data.sh | 2 ++ hack/jenkins/test-flake-chart/process_data.sh | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh b/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh index 28db50692f..7d310f9486 100755 --- a/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh +++ b/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -x -o pipefail +set -eu -o pipefail if [ "$#" -ne 1 ]; then echo "Wrong number of arguments. Usage: jenkins_upload_tests.sh " 1>&2 diff --git a/hack/jenkins/test-flake-chart/optimize_data.sh b/hack/jenkins/test-flake-chart/optimize_data.sh index 1fd93f1901..67dae593e2 100755 --- a/hack/jenkins/test-flake-chart/optimize_data.sh +++ b/hack/jenkins/test-flake-chart/optimize_data.sh @@ -14,5 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +set -eu -o pipefail + # Take input CSV. For each field, if it is the same as the previous row, replace it with an empty string. awk -F, 'BEGIN {OFS = FS} { for(i=1; i<=NF; i++) { if($i == j[i]) { $i = ""; } else { j[i] = $i; } } printf "%s\n",$0 }' diff --git a/hack/jenkins/test-flake-chart/process_data.sh b/hack/jenkins/test-flake-chart/process_data.sh index b3a6e26a9e..7907e69673 100755 --- a/hack/jenkins/test-flake-chart/process_data.sh +++ b/hack/jenkins/test-flake-chart/process_data.sh @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +set -eu -o pipefail + # Print header. printf "Commit Hash,Test Date,Environment,Test,Status,Duration\n" From 7c4615460088198629851054473970ba3daa363c Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 14:12:31 -0700 Subject: [PATCH 035/122] Rename jenkins_upload_tests.sh to upload_tests.sh. Since these scripts are already in the jenkins folder, having the jenkins prefix is redundant. --- hack/jenkins/common.sh | 2 +- .../{jenkins_upload_tests.sh => upload_tests.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename hack/jenkins/test-flake-chart/{jenkins_upload_tests.sh => upload_tests.sh} (100%) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 0832b6b3e2..9d080baa88 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -442,7 +442,7 @@ if [ -z "${EXTERNAL}" ]; then echo ">> uploading ${SUMMARY_OUT}" gsutil -qm cp "${SUMMARY_OUT}" "gs://${JOB_GCS_BUCKET}_summary.json" || true if [[ "${MINIKUBE_LOCATION}" == "master" ]]; then - ./test-flake-chart/jenkins_upload_tests.sh "${SUMMARY_OUT}" + ./test-flake-chart/upload_tests.sh "${SUMMARY_OUT}" fi else # Otherwise, put the results in a predictable spot so the upload job can find them diff --git a/hack/jenkins/test-flake-chart/jenkins_upload_tests.sh b/hack/jenkins/test-flake-chart/upload_tests.sh similarity index 100% rename from hack/jenkins/test-flake-chart/jenkins_upload_tests.sh rename to hack/jenkins/test-flake-chart/upload_tests.sh From 8f953781a2fc31ffed2ca5f8c38007de30717cc5 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 14:18:53 -0700 Subject: [PATCH 036/122] Create report_flakes script to comment on PRs about flake rates of failed tests. --- hack/jenkins/common.sh | 2 + .../jenkins/test-flake-chart/report_flakes.sh | 74 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100755 hack/jenkins/test-flake-chart/report_flakes.sh diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 9d080baa88..b153185ee3 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -443,6 +443,8 @@ if [ -z "${EXTERNAL}" ]; then gsutil -qm cp "${SUMMARY_OUT}" "gs://${JOB_GCS_BUCKET}_summary.json" || true if [[ "${MINIKUBE_LOCATION}" == "master" ]]; then ./test-flake-chart/upload_tests.sh "${SUMMARY_OUT}" + elif [[ "${JOB_NAME}" == "Docker_Linux" ]]; then + ./test-flake-chart/report_flakes.sh "${MINIKUBE_LOCATION}" "${SUMMARY_OUT}" "${JOB_NAME}" fi else # Otherwise, put the results in a predictable spot so the upload job can find them diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh new file mode 100755 index 0000000000..86a4e35e8f --- /dev/null +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Copyright 2018 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu -o pipefail + +if [ "$#" -ne 2 ]; then + echo "Wrong number of arguments. Usage: report_flakes.sh " 1>&2 + exit 1 +fi + +PR_NUMBER=$1 +SUMMARY_DATA=$2 +ENVIRONMENT=$3 + +# To prevent having a super-long comment, add a maximum number of tests to report. +MAX_REPORTED_TESTS=30 + +DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) + +TMP_DATA=$(mktemp) +# 1) Process the data in the gopogh summary. +# 2) Filter tests to only include failed tests on the environment (and only get their names). +# 3) Sort the names of the tests. +# 4) Store in file $TMP_DATA. +< "$SUMMARY_DATA" $DIR/process_data.sh \ + | sed -n -r -e "s/[0-9a-f]*,[0-9-]*,$ENVIRONMENT,([a-zA-Z\/_-]*),Failed,[.0-9]*/\1/p" \ + | sort \ + > "$TMP_DATA" + +# Download the precomputed flake rates from the GCS bucket into file $TMP_FLAKE_RATES. +TMP_FLAKE_RATES=$(mktemp) +gsutil cp gs://minikube-flake-rate/flake_rates.csv "$TMP_FLAKE_RATES" + +TMP_FAILED_RATES="$TMP_FLAKE_RATES\_filtered" +# 1) Parse/filter the flake rates to only include the test name and flake rates for environment. +# 2) Sort the flake rates based on test name. +# 3) Join the flake rates with the failing tests to only get flake rates of failing tests. +# 4) Sort failed test flake rates based on the flakiness of that test - stable tests should be first on the list. +# 5) Store in file $TMP_FAILED_RATES. +< "$TMP_FLAKE_RATES" sed -n -r -e "s/$ENVIRONMENT,([a-zA-Z\/_-]*),([.0-9]*)/\1,\2/p" \ + | sort -t, -k1,1 \ + | join -t , -j 1 "$TMP_DATA" - \ + | sort -g -t, -k2,2 \ + > "$TMP_FAILED_RATES" + +# Create the comment template. +TMP_COMMENT=$(mktemp) +printf "These are the flake rates of all failed tests on %s.\n|Failed Tests|Flake Rate (%%)|\n|---|---|\n" "$ENVIRONMENT" > "$TMP_COMMENT" +# 1) Get the first $MAX_REPORTED_TESTS lines. +# 2) Print a row in the table with the test name, flake rate, and a link to the flake chart for that test. +# 3) Append these rows to file $TMP_COMMENT. +< "$TMP_FAILED_RATES" head -n $MAX_REPORTED_TESTS \ + | sed -n -r -e "s/([a-zA-Z\/_-]*),([.0-9]*)/|\1|\2 ([chart](https:\/\/storage.googleapis.com\/minikube-flake-rate\/flake_chart.html?env=$ENVIRONMENT\&test=\1))|/p" \ + >> "$TMP_COMMENT" + +# If there are too many failing tests, add an extra row explaining this, and a message after the table. +if [[ $(wc -l < "$TMP_FAILED_RATES") -gt 30 ]]; then + printf "|More tests...|Continued...|\n\nToo many tests failed - See test logs for more details." >> "$TMP_COMMENT" +fi + +gh issue comment "https://github.com/kubernetes/minikube/pull/$PR_NUMBER" --body "$(cat $TMP_COMMENT)" From 139d7e37710ee729955ae2afd910a176a20251c9 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 16:32:20 -0700 Subject: [PATCH 037/122] Fix lints in compute_flake_rate.go and compute_flake_rate_test.go. --- .../test-flake-chart/compute_flake_rate.go | 2 +- .../compute_flake_rate_test.go | 126 +++++++++--------- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index 4f71aa3cf5..c8c9806382 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -79,7 +79,7 @@ func ReadData(file io.Reader) []TestEntry { fields := strings.Split(line, ",") if firstLine { if len(fields) != 6 { - exit(fmt.Sprintf("Data CSV in incorrect format. Expected 6 columns, but got %d", len(fields)), fmt.Errorf("Bad CSV format")) + exit(fmt.Sprintf("Data CSV in incorrect format. Expected 6 columns, but got %d", len(fields)), fmt.Errorf("bad CSV format")) } firstLine = false } diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go index 22c1f6b476..0154ee3b02 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go @@ -23,8 +23,8 @@ import ( "time" ) -func simpleDate(year int, month time.Month, day int) time.Time { - return time.Date(year, month, day, 0, 0, 0, 0, time.UTC) +func simpleDate(year int, day int) time.Time { + return time.Date(year, time.January, day, 0, 0, 0, 0, time.UTC) } func compareEntrySlices(t *testing.T, actualData, expectedData []TestEntry, extra string) { @@ -62,31 +62,31 @@ func TestReadData(t *testing.T) { { name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Passed", }, { name: "test2", environment: "env2", - date: simpleDate(2001, time.January, 1), + date: simpleDate(2001, 1), status: "Failed", }, { name: "test1", environment: "env2", - date: simpleDate(2001, time.January, 1), + date: simpleDate(2001, 1), status: "Failed", }, { name: "test1", environment: "env2", - date: simpleDate(2002, time.January, 1), + date: simpleDate(2002, 1), status: "Passed", }, { name: "test3", environment: "env3", - date: simpleDate(2003, time.January, 1), + date: simpleDate(2003, 1), status: "Passed", }, } @@ -129,44 +129,44 @@ func compareSplitData(t *testing.T, actual, expected map[string]map[string][]Tes } func TestSplitData(t *testing.T) { - entry_e1_t1_1, entry_e1_t1_2 := TestEntry{ + entryE1T1_1, entryE1T1_2 := TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Passed", }, TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 2), + date: simpleDate(2000, 2), status: "Passed", } - entry_e1_t2 := TestEntry{ + entryE1T2 := TestEntry{ name: "test2", environment: "env1", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Passed", } - entry_e2_t1 := TestEntry{ + entryE2T1 := TestEntry{ name: "test1", environment: "env2", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Passed", } - entry_e2_t2 := TestEntry{ + entryE2T2 := TestEntry{ name: "test2", environment: "env2", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Passed", } - actual := SplitData([]TestEntry{entry_e1_t1_1, entry_e1_t1_2, entry_e1_t2, entry_e2_t1, entry_e2_t2}) + actual := SplitData([]TestEntry{entryE1T1_1, entryE1T1_2, entryE1T2, entryE2T1, entryE2T2}) expected := map[string]map[string][]TestEntry{ "env1": { - "test1": {entry_e1_t1_1, entry_e1_t1_2}, - "test2": {entry_e1_t2}, + "test1": {entryE1T1_1, entryE1T1_2}, + "test2": {entryE1T2}, }, "env2": { - "test1": {entry_e2_t1}, - "test2": {entry_e2_t2}, + "test1": {entryE2T1}, + "test2": {entryE2T2}, }, } @@ -174,85 +174,85 @@ func TestSplitData(t *testing.T) { } func TestFilterRecentEntries(t *testing.T) { - entry_e1_t1_r1, entry_e1_t1_r2, entry_e1_t1_r3, entry_e1_t1_o1, entry_e1_t1_o2 := TestEntry{ + entryE1T1R1, entryE1T1R2, entryE1T1R3, entryE1T1O1, entryE1T1O2 := TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 4), + date: simpleDate(2000, 4), status: "Passed", }, TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 3), + date: simpleDate(2000, 3), status: "Passed", }, TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 3), + date: simpleDate(2000, 3), status: "Passed", }, TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 2), + date: simpleDate(2000, 2), status: "Passed", }, TestEntry{ name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Passed", } - entry_e1_t2_r1, entry_e1_t2_r2, entry_e1_t2_o1 := TestEntry{ + entryE1T2R1, entryE1T2R2, entryE1T2O1 := TestEntry{ name: "test2", environment: "env1", - date: simpleDate(2001, time.January, 3), + date: simpleDate(2001, 3), status: "Passed", }, TestEntry{ name: "test2", environment: "env1", - date: simpleDate(2001, time.January, 2), + date: simpleDate(2001, 2), status: "Passed", }, TestEntry{ name: "test2", environment: "env1", - date: simpleDate(2001, time.January, 1), + date: simpleDate(2001, 1), status: "Passed", } - entry_e2_t2_r1, entry_e2_t2_r2, entry_e2_t2_o1 := TestEntry{ + entryE2T2R1, entryE2T2R2, entryE2T2O1 := TestEntry{ name: "test2", environment: "env2", - date: simpleDate(2003, time.January, 3), + date: simpleDate(2003, 3), status: "Passed", }, TestEntry{ name: "test2", environment: "env2", - date: simpleDate(2003, time.January, 2), + date: simpleDate(2003, 2), status: "Passed", }, TestEntry{ name: "test2", environment: "env2", - date: simpleDate(2003, time.January, 1), + date: simpleDate(2003, 1), status: "Passed", } actualData := FilterRecentEntries(map[string]map[string][]TestEntry{ "env1": { "test1": { - entry_e1_t1_r1, - entry_e1_t1_r2, - entry_e1_t1_r3, - entry_e1_t1_o1, - entry_e1_t1_o2, + entryE1T1R1, + entryE1T1R2, + entryE1T1R3, + entryE1T1O1, + entryE1T1O2, }, "test2": { - entry_e1_t2_r1, - entry_e1_t2_r2, - entry_e1_t2_o1, + entryE1T2R1, + entryE1T2R2, + entryE1T2O1, }, }, "env2": { "test2": { - entry_e2_t2_r1, - entry_e2_t2_r2, - entry_e2_t2_o1, + entryE2T2R1, + entryE2T2R2, + entryE2T2O1, }, }, }, 2) @@ -260,19 +260,19 @@ func TestFilterRecentEntries(t *testing.T) { expectedData := map[string]map[string][]TestEntry{ "env1": { "test1": { - entry_e1_t1_r1, - entry_e1_t1_r2, - entry_e1_t1_r3, + entryE1T1R1, + entryE1T1R2, + entryE1T1R3, }, "test2": { - entry_e1_t2_r1, - entry_e1_t2_r2, + entryE1T2R1, + entryE1T2R2, }, }, "env2": { "test2": { - entry_e2_t2_r1, - entry_e2_t2_r2, + entryE2T2R1, + entryE2T2R2, }, }, } @@ -287,27 +287,27 @@ func TestComputeFlakeRates(t *testing.T) { { name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 4), + date: simpleDate(2000, 4), status: "Passed", }, { name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 3), + date: simpleDate(2000, 3), status: "Passed", }, { name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 3), + date: simpleDate(2000, 3), status: "Passed", }, { name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 2), + date: simpleDate(2000, 2), status: "Passed", }, { name: "test1", environment: "env1", - date: simpleDate(2000, time.January, 1), + date: simpleDate(2000, 1), status: "Failed", }, }, @@ -315,17 +315,17 @@ func TestComputeFlakeRates(t *testing.T) { { name: "test2", environment: "env1", - date: simpleDate(2001, time.January, 3), + date: simpleDate(2001, 3), status: "Failed", }, { name: "test2", environment: "env1", - date: simpleDate(2001, time.January, 2), + date: simpleDate(2001, 2), status: "Failed", }, { name: "test2", environment: "env1", - date: simpleDate(2001, time.January, 1), + date: simpleDate(2001, 1), status: "Failed", }, }, @@ -335,12 +335,12 @@ func TestComputeFlakeRates(t *testing.T) { { name: "test2", environment: "env2", - date: simpleDate(2003, time.January, 3), + date: simpleDate(2003, 3), status: "Passed", }, TestEntry{ name: "test2", environment: "env2", - date: simpleDate(2003, time.January, 2), + date: simpleDate(2003, 2), status: "Failed", }, }, From 716f6901890ae3882f4710f0fcd7c8ffc080df47 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Mon, 7 Jun 2021 16:39:06 -0700 Subject: [PATCH 038/122] Change copyright to 2021. --- hack/jenkins/test-flake-chart/collect_data.sh | 2 +- hack/jenkins/test-flake-chart/compute_flake_rate.go | 2 +- hack/jenkins/test-flake-chart/compute_flake_rate_test.go | 2 +- hack/jenkins/test-flake-chart/optimize_data.sh | 2 +- hack/jenkins/test-flake-chart/process_data.sh | 2 +- hack/jenkins/test-flake-chart/report_flakes.sh | 2 +- hack/jenkins/test-flake-chart/upload_tests.sh | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hack/jenkins/test-flake-chart/collect_data.sh b/hack/jenkins/test-flake-chart/collect_data.sh index 44273f6d80..a03b726825 100755 --- a/hack/jenkins/test-flake-chart/collect_data.sh +++ b/hack/jenkins/test-flake-chart/collect_data.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Kubernetes Authors All rights reserved. +# Copyright 2021 The Kubernetes Authors All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index c8c9806382..b3e4c2013f 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Kubernetes Authors All rights reserved. +Copyright 2021 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go index 0154ee3b02..c6407c16bd 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Kubernetes Authors All rights reserved. +Copyright 2021 The Kubernetes Authors All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/hack/jenkins/test-flake-chart/optimize_data.sh b/hack/jenkins/test-flake-chart/optimize_data.sh index 67dae593e2..2bc140fc28 100755 --- a/hack/jenkins/test-flake-chart/optimize_data.sh +++ b/hack/jenkins/test-flake-chart/optimize_data.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Kubernetes Authors All rights reserved. +# Copyright 2021 The Kubernetes Authors All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/hack/jenkins/test-flake-chart/process_data.sh b/hack/jenkins/test-flake-chart/process_data.sh index 7907e69673..25c6ba5ec6 100755 --- a/hack/jenkins/test-flake-chart/process_data.sh +++ b/hack/jenkins/test-flake-chart/process_data.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Kubernetes Authors All rights reserved. +# Copyright 2021 The Kubernetes Authors All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index 86a4e35e8f..1cd4490c84 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Kubernetes Authors All rights reserved. +# Copyright 2021 The Kubernetes Authors All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/hack/jenkins/test-flake-chart/upload_tests.sh b/hack/jenkins/test-flake-chart/upload_tests.sh index 7d310f9486..508d76f9ad 100755 --- a/hack/jenkins/test-flake-chart/upload_tests.sh +++ b/hack/jenkins/test-flake-chart/upload_tests.sh @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2018 The Kubernetes Authors All rights reserved. +# Copyright 2021 The Kubernetes Authors All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 3aa922813c86644510c2db7e6789dda4fa2447a7 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 8 Jun 2021 11:50:14 -0700 Subject: [PATCH 039/122] Fix wrong number of parameters for report_flakes.sh. --- hack/jenkins/test-flake-chart/report_flakes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index 1cd4490c84..951e929183 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -16,7 +16,7 @@ set -eu -o pipefail -if [ "$#" -ne 2 ]; then +if [ "$#" -ne 3 ]; then echo "Wrong number of arguments. Usage: report_flakes.sh " 1>&2 exit 1 fi From fcbae7eaa143ae6e1a330518a73f0191de132f50 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 8 Jun 2021 11:54:08 -0700 Subject: [PATCH 040/122] Make sure gh is present when running report_flakes.sh. --- hack/jenkins/test-flake-chart/report_flakes.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index 951e929183..b0933fa56a 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -71,4 +71,7 @@ if [[ $(wc -l < "$TMP_FAILED_RATES") -gt 30 ]]; then printf "|More tests...|Continued...|\n\nToo many tests failed - See test logs for more details." >> "$TMP_COMMENT" fi +# install gh if not present +sudo $DIR/../installers/check_install_gh.sh || true + gh issue comment "https://github.com/kubernetes/minikube/pull/$PR_NUMBER" --body "$(cat $TMP_COMMENT)" From fb8e4d982bce78c88183e4360e6843a81f60380a Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 8 Jun 2021 13:06:28 -0700 Subject: [PATCH 041/122] Clean up compute_flake_rate.go. --- hack/jenkins/test-flake-chart/compute_flake_rate.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index b3e4c2013f..69d40042f2 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -155,7 +155,7 @@ func FilterRecentEntries(splitEntries map[string]map[string][]TestEntry, dateRan return dates[j].Before(dates[i]) }) datesInRange := make([]time.Time, 0, dateRange) - var lastDate time.Time = time.Date(0, 0, 0, 0, 0, 0, 0, time.Local) + var lastDate time.Time // Go through each date. for _, date := range dates { // If date is the same as last date, ignore it. @@ -175,7 +175,7 @@ func FilterRecentEntries(splitEntries map[string]map[string][]TestEntry, dateRan for _, entry := range testSplit { // Look for the first element <= entry.date index := sort.Search(len(datesInRange), func(i int) bool { - return datesInRange[i].Before(entry.date) || datesInRange[i].Equal(entry.date) + return !datesInRange[i].After(entry.date) }) // If no date is <= entry.date, or the found date does not equal entry.date. if index == len(datesInRange) || !datesInRange[index].Equal(entry.date) { From e089973f6530a2f598a9ae041b8717523fd479cf Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 9 Jun 2021 15:21:43 -0700 Subject: [PATCH 042/122] Create SplitEntryMap type to simplify some definitions. --- .../test-flake-chart/compute_flake_rate.go | 15 +++++++++------ .../test-flake-chart/compute_flake_rate_test.go | 10 +++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index 69d40042f2..4da2e48ab4 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -60,6 +60,9 @@ type TestEntry struct { status string } +// A map with keys of (environment, test_name) to values of slcies of TestEntry. +type SplitEntryMap map[string]map[string][]TestEntry + // Reads CSV `file` and consumes each line to be a single TestEntry. func ReadData(file io.Reader) []TestEntry { testEntries := []TestEntry{} @@ -110,8 +113,8 @@ func ReadData(file io.Reader) []TestEntry { } // Splits `testEntries` up into maps indexed first by environment and then by test. -func SplitData(testEntries []TestEntry) map[string]map[string][]TestEntry { - splitEntries := make(map[string]map[string][]TestEntry) +func SplitData(testEntries []TestEntry) SplitEntryMap { + splitEntries := make(SplitEntryMap) for _, entry := range testEntries { appendEntry(splitEntries, entry.environment, entry.name, entry) @@ -121,7 +124,7 @@ func SplitData(testEntries []TestEntry) map[string]map[string][]TestEntry { } // Appends `entry` to `splitEntries` at the `environment` and `test`. -func appendEntry(splitEntries map[string]map[string][]TestEntry, environment, test string, entry TestEntry) { +func appendEntry(splitEntries SplitEntryMap, environment, test string, entry TestEntry) { // Lookup the environment. environmentSplit, ok := splitEntries[environment] if !ok { @@ -141,8 +144,8 @@ func appendEntry(splitEntries map[string]map[string][]TestEntry, environment, te } // Filters `splitEntries` to include only the most recent `date_range` dates. -func FilterRecentEntries(splitEntries map[string]map[string][]TestEntry, dateRange uint) map[string]map[string][]TestEntry { - filteredEntries := make(map[string]map[string][]TestEntry) +func FilterRecentEntries(splitEntries SplitEntryMap, dateRange uint) SplitEntryMap { + filteredEntries := make(SplitEntryMap) for environment, environmentSplit := range splitEntries { for test, testSplit := range environmentSplit { @@ -189,7 +192,7 @@ func FilterRecentEntries(splitEntries map[string]map[string][]TestEntry, dateRan } // Computes the flake rates over each entry in `splitEntries`. -func ComputeFlakeRates(splitEntries map[string]map[string][]TestEntry) map[string]map[string]float32 { +func ComputeFlakeRates(splitEntries SplitEntryMap) map[string]map[string]float32 { flakeRates := make(map[string]map[string]float32) for environment, environmentSplit := range splitEntries { for test, testSplit := range environmentSplit { diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go index c6407c16bd..897d32311a 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go @@ -94,7 +94,7 @@ func TestReadData(t *testing.T) { compareEntrySlices(t, actualData, expectedData, "") } -func compareSplitData(t *testing.T, actual, expected map[string]map[string][]TestEntry) { +func compareSplitData(t *testing.T, actual, expected SplitEntryMap) { for environment, actualTests := range actual { expectedTests, environmentOk := expected[environment] if !environmentOk { @@ -159,7 +159,7 @@ func TestSplitData(t *testing.T) { status: "Passed", } actual := SplitData([]TestEntry{entryE1T1_1, entryE1T1_2, entryE1T2, entryE2T1, entryE2T2}) - expected := map[string]map[string][]TestEntry{ + expected := SplitEntryMap{ "env1": { "test1": {entryE1T1_1, entryE1T1_2}, "test2": {entryE1T2}, @@ -233,7 +233,7 @@ func TestFilterRecentEntries(t *testing.T) { status: "Passed", } - actualData := FilterRecentEntries(map[string]map[string][]TestEntry{ + actualData := FilterRecentEntries(SplitEntryMap{ "env1": { "test1": { entryE1T1R1, @@ -257,7 +257,7 @@ func TestFilterRecentEntries(t *testing.T) { }, }, 2) - expectedData := map[string]map[string][]TestEntry{ + expectedData := SplitEntryMap{ "env1": { "test1": { entryE1T1R1, @@ -281,7 +281,7 @@ func TestFilterRecentEntries(t *testing.T) { } func TestComputeFlakeRates(t *testing.T) { - actualData := ComputeFlakeRates(map[string]map[string][]TestEntry{ + actualData := ComputeFlakeRates(SplitEntryMap{ "env1": { "test1": { { From 22ca607c6a71ba3bfecd9506f965714b30cbf960 Mon Sep 17 00:00:00 2001 From: Felipe Crescencio de Oliveira Date: Thu, 10 Jun 2021 00:31:02 -0300 Subject: [PATCH 043/122] Fix: Certificates folder for x509 error For x509: certificate signed by unknown authority problem in minikube since version v1.20.0 I just found `~/.minikube/certs` dir. I pasted my PEM files over there and it solve my problem. --- site/content/en/docs/handbook/vpn_and_proxy.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/site/content/en/docs/handbook/vpn_and_proxy.md b/site/content/en/docs/handbook/vpn_and_proxy.md index bcd92ee5c8..5b92601853 100644 --- a/site/content/en/docs/handbook/vpn_and_proxy.md +++ b/site/content/en/docs/handbook/vpn_and_proxy.md @@ -93,6 +93,10 @@ Ask your IT department for the appropriate PEM file, and add it to: `~/.minikube/files/etc/ssl/certs` +or + +`~/.minikube/certs` + Then run `minikube delete` and `minikube start`. #### downloading binaries: proxyconnect tcp: tls: oversized record received with length 20527 From e9e7b85e025878bc83279d9afbf1553b6de3f59d Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 11:08:44 -0700 Subject: [PATCH 044/122] Make types and functions private. --- .../test-flake-chart/compute_flake_rate.go | 34 ++++++------ .../compute_flake_rate_test.go | 52 +++++++++---------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index 4da2e48ab4..be741f5bb1 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -41,10 +41,10 @@ func main() { exit("Unable to read data CSV", err) } - testEntries := ReadData(file) - splitEntries := SplitData(testEntries) - filteredEntries := FilterRecentEntries(splitEntries, *dateRange) - flakeRates := ComputeFlakeRates(filteredEntries) + testEntries := readData(file) + splitEntries := splitData(testEntries) + filteredEntries := filterRecentEntries(splitEntries, *dateRange) + flakeRates := computeFlakeRates(filteredEntries) fmt.Println("Environment,Test,Flake Rate") for environment, environmentSplit := range flakeRates { for test, flakeRate := range environmentSplit { @@ -53,7 +53,7 @@ func main() { } } -type TestEntry struct { +type testEntry struct { name string environment string date time.Time @@ -61,11 +61,11 @@ type TestEntry struct { } // A map with keys of (environment, test_name) to values of slcies of TestEntry. -type SplitEntryMap map[string]map[string][]TestEntry +type splitEntryMap map[string]map[string][]testEntry // Reads CSV `file` and consumes each line to be a single TestEntry. -func ReadData(file io.Reader) []TestEntry { - testEntries := []TestEntry{} +func readData(file io.Reader) []testEntry { + testEntries := []testEntry{} fileReader := bufio.NewReaderSize(file, 256) previousLine := []string{"", "", "", "", "", ""} @@ -101,7 +101,7 @@ func ReadData(file io.Reader) []TestEntry { if err != nil { fmt.Printf("Failed to parse date: %v\n", err) } - testEntries = append(testEntries, TestEntry{ + testEntries = append(testEntries, testEntry{ name: fields[3], environment: fields[2], date: date, @@ -113,8 +113,8 @@ func ReadData(file io.Reader) []TestEntry { } // Splits `testEntries` up into maps indexed first by environment and then by test. -func SplitData(testEntries []TestEntry) SplitEntryMap { - splitEntries := make(SplitEntryMap) +func splitData(testEntries []testEntry) splitEntryMap { + splitEntries := make(splitEntryMap) for _, entry := range testEntries { appendEntry(splitEntries, entry.environment, entry.name, entry) @@ -124,12 +124,12 @@ func SplitData(testEntries []TestEntry) SplitEntryMap { } // Appends `entry` to `splitEntries` at the `environment` and `test`. -func appendEntry(splitEntries SplitEntryMap, environment, test string, entry TestEntry) { +func appendEntry(splitEntries splitEntryMap, environment, test string, entry testEntry) { // Lookup the environment. environmentSplit, ok := splitEntries[environment] if !ok { // If the environment map is missing, make a map for this environment and store it. - environmentSplit = make(map[string][]TestEntry) + environmentSplit = make(map[string][]testEntry) splitEntries[environment] = environmentSplit } @@ -137,15 +137,15 @@ func appendEntry(splitEntries SplitEntryMap, environment, test string, entry Tes testSplit, ok := environmentSplit[test] if !ok { // If the test is missing, make a slice for this test. - testSplit = make([]TestEntry, 0) + testSplit = make([]testEntry, 0) // The slice is not inserted, since it will be replaced anyway. } environmentSplit[test] = append(testSplit, entry) } // Filters `splitEntries` to include only the most recent `date_range` dates. -func FilterRecentEntries(splitEntries SplitEntryMap, dateRange uint) SplitEntryMap { - filteredEntries := make(SplitEntryMap) +func filterRecentEntries(splitEntries splitEntryMap, dateRange uint) splitEntryMap { + filteredEntries := make(splitEntryMap) for environment, environmentSplit := range splitEntries { for test, testSplit := range environmentSplit { @@ -192,7 +192,7 @@ func FilterRecentEntries(splitEntries SplitEntryMap, dateRange uint) SplitEntryM } // Computes the flake rates over each entry in `splitEntries`. -func ComputeFlakeRates(splitEntries SplitEntryMap) map[string]map[string]float32 { +func computeFlakeRates(splitEntries splitEntryMap) map[string]map[string]float32 { flakeRates := make(map[string]map[string]float32) for environment, environmentSplit := range splitEntries { for test, testSplit := range environmentSplit { diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go index 897d32311a..2f458daad9 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go @@ -27,7 +27,7 @@ func simpleDate(year int, day int) time.Time { return time.Date(year, time.January, day, 0, 0, 0, 0, time.UTC) } -func compareEntrySlices(t *testing.T, actualData, expectedData []TestEntry, extra string) { +func compareEntrySlices(t *testing.T, actualData, expectedData []testEntry, extra string) { if extra != "" { extra = fmt.Sprintf(" (%s)", extra) } @@ -50,7 +50,7 @@ func compareEntrySlices(t *testing.T, actualData, expectedData []TestEntry, extr } func TestReadData(t *testing.T) { - actualData := ReadData(strings.NewReader( + actualData := readData(strings.NewReader( `A,B,C,D,E,F hash,2000-01-01,env1,test1,Passed,1 hash,2001-01-01,env2,test2,Failed,1 @@ -58,7 +58,7 @@ func TestReadData(t *testing.T) { hash,2002-01-01,,,Passed,1 hash,2003-01-01,env3,test3,Passed,1`, )) - expectedData := []TestEntry{ + expectedData := []testEntry{ { name: "test1", environment: "env1", @@ -94,7 +94,7 @@ func TestReadData(t *testing.T) { compareEntrySlices(t, actualData, expectedData, "") } -func compareSplitData(t *testing.T, actual, expected SplitEntryMap) { +func compareSplitData(t *testing.T, actual, expected splitEntryMap) { for environment, actualTests := range actual { expectedTests, environmentOk := expected[environment] if !environmentOk { @@ -129,37 +129,37 @@ func compareSplitData(t *testing.T, actual, expected SplitEntryMap) { } func TestSplitData(t *testing.T) { - entryE1T1_1, entryE1T1_2 := TestEntry{ + entryE1T1_1, entryE1T1_2 := testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 1), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 2), status: "Passed", } - entryE1T2 := TestEntry{ + entryE1T2 := testEntry{ name: "test2", environment: "env1", date: simpleDate(2000, 1), status: "Passed", } - entryE2T1 := TestEntry{ + entryE2T1 := testEntry{ name: "test1", environment: "env2", date: simpleDate(2000, 1), status: "Passed", } - entryE2T2 := TestEntry{ + entryE2T2 := testEntry{ name: "test2", environment: "env2", date: simpleDate(2000, 1), status: "Passed", } - actual := SplitData([]TestEntry{entryE1T1_1, entryE1T1_2, entryE1T2, entryE2T1, entryE2T2}) - expected := SplitEntryMap{ + actual := splitData([]testEntry{entryE1T1_1, entryE1T1_2, entryE1T2, entryE2T1, entryE2T2}) + expected := splitEntryMap{ "env1": { "test1": {entryE1T1_1, entryE1T1_2}, "test2": {entryE1T2}, @@ -174,66 +174,66 @@ func TestSplitData(t *testing.T) { } func TestFilterRecentEntries(t *testing.T) { - entryE1T1R1, entryE1T1R2, entryE1T1R3, entryE1T1O1, entryE1T1O2 := TestEntry{ + entryE1T1R1, entryE1T1R2, entryE1T1R3, entryE1T1O1, entryE1T1O2 := testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 4), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 3), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 3), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 2), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test1", environment: "env1", date: simpleDate(2000, 1), status: "Passed", } - entryE1T2R1, entryE1T2R2, entryE1T2O1 := TestEntry{ + entryE1T2R1, entryE1T2R2, entryE1T2O1 := testEntry{ name: "test2", environment: "env1", date: simpleDate(2001, 3), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test2", environment: "env1", date: simpleDate(2001, 2), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test2", environment: "env1", date: simpleDate(2001, 1), status: "Passed", } - entryE2T2R1, entryE2T2R2, entryE2T2O1 := TestEntry{ + entryE2T2R1, entryE2T2R2, entryE2T2O1 := testEntry{ name: "test2", environment: "env2", date: simpleDate(2003, 3), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test2", environment: "env2", date: simpleDate(2003, 2), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test2", environment: "env2", date: simpleDate(2003, 1), status: "Passed", } - actualData := FilterRecentEntries(SplitEntryMap{ + actualData := filterRecentEntries(splitEntryMap{ "env1": { "test1": { entryE1T1R1, @@ -257,7 +257,7 @@ func TestFilterRecentEntries(t *testing.T) { }, }, 2) - expectedData := SplitEntryMap{ + expectedData := splitEntryMap{ "env1": { "test1": { entryE1T1R1, @@ -281,7 +281,7 @@ func TestFilterRecentEntries(t *testing.T) { } func TestComputeFlakeRates(t *testing.T) { - actualData := ComputeFlakeRates(SplitEntryMap{ + actualData := computeFlakeRates(splitEntryMap{ "env1": { "test1": { { @@ -337,7 +337,7 @@ func TestComputeFlakeRates(t *testing.T) { environment: "env2", date: simpleDate(2003, 3), status: "Passed", - }, TestEntry{ + }, testEntry{ name: "test2", environment: "env2", date: simpleDate(2003, 2), From 79f8de1bcbf8a7d260d5b4158930912230a5a660 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 11:11:34 -0700 Subject: [PATCH 045/122] Add comment for testEntry. --- hack/jenkins/test-flake-chart/compute_flake_rate.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index be741f5bb1..ccecf4f810 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -53,6 +53,13 @@ func main() { } } +// One entry of a test run. +// Example: TestEntry { +// name: "TestFunctional/parallel/LogsCmd", +// environment: "Docker_Linux", +// date: time.Now, +// status: "Passed", +// } type testEntry struct { name string environment string From ecaee4d932cf64f7d3d45c1e1a82c0892f013178 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 11:16:44 -0700 Subject: [PATCH 046/122] Add better comments for optimize_data and process_data. --- hack/jenkins/test-flake-chart/optimize_data.sh | 8 ++++++++ hack/jenkins/test-flake-chart/process_data.sh | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/optimize_data.sh b/hack/jenkins/test-flake-chart/optimize_data.sh index 2bc140fc28..e92f5e0df2 100755 --- a/hack/jenkins/test-flake-chart/optimize_data.sh +++ b/hack/jenkins/test-flake-chart/optimize_data.sh @@ -17,4 +17,12 @@ set -eu -o pipefail # Take input CSV. For each field, if it is the same as the previous row, replace it with an empty string. +# This is to compress the input CSV. Example: +# Input: +# hash,2021-06-10,Docker_Linux,TestFunctional,Passed,0.5 +# hash,2021-06-10,Docker_Linux_containerd,TestFunctional,Failed,0.6 +# +# Output: +# hash,2021-06-10,Docker_Linux,TestFunctional,Passed,0.5 +# ,,DockerLinux_containerd,,Failed,0.6 awk -F, 'BEGIN {OFS = FS} { for(i=1; i<=NF; i++) { if($i == j[i]) { $i = ""; } else { j[i] = $i; } } printf "%s\n",$0 }' diff --git a/hack/jenkins/test-flake-chart/process_data.sh b/hack/jenkins/test-flake-chart/process_data.sh index 25c6ba5ec6..dc0e66e4b3 100755 --- a/hack/jenkins/test-flake-chart/process_data.sh +++ b/hack/jenkins/test-flake-chart/process_data.sh @@ -19,7 +19,9 @@ set -eu -o pipefail # Print header. printf "Commit Hash,Test Date,Environment,Test,Status,Duration\n" -# Turn each test in each summary file to a CSV line containing its commit hash, date, environment, test, and status. +# Turn each test in each summary file to a CSV line containing its commit hash, date, environment, test, status, and duration. +# Example line: +# 247982745892,2021-06-10,Docker_Linux,TestFunctional,Passed,0.5 jq -r '((.PassedTests[]? as $name | {commit: (.Detail.Details | split(":") | .[0]), date: (.Detail.Details | split(":") | .[1]), environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Passed"}), (.FailedTests[]? as $name | {commit: (.Detail.Details | split(":") | .[0]), date: (.Detail.Details | split(":") | .[1]), environment: .Detail.Name, test: $name, duration: .Durations[$name], status: "Failed"}), (.SkippedTests[]? as $name | {commit: (.Detail.Details | split(":") | .[0]), date: (.Detail.Details | split(":") | .[1]), environment: .Detail.Name, test: $name, duration: 0, status: "Skipped"})) From 941d8f6518da169568f660e19b8ed596ec016cb9 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 10 Jun 2021 11:22:47 -0700 Subject: [PATCH 047/122] update time-to-k8s chart --- .../docs/benchmarks/timeToK8s/v1.21.0-beta.0.md | 7 +++++++ .../benchmarks/timeToK8s/v1.21.0-beta.0.png | Bin 0 -> 35990 bytes 2 files changed, 7 insertions(+) create mode 100644 site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md create mode 100644 site/static/images/benchmarks/timeToK8s/v1.21.0-beta.0.png diff --git a/site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md b/site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md new file mode 100644 index 0000000000..010c3b44f1 --- /dev/null +++ b/site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md @@ -0,0 +1,7 @@ +--- +title: "v1.21.0-beta.0 Benchmark" +linkTitle: "v1.21.0-beta.0 Benchmark" +weight: 1 +--- + +![time-to-k8s](/images/benchmarks/timeToK8s/v1.21.0-beta.0.png) diff --git a/site/static/images/benchmarks/timeToK8s/v1.21.0-beta.0.png b/site/static/images/benchmarks/timeToK8s/v1.21.0-beta.0.png new file mode 100644 index 0000000000000000000000000000000000000000..c9b9d96de097ae9cfd554fba9a96218d851c5092 GIT binary patch literal 35990 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 literal 0 HcmV?d00001 From 79e1b4e99d55a74bb4272055274ef300baaf2594 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 10 Jun 2021 11:34:06 -0700 Subject: [PATCH 048/122] Bump Makefile for 1.21.0 release --- CHANGELOG.md | 31 ++++++++++++++++++++++++++ Makefile | 2 +- hack/benchmark/time-to-k8s/time-to-k8s | 1 - 3 files changed, 32 insertions(+), 2 deletions(-) delete mode 160000 hack/benchmark/time-to-k8s/time-to-k8s diff --git a/CHANGELOG.md b/CHANGELOG.md index 5de17385e3..4e2531559c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,36 @@ # Release Notes +## Version 1.21.0 - 2021-06-10 +* add more polish translations [#11587](https://github.com/kubernetes/minikube/pull/11587) +* Modify MetricsServer to use v1 api version (instead of v1beta1). [#11584](https://github.com/kubernetes/minikube/pull/11584) + +For a more detailed changelog, including changes occuring in pre-release versions, see [CHANGELOG.md](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md). + +Thank you to our contributors for this release! + +- Andriy Dzikh +- Ilya Zuyev +- JacekDuszenko +- Medya Ghazizadeh +- Sharif Elgamal +- Steven Powell + +Thank you to our PR reviewers for this release! + +- spowelljr (11 comments) +- medyagh (2 comments) +- sharifelgamal (2 comments) +- andriyDev (1 comments) + +Thank you to our triage members for this release! + +- RA489 (12 comments) +- andriyDev (10 comments) +- sharifelgamal (10 comments) +- JacekDuszenko (7 comments) +- spowelljr (5 comments) + + ## Version 1.21.0-beta.0 - 2021-06-02 Features: * Support setting addons from environmental variables [#11469](https://github.com/kubernetes/minikube/pull/11469) diff --git a/Makefile b/Makefile index 1802a96575..ce1c5dd247 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ # Bump these on release - and please check ISO_VERSION for correctness. VERSION_MAJOR ?= 1 VERSION_MINOR ?= 21 -VERSION_BUILD ?= 0-beta.0 +VERSION_BUILD ?= 0 RAW_VERSION=$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_BUILD) VERSION ?= v$(RAW_VERSION) diff --git a/hack/benchmark/time-to-k8s/time-to-k8s b/hack/benchmark/time-to-k8s/time-to-k8s deleted file mode 160000 index 72506e9487..0000000000 --- a/hack/benchmark/time-to-k8s/time-to-k8s +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 72506e948764aeeafc01e58e6bec0ea741c61ca0 From af00210a203615d19c161dc80e8db962f6670659 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 10 Jun 2021 11:36:13 -0700 Subject: [PATCH 049/122] link to leaderboard --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e2531559c..947990df55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ Thank you to our triage members for this release! - JacekDuszenko (7 comments) - spowelljr (5 comments) +Check out our [contributions leaderboard](https://minikube.sigs.k8s.io/docs/contrib/leaderboard/v1.21.0/) for this release! ## Version 1.21.0-beta.0 - 2021-06-02 Features: From 23128e7bd48450639b06540c3c737a6401b7b169 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 10 Jun 2021 11:37:20 -0700 Subject: [PATCH 050/122] remove beta time to k8s --- .../content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md diff --git a/site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md b/site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md deleted file mode 100644 index 010c3b44f1..0000000000 --- a/site/content/en/docs/benchmarks/timeToK8s/v1.21.0-beta.0.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: "v1.21.0-beta.0 Benchmark" -linkTitle: "v1.21.0-beta.0 Benchmark" -weight: 1 ---- - -![time-to-k8s](/images/benchmarks/timeToK8s/v1.21.0-beta.0.png) From 95ac619b96c3c6b12968b6e78705f995bde91b5d Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 10 Jun 2021 11:39:28 -0700 Subject: [PATCH 051/122] remove beta time to k8s image --- .../benchmarks/timeToK8s/v1.21.0-beta.0.png | Bin 35990 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 site/static/images/benchmarks/timeToK8s/v1.21.0-beta.0.png diff --git a/site/static/images/benchmarks/timeToK8s/v1.21.0-beta.0.png b/site/static/images/benchmarks/timeToK8s/v1.21.0-beta.0.png deleted file mode 100644 index c9b9d96de097ae9cfd554fba9a96218d851c5092..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35990 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 From 9d0f1f6d8efdd397b90081648b2d1aa8248b2601 Mon Sep 17 00:00:00 2001 From: Medya Ghazizadeh Date: Thu, 10 Jun 2021 14:51:22 -0400 Subject: [PATCH 052/122] Update _index.md --- site/content/en/docs/faq/_index.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index 68445b3db8..2e818ecb75 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -7,6 +7,7 @@ description: > --- + ## How to run an older Kubernetes version with minikube ? You do not need to download an older minikube to run an older kubernetes version. @@ -82,3 +83,12 @@ Simply run the following command to be enrolled into beta notifications. ``` minikube config set WantBetaUpdateNotification true ``` + +## Can I remove/disable the emojis in minikube ? + +Yes ! if you reallly dislike the emoji :( you could set MINIKUBE_IN_STYLE envioronment variable to disable the emojis + +``` +MINIKUBE_IN_STYLE=0 minikube start + +``` From 2b3f7cedd77507aead2df8e0ce9dc2527a1096ee Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 13:02:56 -0700 Subject: [PATCH 053/122] Remove bootstrap from flake_chart.html. --- hack/jenkins/test-flake-chart/flake_chart.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/hack/jenkins/test-flake-chart/flake_chart.html b/hack/jenkins/test-flake-chart/flake_chart.html index f39859daff..beaf224c20 100644 --- a/hack/jenkins/test-flake-chart/flake_chart.html +++ b/hack/jenkins/test-flake-chart/flake_chart.html @@ -1,11 +1,9 @@ -
- \ No newline at end of file From a98db3511e4bfa091626d0c6c833db9cd6547ae8 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 13:16:16 -0700 Subject: [PATCH 054/122] Add description and example usage to all shell scripts. --- hack/jenkins/test-flake-chart/collect_data.sh | 4 ++++ hack/jenkins/test-flake-chart/optimize_data.sh | 3 +++ hack/jenkins/test-flake-chart/process_data.sh | 4 ++++ hack/jenkins/test-flake-chart/report_flakes.sh | 4 ++++ hack/jenkins/test-flake-chart/upload_tests.sh | 4 ++++ 5 files changed, 19 insertions(+) diff --git a/hack/jenkins/test-flake-chart/collect_data.sh b/hack/jenkins/test-flake-chart/collect_data.sh index a03b726825..160eecf18f 100755 --- a/hack/jenkins/test-flake-chart/collect_data.sh +++ b/hack/jenkins/test-flake-chart/collect_data.sh @@ -14,6 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Collects all test data manually, processes it, and uploads to GCS. This will +# overwrite any existing data. +# Example usage: ./collect_data.sh + DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) # 1) "cat" together all summary files. diff --git a/hack/jenkins/test-flake-chart/optimize_data.sh b/hack/jenkins/test-flake-chart/optimize_data.sh index e92f5e0df2..641dd6905b 100755 --- a/hack/jenkins/test-flake-chart/optimize_data.sh +++ b/hack/jenkins/test-flake-chart/optimize_data.sh @@ -14,6 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Takes a CSV file through stdin, compresses it and writes it to stdout. +# Example usage: < data.csv ./optimize_data.sh > data_optimized.csv + set -eu -o pipefail # Take input CSV. For each field, if it is the same as the previous row, replace it with an empty string. diff --git a/hack/jenkins/test-flake-chart/process_data.sh b/hack/jenkins/test-flake-chart/process_data.sh index dc0e66e4b3..b51e07a9e2 100755 --- a/hack/jenkins/test-flake-chart/process_data.sh +++ b/hack/jenkins/test-flake-chart/process_data.sh @@ -14,6 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Takes a series of gopogh summary jsons, and formats them into a CSV file with +# a row for each test. +# Example usage: cat gopogh_1.json gopogh_2.json gopogh_3.json | ./process_data.sh + set -eu -o pipefail # Print header. diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index b0933fa56a..d4d5dc59b8 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -14,6 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Creates a comment on the provided PR number, using the provided gopogh summary +# to list out the flake rates of all failing tests. +# Example usage: ./report_flakes.sh 11602 gopogh.json Docker_Linux + set -eu -o pipefail if [ "$#" -ne 3 ]; then diff --git a/hack/jenkins/test-flake-chart/upload_tests.sh b/hack/jenkins/test-flake-chart/upload_tests.sh index 508d76f9ad..5906f73ae1 100755 --- a/hack/jenkins/test-flake-chart/upload_tests.sh +++ b/hack/jenkins/test-flake-chart/upload_tests.sh @@ -14,6 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +# Takes a gopogh summary, extracts test data as a CSV and appends to the +# existing CSV data in the GCS bucket. +# Example usage: ./jenkins_upload_tests.sh gopogh_summary.json + set -eu -o pipefail if [ "$#" -ne 1 ]; then From 7e785c1c1e426c1a5b53b06df23d487229656f7a Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 13:19:05 -0700 Subject: [PATCH 055/122] Make collect_data.sh optimzie and upload to GCS automatically. --- hack/jenkins/test-flake-chart/collect_data.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hack/jenkins/test-flake-chart/collect_data.sh b/hack/jenkins/test-flake-chart/collect_data.sh index 160eecf18f..e62757a575 100755 --- a/hack/jenkins/test-flake-chart/collect_data.sh +++ b/hack/jenkins/test-flake-chart/collect_data.sh @@ -22,5 +22,9 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) # 1) "cat" together all summary files. # 2) Process all summary files. +# 3) Optimize the resulting data. +# 4) Store in GCS bucket. gsutil cat gs://minikube-builds/logs/master/*/*_summary.json \ | $DIR/process_data.sh +| $DIR/optimize_data.sh +| gsutil cp - gs://minikube-flake-rate/data.csv From 884216db9e28526b3cf948a1aaf2978f94b919fe Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 13:27:00 -0700 Subject: [PATCH 056/122] Make report_flakes.sh abort if there are no failed tests. --- hack/jenkins/test-flake-chart/report_flakes.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index d4d5dc59b8..85589babf8 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -60,6 +60,12 @@ TMP_FAILED_RATES="$TMP_FLAKE_RATES\_filtered" | sort -g -t, -k2,2 \ > "$TMP_FAILED_RATES" +FAILED_RATES_LINES=$(wc -l < "$TMP_FAILED_RATES") +if [[ "$FAILED_RATES_LINES" -gt 30 ]]; then + echo "No failed tests! Aborting without commenting..." 1>&2 + exit 0 +fi + # Create the comment template. TMP_COMMENT=$(mktemp) printf "These are the flake rates of all failed tests on %s.\n|Failed Tests|Flake Rate (%%)|\n|---|---|\n" "$ENVIRONMENT" > "$TMP_COMMENT" @@ -71,7 +77,7 @@ printf "These are the flake rates of all failed tests on %s.\n|Failed Tests|Flak >> "$TMP_COMMENT" # If there are too many failing tests, add an extra row explaining this, and a message after the table. -if [[ $(wc -l < "$TMP_FAILED_RATES") -gt 30 ]]; then +if [[ "$FAILED_RATES_LINES" -gt 30 ]]; then printf "|More tests...|Continued...|\n\nToo many tests failed - See test logs for more details." >> "$TMP_COMMENT" fi From dc6cb0b671fd35b09f995259ef5949525dc7872f Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 13:30:35 -0700 Subject: [PATCH 057/122] Rename collect_data.sh to collect_data_manual.sh and make header comment more clear. --- .../{collect_data.sh => collect_data_manual.sh} | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename hack/jenkins/test-flake-chart/{collect_data.sh => collect_data_manual.sh} (85%) diff --git a/hack/jenkins/test-flake-chart/collect_data.sh b/hack/jenkins/test-flake-chart/collect_data_manual.sh similarity index 85% rename from hack/jenkins/test-flake-chart/collect_data.sh rename to hack/jenkins/test-flake-chart/collect_data_manual.sh index e62757a575..bed3d74679 100755 --- a/hack/jenkins/test-flake-chart/collect_data.sh +++ b/hack/jenkins/test-flake-chart/collect_data_manual.sh @@ -15,8 +15,9 @@ # limitations under the License. # Collects all test data manually, processes it, and uploads to GCS. This will -# overwrite any existing data. -# Example usage: ./collect_data.sh +# overwrite any existing data. This should only be done for a dryrun, new data +# should be handled exclusively through upload_tests.sh. +# Example usage: ./collect_data_manual.sh DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) From 728229c719d3279f1cd88cdca06c7ab0c1171c38 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 13:36:23 -0700 Subject: [PATCH 058/122] Add more environments to the allowed environments for commenting. --- hack/jenkins/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index b153185ee3..7ae29a3329 100755 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -443,7 +443,7 @@ if [ -z "${EXTERNAL}" ]; then gsutil -qm cp "${SUMMARY_OUT}" "gs://${JOB_GCS_BUCKET}_summary.json" || true if [[ "${MINIKUBE_LOCATION}" == "master" ]]; then ./test-flake-chart/upload_tests.sh "${SUMMARY_OUT}" - elif [[ "${JOB_NAME}" == "Docker_Linux" ]]; then + elif [[ "${JOB_NAME}" == "Docker_Linux" || "${JOB_NAME}" == "Docker_Linux_containerd" || "${JOB_NAME}" == "KVM_Linux" || "${JOB_NAME}" == "KVM_Linux_containerd" ]]; then ./test-flake-chart/report_flakes.sh "${MINIKUBE_LOCATION}" "${SUMMARY_OUT}" "${JOB_NAME}" fi else From 1c1fdbff42e0efcf3738640e31900bb421880dbf Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 14:00:47 -0700 Subject: [PATCH 059/122] Make compute_flake_rate also compute average test duration. --- .../test-flake-chart/compute_flake_rate.go | 42 ++++- .../compute_flake_rate_test.go | 173 ++++++++++++++---- .../jenkins/test-flake-chart/report_flakes.sh | 2 +- 3 files changed, 173 insertions(+), 44 deletions(-) diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate.go b/hack/jenkins/test-flake-chart/compute_flake_rate.go index ccecf4f810..0025df2fbe 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate.go @@ -24,6 +24,7 @@ import ( "os" "runtime/debug" "sort" + "strconv" "strings" "time" ) @@ -45,10 +46,12 @@ func main() { splitEntries := splitData(testEntries) filteredEntries := filterRecentEntries(splitEntries, *dateRange) flakeRates := computeFlakeRates(filteredEntries) - fmt.Println("Environment,Test,Flake Rate") + averageDurations := computeAverageDurations(filteredEntries) + fmt.Println("Environment,Test,Flake Rate,Duration") for environment, environmentSplit := range flakeRates { for test, flakeRate := range environmentSplit { - fmt.Printf("%s,%s,%.2f\n", environment, test, flakeRate*100) + duration := averageDurations[environment][test] + fmt.Printf("%s,%s,%.2f,%.3f\n", environment, test, flakeRate*100, duration) } } } @@ -59,12 +62,14 @@ func main() { // environment: "Docker_Linux", // date: time.Now, // status: "Passed", +// duration: 0.1, // } type testEntry struct { name string environment string date time.Time status string + duration float32 } // A map with keys of (environment, test_name) to values of slcies of TestEntry. @@ -107,12 +112,19 @@ func readData(file io.Reader) []testEntry { date, err := time.Parse("2006-01-02", fields[1]) if err != nil { fmt.Printf("Failed to parse date: %v\n", err) + continue + } + duration, err := strconv.ParseFloat(fields[5], 32) + if err != nil { + fmt.Printf("Failed to parse duration: %v\n", err) + continue } testEntries = append(testEntries, testEntry{ name: fields[3], environment: fields[2], date: date, status: fields[4], + duration: float32(duration), }) } } @@ -215,14 +227,32 @@ func computeFlakeRates(splitEntries splitEntryMap) map[string]map[string]float32 return flakeRates } -// Sets the `value` of keys `environment` and `test` in `flakeRates`. -func setValue(flakeRates map[string]map[string]float32, environment, test string, value float32) { +// Computes the average durations over each entry in `splitEntries`. +func computeAverageDurations(splitEntries splitEntryMap) map[string]map[string]float32 { + averageDurations := make(map[string]map[string]float32) + for environment, environmentSplit := range splitEntries { + for test, testSplit := range environmentSplit { + durationSum := float32(0) + for _, entry := range testSplit { + durationSum += entry.duration + } + if len(testSplit) != 0 { + durationSum /= float32(len(testSplit)) + } + setValue(averageDurations, environment, test, durationSum) + } + } + return averageDurations +} + +// Sets the `value` of keys `environment` and `test` in `mapEntries`. +func setValue(mapEntries map[string]map[string]float32, environment, test string, value float32) { // Lookup the environment. - environmentRates, ok := flakeRates[environment] + environmentRates, ok := mapEntries[environment] if !ok { // If the environment map is missing, make a map for this environment and store it. environmentRates = make(map[string]float32) - flakeRates[environment] = environmentRates + mapEntries[environment] = environmentRates } environmentRates[test] = value } diff --git a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go index 2f458daad9..d4013c0885 100644 --- a/hack/jenkins/test-flake-chart/compute_flake_rate_test.go +++ b/hack/jenkins/test-flake-chart/compute_flake_rate_test.go @@ -53,10 +53,10 @@ func TestReadData(t *testing.T) { actualData := readData(strings.NewReader( `A,B,C,D,E,F hash,2000-01-01,env1,test1,Passed,1 - hash,2001-01-01,env2,test2,Failed,1 - hash,,,test1,,1 - hash,2002-01-01,,,Passed,1 - hash,2003-01-01,env3,test3,Passed,1`, + hash,2001-01-01,env2,test2,Failed,0.5 + hash,,,test1,,0.6 + hash,2002-01-01,,,Passed,0.9 + hash,2003-01-01,env3,test3,Passed,2`, )) expectedData := []testEntry{ { @@ -64,30 +64,35 @@ func TestReadData(t *testing.T) { environment: "env1", date: simpleDate(2000, 1), status: "Passed", + duration: 1, }, { name: "test2", environment: "env2", date: simpleDate(2001, 1), status: "Failed", + duration: 0.5, }, { name: "test1", environment: "env2", date: simpleDate(2001, 1), status: "Failed", + duration: 0.6, }, { name: "test1", environment: "env2", date: simpleDate(2002, 1), status: "Passed", + duration: 0.9, }, { name: "test3", environment: "env3", date: simpleDate(2003, 1), status: "Passed", + duration: 2, }, } @@ -280,6 +285,42 @@ func TestFilterRecentEntries(t *testing.T) { compareSplitData(t, actualData, expectedData) } +func compareValues(t *testing.T, actualValues, expectedValues map[string]map[string]float32) { + for environment, actualTests := range actualValues { + expectedTests, environmentOk := expectedValues[environment] + if !environmentOk { + t.Errorf("Unexpected environment %s in actual", environment) + continue + } + + for test, actualValue := range actualTests { + expectedValue, testOk := expectedTests[test] + if !testOk { + t.Errorf("Unexpected test %s (in environment %s) in actual", test, environment) + continue + } + + if actualValue != expectedValue { + t.Errorf("Wrong value at environment %s and test %s. Expected: %v, Actual: %v", environment, test, expectedValue, actualValue) + } + } + + for test := range expectedTests { + _, testOk := actualTests[test] + if !testOk { + t.Errorf("Missing expected test %s (in environment %s) in actual", test, environment) + } + } + } + + for environment := range expectedValues { + _, environmentOk := actualValues[environment] + if !environmentOk { + t.Errorf("Missing expected environment %s in actual", environment) + } + } +} + func TestComputeFlakeRates(t *testing.T) { actualData := computeFlakeRates(splitEntryMap{ "env1": { @@ -357,37 +398,95 @@ func TestComputeFlakeRates(t *testing.T) { }, } - for environment, actualTests := range actualData { - expectedTests, environmentOk := expectedData[environment] - if !environmentOk { - t.Errorf("Unexpected environment %s in actual", environment) - continue - } - - for test, actualFlakeRate := range actualTests { - expectedFlakeRate, testOk := expectedTests[test] - if !testOk { - t.Errorf("Unexpected test %s (in environment %s) in actual", test, environment) - continue - } - - if actualFlakeRate != expectedFlakeRate { - t.Errorf("Wrong flake rate. Expected: %v, Actual: %v", expectedFlakeRate, actualFlakeRate) - } - } - - for test := range expectedTests { - _, testOk := actualTests[test] - if !testOk { - t.Errorf("Missing expected test %s (in environment %s) in actual", test, environment) - } - } - } - - for environment := range expectedData { - _, environmentOk := actualData[environment] - if !environmentOk { - t.Errorf("Missing expected environment %s in actual", environment) - } - } + compareValues(t, actualData, expectedData) +} + +func TestComputeAverageDurations(t *testing.T) { + actualData := computeAverageDurations(splitEntryMap{ + "env1": { + "test1": { + { + name: "test1", + environment: "env1", + date: simpleDate(2000, 4), + status: "Passed", + duration: 1, + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, 3), + status: "Passed", + duration: 2, + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, 3), + status: "Passed", + duration: 3, + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, 2), + status: "Passed", + duration: 3, + }, { + name: "test1", + environment: "env1", + date: simpleDate(2000, 1), + status: "Failed", + duration: 3, + }, + }, + "test2": { + { + name: "test2", + environment: "env1", + date: simpleDate(2001, 3), + status: "Failed", + duration: 1, + }, { + name: "test2", + environment: "env1", + date: simpleDate(2001, 2), + status: "Failed", + duration: 3, + }, { + name: "test2", + environment: "env1", + date: simpleDate(2001, 1), + status: "Failed", + duration: 3, + }, + }, + }, + "env2": { + "test2": { + { + name: "test2", + environment: "env2", + date: simpleDate(2003, 3), + status: "Passed", + duration: 0.5, + }, testEntry{ + name: "test2", + environment: "env2", + date: simpleDate(2003, 2), + status: "Failed", + duration: 1.5, + }, + }, + }, + }) + + expectedData := map[string]map[string]float32{ + "env1": { + "test1": float32(12) / float32(5), + "test2": float32(7) / float32(3), + }, + "env2": { + "test2": 1, + }, + } + + compareValues(t, actualData, expectedData) } diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index 85589babf8..a04c0d359c 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -54,7 +54,7 @@ TMP_FAILED_RATES="$TMP_FLAKE_RATES\_filtered" # 3) Join the flake rates with the failing tests to only get flake rates of failing tests. # 4) Sort failed test flake rates based on the flakiness of that test - stable tests should be first on the list. # 5) Store in file $TMP_FAILED_RATES. -< "$TMP_FLAKE_RATES" sed -n -r -e "s/$ENVIRONMENT,([a-zA-Z\/_-]*),([.0-9]*)/\1,\2/p" \ +< "$TMP_FLAKE_RATES" sed -n -r -e "s/$ENVIRONMENT,([a-zA-Z\/_-]*),([.0-9]*),[.0-9]*/\1,\2/p" \ | sort -t, -k1,1 \ | join -t , -j 1 "$TMP_DATA" - \ | sort -g -t, -k2,2 \ From 806d8999887efc40c849577f2d4177e8c41e2a78 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 10 Jun 2021 14:26:04 -0700 Subject: [PATCH 060/122] Add timeout to apiserver health check. --- pkg/minikube/bootstrapper/bsutil/kverify/api_server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go b/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go index 39c29a1640..e5d275beca 100644 --- a/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go +++ b/pkg/minikube/bootstrapper/bsutil/kverify/api_server.go @@ -232,7 +232,7 @@ func apiServerHealthzNow(hostname string, port int) (state.State, error) { Proxy: nil, // Avoid using a proxy to speak to a local host TLSClientConfig: &tls.Config{RootCAs: pool}, } - client := &http.Client{Transport: tr} + client := &http.Client{Transport: tr, Timeout: 5 * time.Second} resp, err := client.Get(url) // Connection refused, usually. if err != nil { From ed65761187f15a214139ec49c400f2389d493d06 Mon Sep 17 00:00:00 2001 From: minikube-bot Date: Fri, 11 Jun 2021 08:57:50 -0700 Subject: [PATCH 061/122] Update releases.json to include v1.21.0 --- deploy/minikube/releases.json | 8 ++++++++ site/content/en/docs/_index.md | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/deploy/minikube/releases.json b/deploy/minikube/releases.json index 5172ffb61c..af0d047a75 100644 --- a/deploy/minikube/releases.json +++ b/deploy/minikube/releases.json @@ -1,4 +1,12 @@ [ + { + "name": "v1.21.0", + "checksums": { + "darwin": "e2043883ca993b2a65396d379823dab6404dd842d0cc2a81348d247b01785070", + "linux": "5d423a00a24fdfbb95627a3fadbf58540fc4463be2338619257c529f93cf061b", + "windows": "74c961877798531ab8e53e2590bfae3cee7690d0c2e0614fdb44339e065124b5" + } + }, { "name": "v1.20.0", "checksums": { diff --git a/site/content/en/docs/_index.md b/site/content/en/docs/_index.md index a3153bc9eb..69776d0fe3 100644 --- a/site/content/en/docs/_index.md +++ b/site/content/en/docs/_index.md @@ -11,7 +11,7 @@ minikube quickly sets up a local Kubernetes cluster on macOS, Linux, and Windows ![Screenshot](/images/screenshot.png) -🎉 Latest Release: v1.20.0 - May 06, 2021 ([changelog](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md)) +🎉 Latest Release: v1.21.0 - Jun 11, 2021 ([changelog](https://github.com/kubernetes/minikube/blob/master/CHANGELOG.md)) ## Highlights From 2807cb0b8e339e33678335d7e090b6d43cb6a35b Mon Sep 17 00:00:00 2001 From: Medya Ghazizadeh Date: Fri, 11 Jun 2021 12:31:08 -0400 Subject: [PATCH 062/122] Update _index.md --- site/content/en/docs/faq/_index.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index 2e818ecb75..d7346c8699 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -7,7 +7,6 @@ description: > --- - ## How to run an older Kubernetes version with minikube ? You do not need to download an older minikube to run an older kubernetes version. @@ -84,9 +83,7 @@ Simply run the following command to be enrolled into beta notifications. minikube config set WantBetaUpdateNotification true ``` -## Can I remove/disable the emojis in minikube ? - -Yes ! if you reallly dislike the emoji :( you could set MINIKUBE_IN_STYLE envioronment variable to disable the emojis +Yes! If you prefer not having emoji in your minikube output 😔 , just set the MINIKUBE_IN_STYLE environment variable to 0 or false ``` MINIKUBE_IN_STYLE=0 minikube start From efb9514a333c8bd130015ab19a089ace88a39b2d Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Fri, 11 Jun 2021 11:20:20 -0700 Subject: [PATCH 063/122] add contribution leaderboard for v1.21.0 --- .../en/docs/contrib/leaderboard/v1.21.0.html | 496 ++++++++++++++++++ 1 file changed, 496 insertions(+) create mode 100644 site/content/en/docs/contrib/leaderboard/v1.21.0.html diff --git a/site/content/en/docs/contrib/leaderboard/v1.21.0.html b/site/content/en/docs/contrib/leaderboard/v1.21.0.html new file mode 100644 index 0000000000..e497ff1b04 --- /dev/null +++ b/site/content/en/docs/contrib/leaderboard/v1.21.0.html @@ -0,0 +1,496 @@ +--- +title: "v1.21.0 - 2021-06-11" +linkTitle: "v1.21.0 - 2021-06-11" +weight: -97 +--- + + + kubernetes/minikube - Leaderboard + + + + + + + +

kubernetes/minikube

+
2021-05-06 — 2021-06-11
+ + + +

Reviewers

+ + +
+

Most Influential

+

# of Merged PRs reviewed

+
+ +
+ +
+

Most Helpful

+

# of words written in merged PRs

+
+ +
+ +
+

Most Demanding

+

# of Review Comments in merged PRs

+
+ +
+ + +

Pull Requests

+ + +
+

Most Active

+

# of Pull Requests Merged

+
+ +
+ +
+

Big Movers

+

Lines of code (delta)

+
+ +
+ +
+

Most difficult to review

+

Average PR size (added+changed)

+
+ +
+ + +

Issues

+ + +
+

Most Active

+

# of comments

+
+ +
+ +
+

Most Helpful

+

# of words (excludes authored)

+
+ +
+ +
+

Top Closers

+

# of issues closed (excludes authored)

+
+ +
+ + + + From 362a8651fd3c4cb85c30c5f9b5bf528424327491 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Fri, 11 Jun 2021 12:41:19 -0700 Subject: [PATCH 064/122] site: Cleanup FAQ formatting and grammar. --- site/content/en/docs/faq/_index.md | 43 ++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index d7346c8699..4cad059b9f 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -7,10 +7,10 @@ description: > --- -## How to run an older Kubernetes version with minikube ? +## Can I run an older Kubernetes version with minikube? Do I have to downgrade my minikube version? You do not need to download an older minikube to run an older kubernetes version. -You can create a Kubenretes cluster with any version you desire using `--kubernetes-version` flag. +You can create a Kubernetes cluster with any version you desire using `--kubernetes-version` flag. Example: @@ -19,26 +19,27 @@ minikube start --kubernetes-version=v1.15.0 ``` -## Docker Driver: How to set the cgroup manager minikube uses? +## Docker Driver: How can I set minikube's cgroup manager? -By default minikube uses the `cgroupfs` cgroup manager for the Kubernetes clusters, if you are on a system with a systemd cgroup manager, this could cause conflicts. -To use `systemd` cgroup manager, run: +By default minikube uses the `cgroupfs` cgroup manager for Kubernetes clusters. If you are on a system with a systemd cgroup manager, this could cause conflicts. +To use the `systemd` cgroup manager, run: ```bash minikube start --force-systemd=true ``` -## How to run minikube with Docker driver if existing cluster is VM? +## How can I run minikube with the Docker driver if I have an existing cluster with a VM driver? -If you have an existing cluster with a VM driver (virtualbox, hyperkit, KVM,...). +First please ensure your Docker service is running. Then you need to either: + +(a) Delete the existing cluster and create a new one -First please ensure your Docker service is running and then you need to either delete the existing cluster and create one ```bash minikube delete minikube start --driver=docker ``` -Alternatively, if you want to keep your existing cluster you can create a second cluster with a different profile name. (example p1) +Alternatively, (b) Create a second cluster with a different profile name: ```bash minikube start -p p1 --driver=docker @@ -46,27 +47,27 @@ minikube start -p p1 --driver=docker ## Does minikube support IPv6? -minikube currently doesn't support IPv6. However, it is on the [roadmap]({{< ref "/docs/contrib/roadmap.en.md" >}}). +minikube currently doesn't support IPv6. However, it is on the [roadmap]({{< ref "/docs/contrib/roadmap.en.md" >}}). You can also refer to the [open issue.](https://github.com/kubernetes/minikube/issues/8535) ## How can I prevent password prompts on Linux? The easiest approach is to use the `docker` driver, as the backend service always runs as `root`. -`none` users may want to try `CHANGE_MINIKUBE_NONE_USER=true`, where kubectl and such will still work: [see environment variables]({{< ref "/docs/handbook/config.md#environment-variables" >}}) +`none` users may want to try `CHANGE_MINIKUBE_NONE_USER=true`, where kubectl and such will work without `sudo`. See [environment variables]({{< ref "/docs/handbook/config.md#environment-variables" >}}) for more details. -Alternatively, configure `sudo` to never prompt for the commands issued by minikube. +Alternatively, you can configure `sudo` to never prompt for commands issued by minikube. -## How to ignore system verification? +## How can I ignore system verification? -minikube's bootstrapper, [Kubeadm](https://github.com/kubernetes/kubeadm) verifies a list of features on the host system before installing Kubernetes. in case you get this error, and you still want to try minikube anyways despite your system's limitation you can skip the verification by starting minikube with this extra option: +[kubeadm](https://github.com/kubernetes/kubeadm), minikube's bootstrapper, verifies a list of features on the host system before installing Kubernetes. In the case you get an error and still want to try minikube despite your system's limitation, you can skip verification by starting minikube with this extra option: ```shell minikube start --extra-config kubeadm.ignore-preflight-errors=SystemVerification ``` -## what is the resource allocation for Knative Setup using minikube? +## What is the minimum resource allocation necessary for a Knative setup using minikube? -Please allocate sufficient resources for Knative setup using minikube, especially when you run a minikube cluster on your local machine. We recommend allocating at least 6 CPUs and 8G memory. +Please allocate sufficient resources for Knative setup using minikube, especially when you running minikube cluster on your local machine. We recommend allocating at least 6 CPUs and 8G memory: ```shell minikube start --cpus 6 --memory 8000 @@ -74,16 +75,18 @@ minikube start --cpus 6 --memory 8000 ## Do I need to install kubectl locally? -No, minikube comes with built-in kubectl [see minikube's kubectl documentation]({{< ref "docs/handbook/kubectl.md" >}}). +No, minikube comes with a built-in kubectl installation. See [minikube's kubectl documentation.]({{< ref "docs/handbook/kubectl.md" >}}). -## How to opt-in to beta notifications? +## How can I opt-in to beta release notifications? -Simply run the following command to be enrolled into beta notifications. +Simply run the following command to be enrolled into beta notifications: ``` minikube config set WantBetaUpdateNotification true ``` -Yes! If you prefer not having emoji in your minikube output 😔 , just set the MINIKUBE_IN_STYLE environment variable to 0 or false +## Can I get rid of the emoji in minikube's outpuut? + +Yes! If you prefer not having emoji in your minikube output 😔 , just set the `MINIKUBE_IN_STYLE` environment variable to `0` or `false`: ``` MINIKUBE_IN_STYLE=0 minikube start From 79cf1adc400635bfb71cfe0ecfe76b0b87912a5e Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Fri, 11 Jun 2021 12:43:11 -0700 Subject: [PATCH 065/122] change subtitle --- site/content/en/docs/faq/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index 4cad059b9f..3891ad9838 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -3,7 +3,7 @@ title: "FAQ" linkTitle: "FAQ" weight: 3 description: > - Questions that come up regularly + Frequently Asked Questions --- From 60141cf5221887598d63395d2e4f4e96242a263d Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Fri, 11 Jun 2021 13:02:11 -0700 Subject: [PATCH 066/122] fixes --- site/content/en/docs/faq/_index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index 3891ad9838..9b5f9a6d95 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -47,7 +47,7 @@ minikube start -p p1 --driver=docker ## Does minikube support IPv6? -minikube currently doesn't support IPv6. However, it is on the [roadmap]({{< ref "/docs/contrib/roadmap.en.md" >}}). You can also refer to the [open issue.](https://github.com/kubernetes/minikube/issues/8535) +minikube currently doesn't support IPv6. However, it is on the [roadmap]({{< ref "/docs/contrib/roadmap.en.md" >}}). You can also refer to the [open issue](https://github.com/kubernetes/minikube/issues/8535). ## How can I prevent password prompts on Linux? @@ -67,7 +67,7 @@ minikube start --extra-config kubeadm.ignore-preflight-errors=SystemVerification ## What is the minimum resource allocation necessary for a Knative setup using minikube? -Please allocate sufficient resources for Knative setup using minikube, especially when you running minikube cluster on your local machine. We recommend allocating at least 6 CPUs and 8G memory: +Please allocate sufficient resources for Knative setup using minikube, especially when running minikube cluster on your local machine. We recommend allocating at least 6 CPUs and 8G memory: ```shell minikube start --cpus 6 --memory 8000 @@ -75,7 +75,7 @@ minikube start --cpus 6 --memory 8000 ## Do I need to install kubectl locally? -No, minikube comes with a built-in kubectl installation. See [minikube's kubectl documentation.]({{< ref "docs/handbook/kubectl.md" >}}). +No, minikube comes with a built-in kubectl installation. See [minikube's kubectl documentation]({{< ref "docs/handbook/kubectl.md" >}}). ## How can I opt-in to beta release notifications? From 334f3e8e8dfb987c6b6f88b07cf0bc793967041f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Jun 2021 06:52:05 +0000 Subject: [PATCH 067/122] Bump google.golang.org/api from 0.47.0 to 0.48.0 Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.47.0 to 0.48.0. - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/master/CHANGES.md) - [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.47.0...v0.48.0) --- updated-dependencies: - dependency-name: google.golang.org/api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 14e9ebfacc..72a311e546 100644 --- a/go.mod +++ b/go.mod @@ -84,11 +84,11 @@ require ( golang.org/x/mod v0.4.2 golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 + golang.org/x/sys v0.0.0-20210603125802-9665404d3644 golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 golang.org/x/text v0.3.6 gonum.org/v1/plot v0.9.0 - google.golang.org/api v0.47.0 + google.golang.org/api v0.48.0 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect gopkg.in/yaml.v2 v2.4.0 gotest.tools/v3 v3.0.3 // indirect diff --git a/go.sum b/go.sum index 02edccd982..de7f56d87e 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,9 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0 h1:bAMqZidYkmIsUqe6PtkEPT7Q+vfizScn+jfNA6jwK9c= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -467,6 +468,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= @@ -498,8 +500,9 @@ github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0 h1:wCKgOCHuUEVfsaQLpPSJb7VdYCdTVZQAuOdYm1yc/60= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -511,6 +514,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/slowjam v0.0.0-20200530021616-df27e642fe7b h1:x3aElhKtGmXLo6RI2FJSBaPBT0acmn2LFfKVP1CqH8o= github.com/google/slowjam v0.0.0-20200530021616-df27e642fe7b/go.mod h1:i4b4iDjZbKPkbD7z9Ycy4gtcALPoh8E9O3+wvtw7IB0= @@ -1313,8 +1317,9 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210412220455-f1c623a9e750/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0= golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1400,8 +1405,9 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1442,8 +1448,9 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= -google.golang.org/api v0.47.0 h1:sQLWZQvP6jPGIP4JGPkJu4zHswrv81iobiyszr3b/0I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0 h1:RDAPWfNFY06dffEXfn7hZF5Fr1ZbnChzfQZAPyBd1+I= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1501,8 +1508,10 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210420162539-3c870d7478d2/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384 h1:z+j74wi4yV+P7EtK9gPLGukOk7mFOy9wMQaC0wNb7eY= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 h1:pc16UedxnxXXtGxHCSUhafAoVHQZ0yXl8ZelMH4EETc= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -1527,8 +1536,10 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1 h1:ARnQJNWxGyYJpdf/JXscNlQr/uv607ZPU9Z7ogHi+iI= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 4eb3c6332d7a242261a284ca04ee5afbaae3190e Mon Sep 17 00:00:00 2001 From: Dongjoon Hyun Date: Mon, 14 Jun 2021 15:11:49 -0700 Subject: [PATCH 068/122] Fix a download link to use arm64 instead of amd64 --- cmd/minikube/cmd/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/root.go b/cmd/minikube/cmd/root.go index cfcd7f0276..5b81138d82 100644 --- a/cmd/minikube/cmd/root.go +++ b/cmd/minikube/cmd/root.go @@ -97,7 +97,7 @@ func Execute() { if runtime.GOOS == "darwin" && detect.IsAmd64M1Emulation() { exit.Message(reason.WrongBinaryM1, "You are trying to run amd64 binary on M1 system. Please use darwin/arm64 binary instead (Download at {{.url}}.)", - out.V{"url": notify.DownloadURL(version.GetVersion(), "darwin", "amd64")}) + out.V{"url": notify.DownloadURL(version.GetVersion(), "darwin", "arm64")}) } _, callingCmd := filepath.Split(os.Args[0]) From e7e52584c55bc301d3182e1b7f315885f8dc1e4a Mon Sep 17 00:00:00 2001 From: zhangdb-git Date: Tue, 15 Jun 2021 05:36:58 -0400 Subject: [PATCH 069/122] Remove duplicated translations --- site/content/en/docs/handbook/controls.md | 2 +- translations/ko.json | 5 ++--- translations/pl.json | 5 ++--- translations/zh-CN.json | 5 ++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/site/content/en/docs/handbook/controls.md b/site/content/en/docs/handbook/controls.md index 0f1218ca63..0301da5e18 100644 --- a/site/content/en/docs/handbook/controls.md +++ b/site/content/en/docs/handbook/controls.md @@ -16,7 +16,7 @@ Start a cluster by running: minikube start ``` -Access the Kubernetes Dashboard running within the minikube cluster: +Access the Kubernetes dashboard running within the minikube cluster: ```shell minikube dashboard diff --git a/translations/ko.json b/translations/ko.json index 67b0f2a3fa..22a0818c5e 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -33,8 +33,7 @@ "A set of apiserver IP Addresses which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine": "", "A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine": "", "A set of key=value pairs that describe feature gates for alpha/experimental features.": "", - "Access the Kubernetes dashboard running within the minikube cluster": "", - "Access the kubernetes dashboard running within the minikube cluster": "minikube 클러스터 내의 쿠버네티스 대시보드에 접근합니다", + "Access the Kubernetes dashboard running within the minikube cluster": "minikube 클러스터 내의 쿠버네티스 대시보드에 접근합니다", "Access to ports below 1024 may fail on Windows with OpenSSH clients older than v8.1. For more information, see: https://minikube.sigs.k8s.io/docs/handbook/accessing/#access-to-ports-1024-on-windows-requires-root-permission": "", "Add SSH identity key to SSH authentication agent": "SSH 인증 에이전트에 SSH ID 키 추가합니다", "Add an image to local cache.": "로컬 캐시에 이미지를 추가합니다", @@ -962,4 +961,4 @@ "{{.profile}} profile is not valid: {{.err}}": "{{.profile}} 프로파일이 올바르지 않습니다: {{.err}}", "{{.type}} is not yet a supported filesystem. We will try anyways!": "", "{{.url}} is not accessible: {{.error}}": "{{.url}} 이 접근 불가능합니다: {{.error}}" -} \ No newline at end of file +} diff --git a/translations/pl.json b/translations/pl.json index 76bd872c81..8991b99ee0 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -32,8 +32,7 @@ "A set of apiserver IP Addresses which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine": "", "A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine": "", "A set of key=value pairs that describe feature gates for alpha/experimental features.": "", - "Access the Kubernetes dashboard running within the minikube cluster": "", - "Access the kubernetes dashboard running within the minikube cluster": "Dostęp do dashboardu uruchomionego w klastrze kubernetesa w minikube", + "Access the Kubernetes dashboard running within the minikube cluster": "Dostęp do dashboardu uruchomionego w klastrze kubernetesa w minikube", "Access to ports below 1024 may fail on Windows with OpenSSH clients older than v8.1. For more information, see: https://minikube.sigs.k8s.io/docs/handbook/accessing/#access-to-ports-1024-on-windows-requires-root-permission": "", "Add SSH identity key to SSH authentication agent": "", "Add an image to local cache.": "Dodaj obraz do lokalnego cache", @@ -962,4 +961,4 @@ "{{.profile}} profile is not valid: {{.err}}": "{{.profile}} profil nie jest poprawny: {{.err}}", "{{.type}} is not yet a supported filesystem. We will try anyways!": "{{.type}} nie jest wspierany przez system plików. I tak spróbujemy!", "{{.url}} is not accessible: {{.error}}": "{{.url}} nie jest osiągalny: {{.error}}" -} \ No newline at end of file +} diff --git a/translations/zh-CN.json b/translations/zh-CN.json index e586403774..62beb10000 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -39,8 +39,7 @@ "A set of apiserver names which are used in the generated certificate for kubernetes. This can be used if you want to make the apiserver available from outside the machine": "一组在为 kubernetes 生成的证书中使用的 apiserver 名称。如果您希望将此 apiserver 设置为可从机器外部访问,则可以使用这组 apiserver 名称", "A set of key=value pairs that describe configuration that may be passed to different components.\nThe key should be '.' separated, and the first part before the dot is the component to apply the configuration to.\nValid components are: kubelet, kubeadm, apiserver, controller-manager, etcd, proxy, scheduler\nValid kubeadm parameters:": "一组用于描述可传递给不同组件的配置的键值对。\n其中键应以英文句点“.”分隔,英文句点前面的第一个部分是应用该配置的组件。\n有效组件包括:kubelet、kubeadm、apiserver、controller-manager、etcd、proxy、scheduler\n有效 kubeadm 参数包括:", "A set of key=value pairs that describe feature gates for alpha/experimental features.": "一组用于描述 alpha 版功能/实验性功能的功能限制的键值对。", - "Access the Kubernetes dashboard running within the minikube cluster": "", - "Access the kubernetes dashboard running within the minikube cluster": "访问在 minikube 集群中运行的 kubernetes dashboard", + "Access the Kubernetes dashboard running within the minikube cluster": "访问在 minikube 集群中运行的 kubernetes dashboard", "Access to ports below 1024 may fail on Windows with OpenSSH clients older than v8.1. For more information, see: https://minikube.sigs.k8s.io/docs/handbook/accessing/#access-to-ports-1024-on-windows-requires-root-permission": "", "Add SSH identity key to SSH authentication agent": "", "Add an image to local cache.": "将 image 添加到本地缓存。", @@ -1072,4 +1071,4 @@ "{{.profile}} profile is not valid: {{.err}}": "", "{{.type}} is not yet a supported filesystem. We will try anyways!": "", "{{.url}} is not accessible: {{.error}}": "" -} \ No newline at end of file +} From 231fbee7b5a1a0c7ec2d095acc942b5719eb05c8 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 15 Jun 2021 09:55:32 -0700 Subject: [PATCH 070/122] Fix collect_data_manual not being formatted correctly. --- hack/jenkins/test-flake-chart/collect_data_manual.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hack/jenkins/test-flake-chart/collect_data_manual.sh b/hack/jenkins/test-flake-chart/collect_data_manual.sh index bed3d74679..287a1a63d5 100755 --- a/hack/jenkins/test-flake-chart/collect_data_manual.sh +++ b/hack/jenkins/test-flake-chart/collect_data_manual.sh @@ -26,6 +26,6 @@ DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) # 3) Optimize the resulting data. # 4) Store in GCS bucket. gsutil cat gs://minikube-builds/logs/master/*/*_summary.json \ -| $DIR/process_data.sh -| $DIR/optimize_data.sh +| $DIR/process_data.sh \ +| $DIR/optimize_data.sh \ | gsutil cp - gs://minikube-flake-rate/data.csv From 599e7c49e9e06e354a77960d827f5065e810fa03 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Tue, 15 Jun 2021 10:17:46 -0700 Subject: [PATCH 071/122] create automated time-to-k8s benchmarks on release --- .github/workflows/time-to-k8s.yml | 20 +++++++++ .gitmodules | 4 +- .../{time-to-k8s => time-to-k8s-repo} | 0 hack/benchmark/time-to-k8s/time-to-k8s.sh | 43 +++++++++++++++---- 4 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/time-to-k8s.yml rename hack/benchmark/time-to-k8s/{time-to-k8s => time-to-k8s-repo} (100%) diff --git a/.github/workflows/time-to-k8s.yml b/.github/workflows/time-to-k8s.yml new file mode 100644 index 0000000000..d3f82b23d4 --- /dev/null +++ b/.github/workflows/time-to-k8s.yml @@ -0,0 +1,20 @@ +name: "time-to-k8s benchmark" +on: + pull_request: + types: [opened] + # release: + # types: [released] +jobs: + benchmark: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: Checkout submodules + run: git submodule update --init + - uses: actions/setup-go@v2 + with: + go-version: 1.16.5 + stable: true + - name: Benchmark + run: | + ./hack/benchmark/time-to-k8s/time-to-k8s.sh ${{ secrets.MINIKUBE_BOT_PAT }} diff --git a/.gitmodules b/.gitmodules index 0e99693233..d398a94cf9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "site/themes/docsy"] path = site/themes/docsy url = https://github.com/google/docsy.git -[submodule "hack/benchmark/time-to-k8s/time-to-k8s"] - path = hack/benchmark/time-to-k8s/time-to-k8s +[submodule "hack/benchmark/time-to-k8s/time-to-k8s-repo"] + path = hack/benchmark/time-to-k8s/time-to-k8s-repo url = https://github.com/tstromberg/time-to-k8s.git diff --git a/hack/benchmark/time-to-k8s/time-to-k8s b/hack/benchmark/time-to-k8s/time-to-k8s-repo similarity index 100% rename from hack/benchmark/time-to-k8s/time-to-k8s rename to hack/benchmark/time-to-k8s/time-to-k8s-repo diff --git a/hack/benchmark/time-to-k8s/time-to-k8s.sh b/hack/benchmark/time-to-k8s/time-to-k8s.sh index d999a6afc8..f0ea5aaf85 100755 --- a/hack/benchmark/time-to-k8s/time-to-k8s.sh +++ b/hack/benchmark/time-to-k8s/time-to-k8s.sh @@ -17,7 +17,7 @@ set -e install_kind() { - curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.0/kind-linux-amd64 + curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local } @@ -31,31 +31,58 @@ install_minikube() { sudo install ./out/minikube /usr/local/bin/minikube } +install_gh() { + export access_token="$1" + + # Make sure gh is installed and configured + ./hack/jenkins/installers/check_install_gh.sh +} + +config_git() { + git config user.name "minikube-bot" + git config user.email "minikube-bot@google.com" +} + +create_branch() { + git checkout -b addTimeToK8s"$1" +} + run_benchmark() { - ( cd ./hack/benchmark/time-to-k8s/time-to-k8s/ && + pwd + ( cd ./hack/benchmark/time-to-k8s/time-to-k8s-repo/ && git submodule update --init && - go run . --config local-kubernetes.yaml --iterations 5 --output output.csv ) + go run . --config local-kubernetes.yaml --iterations 1 --output output.csv ) } generate_chart() { - go run ./hack/benchmark/time-to-k8s/chart.go --csv ./hack/benchmark/time-to-k8s/time-to-k8s/output.csv --output ./site/static/images/benchmarks/timeToK8s/"$1".png + go run ./hack/benchmark/time-to-k8s/chart.go --csv ./hack/benchmark/time-to-k8s/time-to-k8s-repo/output.csv --output ./site/static/images/benchmarks/timeToK8s/"$1".png } create_page() { printf -- "---\ntitle: \"%s Benchmark\"\nlinkTitle: \"%s Benchmark\"\nweight: 1\n---\n\n![time-to-k8s](/images/benchmarks/timeToK8s/%s.png)\n" "$1" "$1" "$1" > ./site/content/en/docs/benchmarks/timeToK8s/"$1".md } -commit_chart() { +commit_changes() { git add ./site/static/images/benchmarks/timeToK8s/"$1".png ./site/content/en/docs/benchmarks/timeToK8s/"$1".md - git commit -m 'update time-to-k8s chart' + git commit -m "add time-to-k8s benchmark for $1" +} + +create_pr() { + git remote add minikube-bot https://minikube-bot:"$2"@github.com/minikube-bot/minikube.git + git push -u minikube-bot addTimeToK8s"$1" + gh pr create --repo kubernetes/minikube --base master --title "Add time-to-k8s benchmark for $1" --body "Updating time-to-k8s benchmark as part of the release process" } install_kind install_k3d install_minikube -VERSION=$(minikube version --short) +install_gh "$1" +config_git +VERSION=$(minikube version --short) +create_branch "$VERSION" run_benchmark generate_chart "$VERSION" create_page "$VERSION" -commit_chart "$VERSION" +commit_changes "$VERSION" +create_pr "$VERSION" "$1" From 262e6c2072a4b2e3b2c158c03210029729a87969 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Tue, 15 Jun 2021 10:23:03 -0700 Subject: [PATCH 072/122] uncomment run on release --- .github/workflows/time-to-k8s.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/time-to-k8s.yml b/.github/workflows/time-to-k8s.yml index d3f82b23d4..991f8b73a0 100644 --- a/.github/workflows/time-to-k8s.yml +++ b/.github/workflows/time-to-k8s.yml @@ -1,9 +1,7 @@ name: "time-to-k8s benchmark" on: - pull_request: - types: [opened] - # release: - # types: [released] + release: + types: [released] jobs: benchmark: runs-on: ubuntu-18.04 From 4480bda5a040fb33b0e2c1d0c20d7f40052df8c0 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Tue, 15 Jun 2021 10:27:02 -0700 Subject: [PATCH 073/122] fixed yaml formatting --- .github/workflows/time-to-k8s.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/time-to-k8s.yml b/.github/workflows/time-to-k8s.yml index 991f8b73a0..0b4103ac71 100644 --- a/.github/workflows/time-to-k8s.yml +++ b/.github/workflows/time-to-k8s.yml @@ -1,7 +1,7 @@ name: "time-to-k8s benchmark" on: - release: - types: [released] + release: + types: [released] jobs: benchmark: runs-on: ubuntu-18.04 From 25c5bec652876db534cd186a5c4c7b7f70f8b50c Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Tue, 15 Jun 2021 10:30:08 -0700 Subject: [PATCH 074/122] change back iterations to 5 --- hack/benchmark/time-to-k8s/time-to-k8s.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/benchmark/time-to-k8s/time-to-k8s.sh b/hack/benchmark/time-to-k8s/time-to-k8s.sh index f0ea5aaf85..a16beea807 100755 --- a/hack/benchmark/time-to-k8s/time-to-k8s.sh +++ b/hack/benchmark/time-to-k8s/time-to-k8s.sh @@ -51,7 +51,7 @@ run_benchmark() { pwd ( cd ./hack/benchmark/time-to-k8s/time-to-k8s-repo/ && git submodule update --init && - go run . --config local-kubernetes.yaml --iterations 1 --output output.csv ) + go run . --config local-kubernetes.yaml --iterations 5 --output output.csv ) } generate_chart() { From 4e9cab72d13a3d2d3ca432bb2a78f1fc57eb1c65 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Tue, 15 Jun 2021 10:36:49 -0700 Subject: [PATCH 075/122] run `make generate-docs` --- translations/de.json | 2 +- translations/es.json | 2 +- translations/fr.json | 2 +- translations/ja.json | 2 +- translations/ko.json | 4 ++-- translations/pl.json | 4 ++-- translations/strings.txt | 2 +- translations/zh-CN.json | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/translations/de.json b/translations/de.json index bbd00044da..be50ba730e 100644 --- a/translations/de.json +++ b/translations/de.json @@ -625,7 +625,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "Der Name des virtuellen Hyperv-Switch. Standardmäßig zuerst gefunden. (nur Hyperv-Treiber)", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)": "Die von der minikube-VM verwendete Kubernetes-Version (Beispiel: v1.2.3)", diff --git a/translations/es.json b/translations/es.json index 67f349fb27..2595b1fe5a 100644 --- a/translations/es.json +++ b/translations/es.json @@ -630,7 +630,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "El nombre del conmutador virtual de hyperv. El valor predeterminado será el primer nombre que se encuentre (solo con el controlador de hyperv).", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)": "La versión de Kubernetes que utilizará la VM de minikube (p. ej.: versión 1.2.3)", diff --git a/translations/fr.json b/translations/fr.json index 7948802753..096e9d24c9 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -628,7 +628,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "Nom du commutateur virtuel hyperv. La valeur par défaut affiche le premier commutateur trouvé (pilote hyperv uniquement).", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)": "Version de Kubernetes qu'utilisera la VM minikube (exemple : v1.2.3).", diff --git a/translations/ja.json b/translations/ja.json index 359f941d7b..d86712a73c 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -624,7 +624,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "hyperv 仮想スイッチ名。最初に見つかったものにデフォルト設定されます(hyperv ドライバのみ)", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)": "minikube VM で使用される Kubernetes バージョン(例: v1.2.3)", diff --git a/translations/ko.json b/translations/ko.json index 22a0818c5e..6d9761ed21 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -638,7 +638,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The machine-driver specified is failing to start. Try running 'docker-machine-driver-\u003ctype\u003e version'": "", @@ -961,4 +961,4 @@ "{{.profile}} profile is not valid: {{.err}}": "{{.profile}} 프로파일이 올바르지 않습니다: {{.err}}", "{{.type}} is not yet a supported filesystem. We will try anyways!": "", "{{.url}} is not accessible: {{.error}}": "{{.url}} 이 접근 불가능합니다: {{.error}}" -} +} \ No newline at end of file diff --git a/translations/pl.json b/translations/pl.json index 8991b99ee0..1d0462ae21 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -642,7 +642,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)": "Wersja kubernetesa, która zostanie użyta przez wirtualną maszynę minikube (np. v1.2.3)", @@ -961,4 +961,4 @@ "{{.profile}} profile is not valid: {{.err}}": "{{.profile}} profil nie jest poprawny: {{.err}}", "{{.type}} is not yet a supported filesystem. We will try anyways!": "{{.type}} nie jest wspierany przez system plików. I tak spróbujemy!", "{{.url}} is not accessible: {{.error}}": "{{.url}} nie jest osiągalny: {{.error}}" -} +} \ No newline at end of file diff --git a/translations/strings.txt b/translations/strings.txt index b3a8957bf6..4757ac5dce 100644 --- a/translations/strings.txt +++ b/translations/strings.txt @@ -585,7 +585,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The machine-driver specified is failing to start. Try running 'docker-machine-driver-\u003ctype\u003e version'": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index 62beb10000..2fcb2b1d02 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -731,7 +731,7 @@ "The heapster addon is depreciated. please try to disable metrics-server instead": "", "The hyperv virtual switch name. Defaults to first found. (hyperv driver only)": "hyperv 虚拟交换机名称。默认为找到的第一个 hyperv 虚拟交换机。(仅限 hyperv 驱动程序)", "The hypervisor does not appear to be configured properly. Run 'minikube start --alsologtostderr -v=1' and inspect the error code": "管理程序似乎配置的不正确。执行 'minikube start --alsologtostderr -v=1' 并且检查错误代码", - "The image you are trying to add {{.imageName}} doesn't exist!": "", + "The image '{{.imageName}}' was not found; unable to add it to cache.": "", "The initial time interval for each check that wait performs in seconds": "", "The kubeadm binary within the Docker container is not executable": "", "The kubernetes version that the minikube VM will use (ex: v1.2.3)": "minikube 虚拟机将使用的 kubernetes 版本(例如 v1.2.3)", @@ -1071,4 +1071,4 @@ "{{.profile}} profile is not valid: {{.err}}": "", "{{.type}} is not yet a supported filesystem. We will try anyways!": "", "{{.url}} is not accessible: {{.error}}": "" -} +} \ No newline at end of file From 7537c9da2b0ebec5bea78a33e621276af12ddc91 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Tue, 15 Jun 2021 14:22:04 -0700 Subject: [PATCH 076/122] add local-kicbase make target --- Makefile | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ce1c5dd247..445f7a56e9 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ KVM_GO_VERSION ?= $(GO_VERSION:.0=) INSTALL_SIZE ?= $(shell du out/minikube-windows-amd64.exe | cut -f1) BUILDROOT_BRANCH ?= 2020.02.12 -REGISTRY?=gcr.io/k8s-minikube +REGISTRY ?=gcr.io/k8s-minikube # Get git commit id COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true) @@ -705,6 +705,21 @@ KICBASE_IMAGE_GCR ?= $(REGISTRY)/kicbase:$(KIC_VERSION) KICBASE_IMAGE_HUB ?= kicbase/stable:$(KIC_VERSION) KICBASE_IMAGE_REGISTRIES ?= $(KICBASE_IMAGE_GCR) $(KICBASE_IMAGE_HUB) +.PHONY: local-kicbase +local-kicbase: deploy/kicbase/auto-pause ## Builds the kicbase image and tags it local/kicbase:latest and local/kicbase:$(KIC_VERSION)-$(COMMIT_SHORT) + docker build -f ./deploy/kicbase/Dockerfile -t local/kicbase:$(KIC_VERSION) --build-arg COMMIT_SHA=${VERSION}-$(COMMIT) --cache-from $(KICBASE_IMAGE_GCR) ./deploy/kicbase + docker tag local/kicbase:$(KIC_VERSION) local/kicbase:latest + docker tag local/kicbase:$(KIC_VERSION) local/kicbase:$(KIC_VERSION)-$(COMMIT_SHORT) + +SED = sed -i +ifeq ($(GOOS),darwin) + SED = sed -i '' +endif + +.PHONY: local-kicbase-debug +local-kicbase-debug: local-kicbase ## Builds a local kicbase image and switches source code to point to it + $(SED) 's|Version = .*|Version = \"$(KIC_VERSION)-$(COMMIT_SHORT)\"|;s|baseImageSHA = .*|baseImageSHA = \"\"|;s|gcrRepo = .*|gcrRepo = \"local/kicbase\"|;s|dockerhubRepo = .*|dockerhubRepo = \"local/kicbase\"|' pkg/drivers/kic/types.go + .PHONY: push-kic-base-image push-kic-base-image: deploy/kicbase/auto-pause docker-multi-arch-builder ## Push multi-arch local/kicbase:latest to all remote registries ifdef AUTOPUSH From ed42a7bcf8eea7f49035d4a91b383517f775a046 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Tue, 15 Jun 2021 14:36:38 -0700 Subject: [PATCH 077/122] Upgrade gcp-auth-webhook to v0.0.6 --- pkg/minikube/assets/addons.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 779b5b6791..37edd415ce 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -529,7 +529,7 @@ var Addons = map[string]*Addon{ "0640"), }, false, "gcp-auth", map[string]string{ "KubeWebhookCertgen": "jettech/kube-webhook-certgen:v1.3.0@sha256:ff01fba91131ed260df3f3793009efbf9686f5a5ce78a85f81c386a4403f7689", - "GCPAuthWebhook": "k8s-minikube/gcp-auth-webhook:v0.0.5@sha256:4da26a6937e876c80642c98fed9efb2269a5d2cb55029de9e2685c9fd6bc1add", + "GCPAuthWebhook": "k8s-minikube/gcp-auth-webhook:v0.0.6@sha256:c407ad6ee97d8a0e8a21c713e2d9af66aaf73315e4a123874c00b786f962f3cd", }, map[string]string{ "GCPAuthWebhook": "gcr.io", }), From 0f3255eab63381bffee3f10a7ab2efe17e254b9a Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Tue, 15 Jun 2021 15:16:04 -0700 Subject: [PATCH 078/122] space --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 445f7a56e9..db9a23088e 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ KVM_GO_VERSION ?= $(GO_VERSION:.0=) INSTALL_SIZE ?= $(shell du out/minikube-windows-amd64.exe | cut -f1) BUILDROOT_BRANCH ?= 2020.02.12 -REGISTRY ?=gcr.io/k8s-minikube +REGISTRY ?= gcr.io/k8s-minikube # Get git commit id COMMIT_NO := $(shell git rev-parse HEAD 2> /dev/null || true) From 7b5381b6977cb8b6656c7ca717e17dd26b4404e5 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Wed, 16 Jun 2021 09:23:54 -0700 Subject: [PATCH 079/122] add generate-docs script --- cmd/minikube/cmd/generate-docs_test.go | 27 --------------- hack/generate_docs.sh | 47 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 hack/generate_docs.sh diff --git a/cmd/minikube/cmd/generate-docs_test.go b/cmd/minikube/cmd/generate-docs_test.go index 0d03d2a293..9489fdc88a 100644 --- a/cmd/minikube/cmd/generate-docs_test.go +++ b/cmd/minikube/cmd/generate-docs_test.go @@ -17,7 +17,6 @@ limitations under the License. package cmd import ( - "fmt" "io/ioutil" "os" "path/filepath" @@ -25,35 +24,9 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/spf13/pflag" "k8s.io/minikube/pkg/generate" ) -func TestGenerateDocs(t *testing.T) { - pflag.BoolP("help", "h", false, "") // avoid 'Docs are not updated. Please run `make generate-docs` to update commands documentation' error - dir := "../../../site/content/en/docs/commands/" - - for _, sc := range RootCmd.Commands() { - t.Run(sc.Name(), func(t *testing.T) { - if sc.Hidden { - t.Skip() - } - fp := filepath.Join(dir, fmt.Sprintf("%s.md", sc.Name())) - expectedContents, err := ioutil.ReadFile(fp) - if err != nil { - t.Fatalf("Docs are not updated. Please run `make generate-docs` to update commands documentation: %v", err) - } - actualContents, err := generate.DocForCommand(sc) - if err != nil { - t.Fatalf("error getting contents: %v", err) - } - if diff := cmp.Diff(actualContents, string(expectedContents)); diff != "" { - t.Fatalf("Docs are not updated. Please run `make generate-docs` to update commands documentation: %s", diff) - } - }) - } -} - func TestGenerateTestDocs(t *testing.T) { tempdir, err := ioutil.TempDir("", "") if err != nil { diff --git a/hack/generate_docs.sh b/hack/generate_docs.sh new file mode 100644 index 0000000000..cae908cee7 --- /dev/null +++ b/hack/generate_docs.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Copyright 2021 The Kubernetes Authors All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +install_gh() { + export access_token="$1" + + # Make sure gh is installed and configured + ./hack/jenkins/installers/check_install_gh.sh +} + +config_git() { + git config user.name "minikube-bot" + git config user.email "minikube-bot@google.com" +} + +make generate-docs + +# If there are changes, open a PR +if ! git diff-index --quiet HEAD --; then + install_gh $1 + config_git + + branch=gendocs$(date +%s%N) + git checkout -b $branch + + git add . + git commit -m "Update generate-docs" + + git remote add minikube-bot https://minikube-bot:$1@github.com/minikube-bot/minikube.git + git push -u minikube-bot $branch + gh pr create --repo kubernetes/minukube --base master --title "Update generate-docs" --body "Committing changes resulting from \`make generate-docs\`" +fi From cf0d335309bbfe977e491e740937077dd7c13e00 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 15 Jun 2021 14:20:47 -0700 Subject: [PATCH 080/122] Remove assets.go from Makefile and replace with directly referencing addon files. --- Makefile | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index ce1c5dd247..e86e5b7f67 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ GOLINT_OPTIONS = --timeout 7m \ --build-tags "${MINIKUBE_INTEGRATION_BUILD_TAGS}" \ --enable gofmt,goimports,gocritic,golint,gocyclo,misspell,nakedret,stylecheck,unconvert,unparam,dogsled \ --exclude 'variable on range scope.*in function literal|ifElseChain' \ - --skip-files "pkg/minikube/translate/translations.go|pkg/minikube/assets/assets.go" + --skip-files "pkg/minikube/translate/translations.go" export GO111MODULE := on @@ -134,9 +134,10 @@ CMD_SOURCE_DIRS = cmd pkg SOURCE_DIRS = $(CMD_SOURCE_DIRS) test SOURCE_PACKAGES = ./cmd/... ./pkg/... ./test/... -SOURCE_GENERATED = pkg/minikube/assets/assets.go pkg/minikube/translate/translations.go +SOURCE_GENERATED = pkg/minikube/translate/translations.go SOURCE_FILES = $(shell find $(CMD_SOURCE_DIRS) -type f -name "*.go" | grep -v _test.go) GOTEST_FILES = $(shell find $(CMD_SOURCE_DIRS) -type f -name "*.go" | grep _test.go) +ADDON_FILES = $(shell find "deploy/addons" -type f) # kvm2 ldflags KVM2_LDFLAGS := -X k8s.io/minikube/pkg/drivers/kvm.version=$(VERSION) -X k8s.io/minikube/pkg/drivers/kvm.gitCommitID=$(COMMIT) @@ -195,7 +196,7 @@ ifneq ($(TEST_FILES),) INTEGRATION_TESTS_TO_RUN := $(addprefix ./test/integration/, $(TEST_HELPERS) $(TEST_FILES)) endif -out/minikube$(IS_EXE): $(SOURCE_GENERATED) $(SOURCE_FILES) go.mod +out/minikube$(IS_EXE): $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) go.mod ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) $(call DOCKER,$(BUILD_IMAGE),GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) /usr/bin/make $@) else @@ -244,7 +245,7 @@ minikube-windows-amd64.exe: out/minikube-windows-amd64.exe ## Build Minikube for eq = $(and $(findstring x$(1),x$(2)),$(findstring x$(2),x$(1))) -out/minikube-%: $(SOURCE_GENERATED) $(SOURCE_FILES) +out/minikube-%: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) $(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@) else @@ -253,7 +254,7 @@ else go build -tags "$(MINIKUBE_BUILD_TAGS)" -ldflags="$(MINIKUBE_LDFLAGS)" -a -o $@ k8s.io/minikube/cmd/minikube endif -out/minikube-linux-armv6: $(SOURCE_GENERATED) $(SOURCE_FILES) +out/minikube-linux-armv6: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) $(Q)GOOS=linux GOARCH=arm GOARM=6 \ go build -tags "$(MINIKUBE_BUILD_TAGS)" -ldflags="$(MINIKUBE_LDFLAGS)" -a -o $@ k8s.io/minikube/cmd/minikube @@ -397,22 +398,6 @@ out/coverage.html: out/coverage.out extract: ## extract internationalization words for translations go run cmd/extract/extract.go -# Regenerates assets.go when template files have been updated -pkg/minikube/assets/assets.go: $(shell find "deploy/addons" -type f) -ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) - $(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@) -endif - @which go-bindata >/dev/null 2>&1 || GO111MODULE=off GOBIN="$(GOPATH)$(DIRSEP)bin" go get github.com/go-bindata/go-bindata/... - $(if $(quiet),@echo " GEN $@") - $(Q)PATH="$(PATH)$(PATHSEP)$(GOPATH)$(DIRSEP)bin" go-bindata -nomemcopy -o $@ -pkg assets deploy/addons/... - $(Q)-gofmt -s -w $@ - @#golint: Dns should be DNS (compat sed) - @sed -i -e 's/Dns/DNS/g' $@ && rm -f ./-e - @#golint: Html should be HTML (compat sed) - @sed -i -e 's/Html/HTML/g' $@ && rm -f ./-e - @#golint: don't use underscores in Go names - @sed -i -e 's/SnapshotStorageK8sIo_volumesnapshot/SnapshotStorageK8sIoVolumesnapshot/g' $@ && rm -f ./-e - pkg/minikube/translate/translations.go: $(shell find "translations/" -type f) ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) $(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@) @@ -882,11 +867,11 @@ out/mkcmp: GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $@ cmd/performance/mkcmp/main.go .PHONY: deploy/kicbase/auto-pause # auto pause binary to be used for kic image work around for not passing the whole repo as docker context -deploy/kicbase/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES) +deploy/kicbase/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) GOOS=linux GOARCH=$(GOARCH) go build -o $@ cmd/auto-pause/auto-pause.go # auto pause binary to be used for ISO -deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/usr/bin/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES) +deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/usr/bin/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) GOOS=linux GOARCH=$(GOARCH) go build -o $@ cmd/auto-pause/auto-pause.go From 02b996e0116eb1899880894accb62d626e1ad3b1 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Tue, 15 Jun 2021 15:45:11 -0700 Subject: [PATCH 081/122] Redefine addon asset in terms of embed.FS. --- Makefile | 6 +- deploy/addons/assets.go | 135 +++++++++++++ pkg/minikube/assets/addons.go | 328 ++++++++++++++++--------------- pkg/minikube/assets/vm_assets.go | 11 +- 4 files changed, 312 insertions(+), 168 deletions(-) create mode 100644 deploy/addons/assets.go diff --git a/Makefile b/Makefile index e86e5b7f67..001301f846 100644 --- a/Makefile +++ b/Makefile @@ -130,14 +130,14 @@ MINIKUBE_MARKDOWN_FILES := README.md CONTRIBUTING.md CHANGELOG.md MINIKUBE_BUILD_TAGS := MINIKUBE_INTEGRATION_BUILD_TAGS := integration $(MINIKUBE_BUILD_TAGS) -CMD_SOURCE_DIRS = cmd pkg +CMD_SOURCE_DIRS = cmd pkg deploy/addons SOURCE_DIRS = $(CMD_SOURCE_DIRS) test -SOURCE_PACKAGES = ./cmd/... ./pkg/... ./test/... +SOURCE_PACKAGES = ./cmd/... ./pkg/... ./deploy/addons/... ./test/... SOURCE_GENERATED = pkg/minikube/translate/translations.go SOURCE_FILES = $(shell find $(CMD_SOURCE_DIRS) -type f -name "*.go" | grep -v _test.go) GOTEST_FILES = $(shell find $(CMD_SOURCE_DIRS) -type f -name "*.go" | grep _test.go) -ADDON_FILES = $(shell find "deploy/addons" -type f) +ADDON_FILES = $(shell find "deploy/addons" -type f | grep -v "\.go") # kvm2 ldflags KVM2_LDFLAGS := -X k8s.io/minikube/pkg/drivers/kvm.version=$(VERSION) -X k8s.io/minikube/pkg/drivers/kvm.gitCommitID=$(COMMIT) diff --git a/deploy/addons/assets.go b/deploy/addons/assets.go new file mode 100644 index 0000000000..dfbdbfa379 --- /dev/null +++ b/deploy/addons/assets.go @@ -0,0 +1,135 @@ +/* +Copyright 2021 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package addons + +import "embed" + +var ( + // AutoPauseAssets assets for auto-pause addon + //go:embed auto-pause/*.tmpl + //go:embed auto-pause/auto-pause.service + //go:embed auto-pause/unpause.lua + AutoPauseAssets embed.FS + + // DashboardAssets assets for dashboard addon + //go:embed dashboard/*.yaml dashboard/*.tmpl + DashboardAssets embed.FS + + // DefaultStorageClassAssets assets for default-storageclass addon + //go:embed storageclass/storageclass.yaml.tmpl + DefaultStorageClassAssets embed.FS + + // PodSecurityPolicyAssets assets for pod-security-policy addon + //go:embed pod-security-policy/pod-security-policy.yaml.tmpl + PodSecurityPolicyAssets embed.FS + + // StorageProvisionerAssets assets for storage-provisioner addon + //go:embed storage-provisioner/storage-provisioner.yaml.tmpl + StorageProvisionerAssets embed.FS + + // StorageProvisionerGlusterAssets assets for storage-provisioner-gluster addon + //go:embed storage-provisioner-gluster/*.tmpl + StorageProvisionerGlusterAssets embed.FS + + // EfkAssets assets for efk addon + //go:embed efk/*.tmpl + EfkAssets embed.FS + + // IngressAssets assets for ingress addon + //go:embed ingress/*.tmpl + IngressAssets embed.FS + + // IstioProvisionerAssets assets for istio-provisioner addon + //go:embed istio-provisioner/istio-operator.yaml.tmpl + IstioProvisionerAssets embed.FS + + // IstioAssets assets for istio addon + //go:embed istio/istio-default-profile.yaml.tmpl + IstioAssets embed.FS + + // KubevirtAssets assets for kubevirt addon + //go:embed kubevirt/pod.yaml.tmpl + KubevirtAssets embed.FS + + // MetricsServerAssets assets for metrics-server addon + //go:embed metrics-server/*.tmpl + MetricsServerAssets embed.FS + + // OlmAssets assets for olm addon + //go:embed olm/*.tmpl + OlmAssets embed.FS + + // RegistryAssets assets for registry addon + //go:embed registry/*.tmpl + RegistryAssets embed.FS + + // RegistryCredsAssets assets for registry-creds addon + //go:embed registry-creds/registry-creds-rc.yaml.tmpl + RegistryCredsAssets embed.FS + + // RegistryAliasesAssets assets for registry-aliases addon + //go:embed registry-aliases/*.tmpl + RegistryAliasesAssets embed.FS + + // FreshpodAssets assets for freshpod addon + //go:embed freshpod/freshpod-rc.yaml.tmpl + FreshpodAssets embed.FS + + // NvidiaDriverInstallerAssets assets for nvidia-driver-installer addon + //go:embed gpu/nvidia-driver-installer.yaml.tmpl + NvidiaDriverInstallerAssets embed.FS + + // NvidiaGpuDevicePluginAssets assets for nvidia-gpu-device-plugin addon + //go:embed gpu/nvidia-gpu-device-plugin.yaml.tmpl + NvidiaGpuDevicePluginAssets embed.FS + + // LogviewerAssets assets for logviewer addon + //go:embed logviewer/*.tmpl + LogviewerAssets embed.FS + + // GvisorAssets assets for gvisor addon + //go:embed gvisor/*.tmpl gvisor/*.toml + GvisorAssets embed.FS + + // HelmTillerAssets assets for helm-tiller addon + //go:embed helm-tiller/*.tmpl + HelmTillerAssets embed.FS + + // IngressDNSAssets assets for ingress-dns addon + //go:embed ingress-dns/ingress-dns-pod.yaml.tmpl + IngressDNSAssets embed.FS + + // MetallbAssets assets for metallb addon + //go:embed metallb/*.tmpl + MetallbAssets embed.FS + + // AmbassadorAssets assets for ambassador addon + //go:embed ambassador/*.tmpl + AmbassadorAssets embed.FS + + // GcpAuthAssets assets for gcp-auth addon + //go:embed gcp-auth/*.tmpl + GcpAuthAssets embed.FS + + // VolumeSnapshotsAssets assets for volumesnapshots addon + //go:embed volumesnapshots/*.tmpl + VolumeSnapshotsAssets embed.FS + + // CsiHostpathDriverAssets assets for csi-hostpath-driver addon + //go:embed csi-hostpath-driver/deploy/*.tmpl csi-hostpath-driver/rbac/*.tmpl + CsiHostpathDriverAssets embed.FS +) diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 779b5b6791..f4c4dd5d20 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/spf13/viper" + "k8s.io/minikube/deploy/addons" "k8s.io/minikube/pkg/minikube/config" "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/out" @@ -79,27 +80,32 @@ func (a *Addon) IsEnabled(cc *config.ClusterConfig) bool { var Addons = map[string]*Addon{ "auto-pause": NewAddon([]*BinAsset{ MustBinAsset( - "deploy/addons/auto-pause/auto-pause.yaml.tmpl", + addons.AutoPauseAssets, + "auto-pause/auto-pause.yaml.tmpl", vmpath.GuestAddonsDir, "auto-pause.yaml", "0640"), MustBinAsset( - "deploy/addons/auto-pause/auto-pause-hook.yaml.tmpl", + addons.AutoPauseAssets, + "auto-pause/auto-pause-hook.yaml.tmpl", vmpath.GuestAddonsDir, "auto-pause-hook.yaml", "0640"), MustBinAsset( - "deploy/addons/auto-pause/haproxy.cfg.tmpl", + addons.AutoPauseAssets, + "auto-pause/haproxy.cfg.tmpl", vmpath.GuestPersistentDir, "haproxy.cfg", "0640"), MustBinAsset( - "deploy/addons/auto-pause/unpause.lua", + addons.AutoPauseAssets, + "auto-pause/unpause.lua", vmpath.GuestPersistentDir, "unpause.lua", "0640"), MustBinAsset( - "deploy/addons/auto-pause/auto-pause.service", + addons.AutoPauseAssets, + "auto-pause/auto-pause.service", "/etc/systemd/system/", "auto-pause.service", "0640"), @@ -112,37 +118,37 @@ var Addons = map[string]*Addon{ }), "dashboard": NewAddon([]*BinAsset{ // We want to create the kubernetes-dashboard ns first so that every subsequent object can be created - MustBinAsset("deploy/addons/dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-clusterrole.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrole.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrolebinding.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-configmap.yaml", vmpath.GuestAddonsDir, "dashboard-configmap.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-dp.yaml.tmpl", vmpath.GuestAddonsDir, "dashboard-dp.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-role.yaml", vmpath.GuestAddonsDir, "dashboard-role.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-rolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-rolebinding.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-secret.yaml", vmpath.GuestAddonsDir, "dashboard-secret.yaml", "0640"), - MustBinAsset("deploy/addons/dashboard/dashboard-svc.yaml", vmpath.GuestAddonsDir, "dashboard-svc.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-ns.yaml", vmpath.GuestAddonsDir, "dashboard-ns.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-clusterrole.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrole.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-clusterrolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-clusterrolebinding.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-configmap.yaml", vmpath.GuestAddonsDir, "dashboard-configmap.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-dp.yaml.tmpl", vmpath.GuestAddonsDir, "dashboard-dp.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-role.yaml", vmpath.GuestAddonsDir, "dashboard-role.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-rolebinding.yaml", vmpath.GuestAddonsDir, "dashboard-rolebinding.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-sa.yaml", vmpath.GuestAddonsDir, "dashboard-sa.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-secret.yaml", vmpath.GuestAddonsDir, "dashboard-secret.yaml", "0640"), + MustBinAsset(addons.DashboardAssets, "dashboard/dashboard-svc.yaml", vmpath.GuestAddonsDir, "dashboard-svc.yaml", "0640"), }, false, "dashboard", map[string]string{ "Dashboard": "kubernetesui/dashboard:v2.1.0@sha256:7f80b5ba141bead69c4fee8661464857af300d7d7ed0274cf7beecedc00322e6", "MetricsScraper": "kubernetesui/metrics-scraper:v1.0.4@sha256:555981a24f184420f3be0c79d4efb6c948a85cfce84034f85a563f4151a81cbf", }, nil), "default-storageclass": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/storageclass/storageclass.yaml.tmpl", + MustBinAsset(addons.DefaultStorageClassAssets, + "storageclass/storageclass.yaml.tmpl", vmpath.GuestAddonsDir, "storageclass.yaml", "0640"), }, true, "default-storageclass", nil, nil), "pod-security-policy": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/pod-security-policy/pod-security-policy.yaml.tmpl", + MustBinAsset(addons.PodSecurityPolicyAssets, + "pod-security-policy/pod-security-policy.yaml.tmpl", vmpath.GuestAddonsDir, "pod-security-policy.yaml", "0640"), }, false, "pod-security-policy", nil, nil), "storage-provisioner": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/storage-provisioner/storage-provisioner.yaml.tmpl", + MustBinAsset(addons.StorageProvisionerAssets, + "storage-provisioner/storage-provisioner.yaml.tmpl", vmpath.GuestAddonsDir, "storage-provisioner.yaml", "0640"), @@ -152,23 +158,23 @@ var Addons = map[string]*Addon{ "StorageProvisioner": "gcr.io", }), "storage-provisioner-gluster": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/storage-provisioner-gluster/storage-gluster-ns.yaml.tmpl", + MustBinAsset(addons.StorageProvisionerGlusterAssets, + "storage-provisioner-gluster/storage-gluster-ns.yaml.tmpl", vmpath.GuestAddonsDir, "storage-gluster-ns.yaml", "0640"), - MustBinAsset( - "deploy/addons/storage-provisioner-gluster/glusterfs-daemonset.yaml.tmpl", + MustBinAsset(addons.StorageProvisionerGlusterAssets, + "storage-provisioner-gluster/glusterfs-daemonset.yaml.tmpl", vmpath.GuestAddonsDir, "glusterfs-daemonset.yaml", "0640"), - MustBinAsset( - "deploy/addons/storage-provisioner-gluster/heketi-deployment.yaml.tmpl", + MustBinAsset(addons.StorageProvisionerGlusterAssets, + "storage-provisioner-gluster/heketi-deployment.yaml.tmpl", vmpath.GuestAddonsDir, "heketi-deployment.yaml", "0640"), - MustBinAsset( - "deploy/addons/storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl", + MustBinAsset(addons.StorageProvisionerGlusterAssets, + "storage-provisioner-gluster/storage-provisioner-glusterfile.yaml.tmpl", vmpath.GuestAddonsDir, "storage-privisioner-glusterfile.yaml", "0640"), @@ -180,33 +186,33 @@ var Addons = map[string]*Addon{ "GlusterfsServer": "quay.io", }), "efk": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/efk/elasticsearch-rc.yaml.tmpl", + MustBinAsset(addons.EfkAssets, + "efk/elasticsearch-rc.yaml.tmpl", vmpath.GuestAddonsDir, "elasticsearch-rc.yaml", "0640"), - MustBinAsset( - "deploy/addons/efk/elasticsearch-svc.yaml.tmpl", + MustBinAsset(addons.EfkAssets, + "efk/elasticsearch-svc.yaml.tmpl", vmpath.GuestAddonsDir, "elasticsearch-svc.yaml", "0640"), - MustBinAsset( - "deploy/addons/efk/fluentd-es-rc.yaml.tmpl", + MustBinAsset(addons.EfkAssets, + "efk/fluentd-es-rc.yaml.tmpl", vmpath.GuestAddonsDir, "fluentd-es-rc.yaml", "0640"), - MustBinAsset( - "deploy/addons/efk/fluentd-es-configmap.yaml.tmpl", + MustBinAsset(addons.EfkAssets, + "efk/fluentd-es-configmap.yaml.tmpl", vmpath.GuestAddonsDir, "fluentd-es-configmap.yaml", "0640"), - MustBinAsset( - "deploy/addons/efk/kibana-rc.yaml.tmpl", + MustBinAsset(addons.EfkAssets, + "efk/kibana-rc.yaml.tmpl", vmpath.GuestAddonsDir, "kibana-rc.yaml", "0640"), - MustBinAsset( - "deploy/addons/efk/kibana-svc.yaml.tmpl", + MustBinAsset(addons.EfkAssets, + "efk/kibana-svc.yaml.tmpl", vmpath.GuestAddonsDir, "kibana-svc.yaml", "0640"), @@ -221,18 +227,18 @@ var Addons = map[string]*Addon{ "Kibana": "docker.elastic.co", }), "ingress": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/ingress/ingress-configmap.yaml.tmpl", + MustBinAsset(addons.IngressAssets, + "ingress/ingress-configmap.yaml.tmpl", vmpath.GuestAddonsDir, "ingress-configmap.yaml", "0640"), - MustBinAsset( - "deploy/addons/ingress/ingress-rbac.yaml.tmpl", + MustBinAsset(addons.IngressAssets, + "ingress/ingress-rbac.yaml.tmpl", vmpath.GuestAddonsDir, "ingress-rbac.yaml", "0640"), - MustBinAsset( - "deploy/addons/ingress/ingress-dp.yaml.tmpl", + MustBinAsset(addons.IngressAssets, + "ingress/ingress-dp.yaml.tmpl", vmpath.GuestAddonsDir, "ingress-dp.yaml", "0640"), @@ -244,8 +250,8 @@ var Addons = map[string]*Addon{ "IngressController": "k8s.gcr.io", }), "istio-provisioner": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/istio-provisioner/istio-operator.yaml.tmpl", + MustBinAsset(addons.IstioProvisionerAssets, + "istio-provisioner/istio-operator.yaml.tmpl", vmpath.GuestAddonsDir, "istio-operator.yaml", "0640"), @@ -253,15 +259,15 @@ var Addons = map[string]*Addon{ "IstioOperator": "istio/operator:1.5.0@sha256:25a6398ed4996a5313767ceb63768d503c266f63506ad3074b30eef6b5b5167e", }, nil), "istio": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/istio/istio-default-profile.yaml.tmpl", + MustBinAsset(addons.IstioAssets, + "istio/istio-default-profile.yaml.tmpl", vmpath.GuestAddonsDir, "istio-default-profile.yaml", "0640"), }, false, "istio", nil, nil), "kubevirt": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/kubevirt/pod.yaml.tmpl", + MustBinAsset(addons.KubevirtAssets, + "kubevirt/pod.yaml.tmpl", vmpath.GuestAddonsDir, "pod.yaml", "0640"), @@ -269,23 +275,23 @@ var Addons = map[string]*Addon{ "Kubectl": "bitnami/kubectl:1.17@sha256:de642e973d3d0ef60e4d0a1f92286a9fdae245535c5990d4762bbe86fcf95887", }, nil), "metrics-server": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/metrics-server/metrics-apiservice.yaml.tmpl", + MustBinAsset(addons.MetricsServerAssets, + "metrics-server/metrics-apiservice.yaml.tmpl", vmpath.GuestAddonsDir, "metrics-apiservice.yaml", "0640"), - MustBinAsset( - "deploy/addons/metrics-server/metrics-server-deployment.yaml.tmpl", + MustBinAsset(addons.MetricsServerAssets, + "metrics-server/metrics-server-deployment.yaml.tmpl", vmpath.GuestAddonsDir, "metrics-server-deployment.yaml", "0640"), - MustBinAsset( - "deploy/addons/metrics-server/metrics-server-rbac.yaml.tmpl", + MustBinAsset(addons.MetricsServerAssets, + "metrics-server/metrics-server-rbac.yaml.tmpl", vmpath.GuestAddonsDir, "metrics-server-rbac.yaml", "0640"), - MustBinAsset( - "deploy/addons/metrics-server/metrics-server-service.yaml.tmpl", + MustBinAsset(addons.MetricsServerAssets, + "metrics-server/metrics-server-service.yaml.tmpl", vmpath.GuestAddonsDir, "metrics-server-service.yaml", "0640"), @@ -295,13 +301,13 @@ var Addons = map[string]*Addon{ "MetricsServer": "k8s.gcr.io", }), "olm": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/olm/crds.yaml.tmpl", + MustBinAsset(addons.OlmAssets, + "olm/crds.yaml.tmpl", vmpath.GuestAddonsDir, "crds.yaml", "0640"), - MustBinAsset( - "deploy/addons/olm/olm.yaml.tmpl", + MustBinAsset(addons.OlmAssets, + "olm/olm.yaml.tmpl", vmpath.GuestAddonsDir, "olm.yaml", "0640"), @@ -313,18 +319,18 @@ var Addons = map[string]*Addon{ "UpstreamCommunityOperators": "quay.io", }), "registry": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/registry/registry-rc.yaml.tmpl", + MustBinAsset(addons.RegistryAssets, + "registry/registry-rc.yaml.tmpl", vmpath.GuestAddonsDir, "registry-rc.yaml", "0640"), - MustBinAsset( - "deploy/addons/registry/registry-svc.yaml.tmpl", + MustBinAsset(addons.RegistryAssets, + "registry/registry-svc.yaml.tmpl", vmpath.GuestAddonsDir, "registry-svc.yaml", "0640"), - MustBinAsset( - "deploy/addons/registry/registry-proxy.yaml.tmpl", + MustBinAsset(addons.RegistryAssets, + "registry/registry-proxy.yaml.tmpl", vmpath.GuestAddonsDir, "registry-proxy.yaml", "0640"), @@ -335,8 +341,8 @@ var Addons = map[string]*Addon{ "KubeRegistryProxy": "gcr.io", }), "registry-creds": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/registry-creds/registry-creds-rc.yaml.tmpl", + MustBinAsset(addons.RegistryCredsAssets, + "registry-creds/registry-creds-rc.yaml.tmpl", vmpath.GuestAddonsDir, "registry-creds-rc.yaml", "0640"), @@ -344,28 +350,28 @@ var Addons = map[string]*Addon{ "RegistryCreds": "upmcenterprises/registry-creds:1.10@sha256:93a633d4f2b76a1c66bf19c664dbddc56093a543de6d54320f19f585ccd7d605", }, nil), "registry-aliases": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/registry-aliases/registry-aliases-sa.tmpl", + MustBinAsset(addons.RegistryAliasesAssets, + "registry-aliases/registry-aliases-sa.tmpl", vmpath.GuestAddonsDir, "registry-aliases-sa.yaml", "0640"), - MustBinAsset( - "deploy/addons/registry-aliases/registry-aliases-sa-crb.tmpl", + MustBinAsset(addons.RegistryAliasesAssets, + "registry-aliases/registry-aliases-sa-crb.tmpl", vmpath.GuestAddonsDir, "registry-aliases-sa-crb.yaml", "0640"), - MustBinAsset( - "deploy/addons/registry-aliases/registry-aliases-config.tmpl", + MustBinAsset(addons.RegistryAliasesAssets, + "registry-aliases/registry-aliases-config.tmpl", vmpath.GuestAddonsDir, "registry-aliases-config.yaml", "0640"), - MustBinAsset( - "deploy/addons/registry-aliases/node-etc-hosts-update.tmpl", + MustBinAsset(addons.RegistryAliasesAssets, + "registry-aliases/node-etc-hosts-update.tmpl", vmpath.GuestAddonsDir, "node-etc-hosts-update.yaml", "0640"), - MustBinAsset( - "deploy/addons/registry-aliases/patch-coredns-job.tmpl", + MustBinAsset(addons.RegistryAliasesAssets, + "registry-aliases/patch-coredns-job.tmpl", vmpath.GuestAddonsDir, "patch-coredns-job.yaml", "0640"), @@ -378,8 +384,8 @@ var Addons = map[string]*Addon{ "Pause": "gcr.io", }), "freshpod": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/freshpod/freshpod-rc.yaml.tmpl", + MustBinAsset(addons.FreshpodAssets, + "freshpod/freshpod-rc.yaml.tmpl", vmpath.GuestAddonsDir, "freshpod-rc.yaml", "0640"), @@ -389,8 +395,8 @@ var Addons = map[string]*Addon{ "FreshPod": "gcr.io", }), "nvidia-driver-installer": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/gpu/nvidia-driver-installer.yaml.tmpl", + MustBinAsset(addons.NvidiaDriverInstallerAssets, + "gpu/nvidia-driver-installer.yaml.tmpl", vmpath.GuestAddonsDir, "nvidia-driver-installer.yaml", "0640"), @@ -402,8 +408,8 @@ var Addons = map[string]*Addon{ "Pause": "k8s.gcr.io", }), "nvidia-gpu-device-plugin": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/gpu/nvidia-gpu-device-plugin.yaml.tmpl", + MustBinAsset(addons.NvidiaGpuDevicePluginAssets, + "gpu/nvidia-gpu-device-plugin.yaml.tmpl", vmpath.GuestAddonsDir, "nvidia-gpu-device-plugin.yaml", "0640"), @@ -411,13 +417,13 @@ var Addons = map[string]*Addon{ "NvidiaDevicePlugin": "nvidia/k8s-device-plugin:1.0.0-beta4@sha256:94d46bf513cbc43c4d77a364e4bbd409d32d89c8e686e12551cc3eb27c259b90", }, nil), "logviewer": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/logviewer/logviewer-dp-and-svc.yaml.tmpl", + MustBinAsset(addons.LogviewerAssets, + "logviewer/logviewer-dp-and-svc.yaml.tmpl", vmpath.GuestAddonsDir, "logviewer-dp-and-svc.yaml", "0640"), - MustBinAsset( - "deploy/addons/logviewer/logviewer-rbac.yaml.tmpl", + MustBinAsset(addons.LogviewerAssets, + "logviewer/logviewer-rbac.yaml.tmpl", vmpath.GuestAddonsDir, "logviewer-rbac.yaml", "0640"), @@ -425,18 +431,18 @@ var Addons = map[string]*Addon{ "LogViewer": "ivans3/minikube-log-viewer:latest@sha256:75854f45305cc47d17b04c6c588fa60777391761f951e3a34161ddf1f1b06405", }, nil), "gvisor": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/gvisor/gvisor-pod.yaml.tmpl", + MustBinAsset(addons.GvisorAssets, + "gvisor/gvisor-pod.yaml.tmpl", vmpath.GuestAddonsDir, "gvisor-pod.yaml", "0640"), - MustBinAsset( - "deploy/addons/gvisor/gvisor-runtimeclass.yaml.tmpl", + MustBinAsset(addons.GvisorAssets, + "gvisor/gvisor-runtimeclass.yaml.tmpl", vmpath.GuestAddonsDir, "gvisor-runtimeclass.yaml", "0640"), - MustBinAsset( - "deploy/addons/gvisor/gvisor-config.toml", + MustBinAsset(addons.GvisorAssets, + "gvisor/gvisor-config.toml", vmpath.GuestGvisorDir, constants.GvisorConfigTomlTargetName, "0640"), @@ -446,18 +452,18 @@ var Addons = map[string]*Addon{ "GvisorAddon": "gcr.io", }), "helm-tiller": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/helm-tiller/helm-tiller-dp.tmpl", + MustBinAsset(addons.HelmTillerAssets, + "helm-tiller/helm-tiller-dp.tmpl", vmpath.GuestAddonsDir, "helm-tiller-dp.yaml", "0640"), - MustBinAsset( - "deploy/addons/helm-tiller/helm-tiller-rbac.tmpl", + MustBinAsset(addons.HelmTillerAssets, + "helm-tiller/helm-tiller-rbac.tmpl", vmpath.GuestAddonsDir, "helm-tiller-rbac.yaml", "0640"), - MustBinAsset( - "deploy/addons/helm-tiller/helm-tiller-svc.tmpl", + MustBinAsset(addons.HelmTillerAssets, + "helm-tiller/helm-tiller-svc.tmpl", vmpath.GuestAddonsDir, "helm-tiller-svc.yaml", "0640"), @@ -467,8 +473,8 @@ var Addons = map[string]*Addon{ "Tiller": "gcr.io", }), "ingress-dns": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/ingress-dns/ingress-dns-pod.yaml.tmpl", + MustBinAsset(addons.IngressDNSAssets, + "ingress-dns/ingress-dns-pod.yaml.tmpl", vmpath.GuestAddonsDir, "ingress-dns-pod.yaml", "0640"), @@ -476,13 +482,13 @@ var Addons = map[string]*Addon{ "IngressDNS": "cryptexlabs/minikube-ingress-dns:0.3.0@sha256:e252d2a4c704027342b303cc563e95d2e71d2a0f1404f55d676390e28d5093ab", }, nil), "metallb": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/metallb/metallb.yaml.tmpl", + MustBinAsset(addons.MetallbAssets, + "metallb/metallb.yaml.tmpl", vmpath.GuestAddonsDir, "metallb.yaml", "0640"), - MustBinAsset( - "deploy/addons/metallb/metallb-config.yaml.tmpl", + MustBinAsset(addons.MetallbAssets, + "metallb/metallb-config.yaml.tmpl", vmpath.GuestAddonsDir, "metallb-config.yaml", "0640"), @@ -491,18 +497,18 @@ var Addons = map[string]*Addon{ "Controller": "metallb/controller:v0.9.6@sha256:fbfdb9d3f55976b0ee38f3309d83a4ca703efcf15d6ca7889cd8189142286502", }, nil), "ambassador": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/ambassador/ambassador-operator-crds.yaml.tmpl", + MustBinAsset(addons.AmbassadorAssets, + "ambassador/ambassador-operator-crds.yaml.tmpl", vmpath.GuestAddonsDir, "ambassador-operator-crds.yaml", "0640"), - MustBinAsset( - "deploy/addons/ambassador/ambassador-operator.yaml.tmpl", + MustBinAsset(addons.AmbassadorAssets, + "ambassador/ambassador-operator.yaml.tmpl", vmpath.GuestAddonsDir, "ambassador-operator.yaml", "0640"), - MustBinAsset( - "deploy/addons/ambassador/ambassadorinstallation.yaml.tmpl", + MustBinAsset(addons.AmbassadorAssets, + "ambassador/ambassadorinstallation.yaml.tmpl", vmpath.GuestAddonsDir, "ambassadorinstallation.yaml", "0640"), @@ -512,18 +518,18 @@ var Addons = map[string]*Addon{ "AmbassadorOperator": "quay.io", }), "gcp-auth": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/gcp-auth/gcp-auth-ns.yaml.tmpl", + MustBinAsset(addons.GcpAuthAssets, + "gcp-auth/gcp-auth-ns.yaml.tmpl", vmpath.GuestAddonsDir, "gcp-auth-ns.yaml", "0640"), - MustBinAsset( - "deploy/addons/gcp-auth/gcp-auth-service.yaml.tmpl", + MustBinAsset(addons.GcpAuthAssets, + "gcp-auth/gcp-auth-service.yaml.tmpl", vmpath.GuestAddonsDir, "gcp-auth-service.yaml", "0640"), - MustBinAsset( - "deploy/addons/gcp-auth/gcp-auth-webhook.yaml.tmpl.tmpl", + MustBinAsset(addons.GcpAuthAssets, + "gcp-auth/gcp-auth-webhook.yaml.tmpl.tmpl", vmpath.GuestAddonsDir, "gcp-auth-webhook.yaml", "0640"), @@ -536,33 +542,33 @@ var Addons = map[string]*Addon{ "volumesnapshots": NewAddon([]*BinAsset{ // make sure the order of apply. `csi-hostpath-snapshotclass` must be the first position, because it depends on `snapshot.storage.k8s.io_volumesnapshotclasses` // if user disable volumesnapshots addon and delete `csi-hostpath-snapshotclass` after `snapshot.storage.k8s.io_volumesnapshotclasses`, kubernetes will return the error - MustBinAsset( - "deploy/addons/volumesnapshots/csi-hostpath-snapshotclass.yaml.tmpl", + MustBinAsset(addons.VolumeSnapshotsAssets, + "volumesnapshots/csi-hostpath-snapshotclass.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-snapshotclass.yaml", "0640"), - MustBinAsset( - "deploy/addons/volumesnapshots/snapshot.storage.k8s.io_volumesnapshotclasses.yaml.tmpl", + MustBinAsset(addons.VolumeSnapshotsAssets, + "volumesnapshots/snapshot.storage.k8s.io_volumesnapshotclasses.yaml.tmpl", vmpath.GuestAddonsDir, "snapshot.storage.k8s.io_volumesnapshotclasses.yaml", "0640"), - MustBinAsset( - "deploy/addons/volumesnapshots/snapshot.storage.k8s.io_volumesnapshotcontents.yaml.tmpl", + MustBinAsset(addons.VolumeSnapshotsAssets, + "volumesnapshots/snapshot.storage.k8s.io_volumesnapshotcontents.yaml.tmpl", vmpath.GuestAddonsDir, "snapshot.storage.k8s.io_volumesnapshotcontents.yaml", "0640"), - MustBinAsset( - "deploy/addons/volumesnapshots/snapshot.storage.k8s.io_volumesnapshots.yaml.tmpl", + MustBinAsset(addons.VolumeSnapshotsAssets, + "volumesnapshots/snapshot.storage.k8s.io_volumesnapshots.yaml.tmpl", vmpath.GuestAddonsDir, "snapshot.storage.k8s.io_volumesnapshots.yaml", "0640"), - MustBinAsset( - "deploy/addons/volumesnapshots/rbac-volume-snapshot-controller.yaml.tmpl", + MustBinAsset(addons.VolumeSnapshotsAssets, + "volumesnapshots/rbac-volume-snapshot-controller.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-volume-snapshot-controller.yaml", "0640"), - MustBinAsset( - "deploy/addons/volumesnapshots/volume-snapshot-controller-deployment.yaml.tmpl", + MustBinAsset(addons.VolumeSnapshotsAssets, + "volumesnapshots/volume-snapshot-controller-deployment.yaml.tmpl", vmpath.GuestAddonsDir, "volume-snapshot-controller-deployment.yaml", "0640"), @@ -572,68 +578,68 @@ var Addons = map[string]*Addon{ "SnapshotController": "k8s.gcr.io", }), "csi-hostpath-driver": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/csi-hostpath-driver/rbac/rbac-external-attacher.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/rbac/rbac-external-attacher.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-external-attacher.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/rbac/rbac-external-health-monitor-agent.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/rbac/rbac-external-health-monitor-agent.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-external-health-monitor-agent.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/rbac/rbac-external-health-monitor-controller.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/rbac/rbac-external-health-monitor-controller.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-external-health-monitor-controller.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/rbac/rbac-external-provisioner.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/rbac/rbac-external-provisioner.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-external-provisioner.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/rbac/rbac-external-resizer.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/rbac/rbac-external-resizer.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-external-resizer.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/rbac/rbac-external-snapshotter.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/rbac/rbac-external-snapshotter.yaml.tmpl", vmpath.GuestAddonsDir, "rbac-external-snapshotter.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-attacher.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-attacher.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-attacher.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-driverinfo.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-driverinfo.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-driverinfo.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-plugin.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-plugin.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-plugin.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-provisioner.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-provisioner.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-provisioner.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-resizer.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-resizer.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-resizer.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-snapshotter.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-snapshotter.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-snapshotter.yaml", "0640"), - MustBinAsset( - "deploy/addons/csi-hostpath-driver/deploy/csi-hostpath-storageclass.yaml.tmpl", + MustBinAsset(addons.CsiHostpathDriverAssets, + "csi-hostpath-driver/deploy/csi-hostpath-storageclass.yaml.tmpl", vmpath.GuestAddonsDir, "csi-hostpath-storageclass.yaml", "0640"), diff --git a/pkg/minikube/assets/vm_assets.go b/pkg/minikube/assets/vm_assets.go index 35df4fb275..b6ec89e9b8 100644 --- a/pkg/minikube/assets/vm_assets.go +++ b/pkg/minikube/assets/vm_assets.go @@ -18,6 +18,7 @@ package assets import ( "bytes" + "embed" "fmt" "html/template" "io" @@ -207,6 +208,7 @@ func NewMemoryAsset(d []byte, targetDir, targetName, permissions string) *Memory // BinAsset is a bindata (binary data) asset type BinAsset struct { + embed.FS BaseAsset reader io.ReadSeeker template *template.Template @@ -214,8 +216,8 @@ type BinAsset struct { } // MustBinAsset creates a new BinAsset, or panics if invalid -func MustBinAsset(name, targetDir, targetName, permissions string) *BinAsset { - asset, err := NewBinAsset(name, targetDir, targetName, permissions) +func MustBinAsset(fs embed.FS, name, targetDir, targetName, permissions string) *BinAsset { + asset, err := NewBinAsset(fs, name, targetDir, targetName, permissions) if err != nil { panic(fmt.Sprintf("Failed to define asset %s: %v", name, err)) } @@ -223,8 +225,9 @@ func MustBinAsset(name, targetDir, targetName, permissions string) *BinAsset { } // NewBinAsset creates a new BinAsset -func NewBinAsset(name, targetDir, targetName, permissions string) (*BinAsset, error) { +func NewBinAsset(fs embed.FS, name, targetDir, targetName, permissions string) (*BinAsset, error) { m := &BinAsset{ + FS: fs, BaseAsset: BaseAsset{ SourcePath: name, TargetDir: targetDir, @@ -249,7 +252,7 @@ func defaultValue(defValue string, val interface{}) string { } func (m *BinAsset) loadData() error { - contents, err := Asset(m.SourcePath) + contents, err := m.FS.ReadFile(m.SourcePath) if err != nil { return err } From 1bac30bbe7caa5b8c64b35cfb97c197ffe08840a Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 16 Jun 2021 09:14:09 -0700 Subject: [PATCH 082/122] Update site to describe new addon creation workflow. --- site/content/en/docs/contrib/addons.en.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/site/content/en/docs/contrib/addons.en.md b/site/content/en/docs/contrib/addons.en.md index 0ffe726934..b16a2f9ad9 100644 --- a/site/content/en/docs/contrib/addons.en.md +++ b/site/content/en/docs/contrib/addons.en.md @@ -47,24 +47,32 @@ To make the addon appear in `minikube addons list`, add it to `pkg/addons/config }, ``` +Next, add all required files using `//go:embed` directives to a new embed.FS variable in `deploy/addons/assets.go`. Here is the entry used by the `csi-hostpath-driver` addon: + +```go + // CsiHostpathDriverAssets assets for csi-hostpath-driver addon + //go:embed csi-hostpath-driver/deploy/*.tmpl csi-hostpath-driver/rbac/*.tmpl + CsiHostpathDriverAssets embed.FS +``` + Then, add into `pkg/minikube/assets/addons.go` the list of files to copy into the cluster, including manifests. Here is the entry used by the `registry` addon: ```go "registry": NewAddon([]*BinAsset{ - MustBinAsset( - "deploy/addons/registry/registry-rc.yaml.tmpl", + MustBinAsset(addons.RegistryAssets, + "registry/registry-rc.yaml.tmpl", vmpath.GuestAddonsDir, "registry-rc.yaml", "0640", false), - MustBinAsset( - "deploy/addons/registry/registry-svc.yaml.tmpl", + MustBinAsset(addons.RegistryAssets, + "registry/registry-svc.yaml.tmpl", vmpath.GuestAddonsDir, "registry-svc.yaml", "0640", false), - MustBinAsset( - "deploy/addons/registry/registry-proxy.yaml.tmpl", + MustBinAsset(addons.RegistryAssets, + "registry/registry-proxy.yaml.tmpl", vmpath.GuestAddonsDir, "registry-proxy.yaml", "0640", @@ -74,6 +82,7 @@ Then, add into `pkg/minikube/assets/addons.go` the list of files to copy into th The `MustBinAsset` arguments are: +* asset variable (typically present in `deploy/addons/assets.go`) * source filename * destination directory (typically `vmpath.GuestAddonsDir`) * destination filename From f7cb9286f6653b795301a2582da8aecc7190dc99 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Wed, 16 Jun 2021 10:06:11 -0700 Subject: [PATCH 083/122] only test for missing docs string --- cmd/minikube/cmd/generate-docs_test.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/cmd/minikube/cmd/generate-docs_test.go b/cmd/minikube/cmd/generate-docs_test.go index 9489fdc88a..91ce515de6 100644 --- a/cmd/minikube/cmd/generate-docs_test.go +++ b/cmd/minikube/cmd/generate-docs_test.go @@ -23,7 +23,6 @@ import ( "strings" "testing" - "github.com/google/go-cmp/cmp" "k8s.io/minikube/pkg/generate" ) @@ -34,12 +33,6 @@ func TestGenerateTestDocs(t *testing.T) { } defer os.RemoveAll(tempdir) docPath := filepath.Join(tempdir, "tests.md") - realPath := "../../../site/content/en/docs/contrib/tests.en.md" - - expectedContents, err := ioutil.ReadFile(realPath) - if err != nil { - t.Fatalf("error reading existing file: %v", err) - } err = generate.TestDocs(docPath, "../../../test/integration") if err != nil { @@ -50,10 +43,6 @@ func TestGenerateTestDocs(t *testing.T) { t.Fatalf("error reading generated file: %v", err) } - if diff := cmp.Diff(string(actualContents), string(expectedContents)); diff != "" { - t.Errorf("Test docs are not updated. Please run `make generate-docs` to update documentation: %s", diff) - } - rest := string(actualContents) for rest != "" { rest = checkForNeedsDoc(t, rest) From 7e904f7b3a723a56bd673199b4f031fbc55532c1 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Wed, 16 Jun 2021 10:06:28 -0700 Subject: [PATCH 084/122] add github action yaml --- .github/workflows/docs.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/docs.yaml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000000..dd1002a719 --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,17 @@ +name: "generate-docs" +on: + pull_request: + types: [closed] + +jobs: + generate-docs: + if: github.event.pull_request.merged == true + runs-on: ubuntu-18.04 + steps: + - uses: actions/setup-go@v2 + with: + go-version: 1.16.5 + stable: true + - name: gendocs + run: | + ./hack/generate_docs.sh ${{ secrets.MINIKUBE_BOT_PAT }} From 5efd296fde4a18c60fd50ef405bb183124401f07 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Wed, 16 Jun 2021 12:59:45 -0700 Subject: [PATCH 085/122] add tutorial for user flag --- site/content/en/docs/tutorials/user_flag.md | 50 +++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 site/content/en/docs/tutorials/user_flag.md diff --git a/site/content/en/docs/tutorials/user_flag.md b/site/content/en/docs/tutorials/user_flag.md new file mode 100644 index 0000000000..1db7833a00 --- /dev/null +++ b/site/content/en/docs/tutorials/user_flag.md @@ -0,0 +1,50 @@ +--- +title: "Using the User Flag" +linkTitle: "Using the User Flag" +weight: 1 +date: 2021-06-15 +description: > + Using the User Flag to Keep an Audit Log +--- + +## Overview + +In minikube, all executed commands are logged to a local audit log in the minikube home directory (default: `~/.minikube/logs/audit.json`). +These commands are logged with additional information including the user that ran them, which by default is the OS user. +However, there is a global flag `--user` that will set the user who ran the command in the audit log. + +## Prerequisites + +- minikube v1.17.1 or newer + +## What does the flag do? + +Assuming the OS user is `johndoe`, running `minikube start` will add the following to the audit log: +``` +|---------------|--------------------------|-----------------------------|--------------|----------------|-------------------------------|-------------------------------| +| Command | Args | Profile | User | Version | Start Time | End Time | +|---------------|--------------------------|-----------------------------|--------------|----------------|-------------------------------|-------------------------------| +| start | | minikube | johndoe | v1.21.0 | Tue, 15 Jun 2021 09:00:00 MST | Tue, 15 Jun 2021 09:01:00 MST | +|---------------|--------------------------|-----------------------------|--------------|----------------|-------------------------------|-------------------------------| +``` +As you can see, minikube pulled the OS user and listed them as the user for the command. + +Running the same command with `--user=mary` appended to the command will add the following to the audit log: +``` +|---------------|--------------------------|-----------------------------|--------------|----------------|-------------------------------|-------------------------------| +| Command | Args | Profile | User | Version | Start Time | End Time | +|---------------|--------------------------|-----------------------------|--------------|----------------|-------------------------------|-------------------------------| +| start | --user=mary | minikube | mary | v1.21.0 | Tue, 15 Jun 2021 09:00:00 MST | Tue, 15 Jun 2021 09:01:00 MST | +|---------------|--------------------------|-----------------------------|--------------|----------------|-------------------------------|-------------------------------| +``` +Here you can see that passing `--user=mary` overwrote the OS user with `mary` as the user for the command. + +## Example use case + +A good use case for the `--user` flag is if you have an application that starts and stops minikube clusters. +Assume the application will use an exsiting cluster if available, otherwise, it will start a new one. +The problem comes when the application is finished using the cluster, you only want to stop the running cluster if the application started the cluster, not if it was already existing. + +This is where the user flag comes into play. +If the application was configured to pass a user flag on minikube commands (ex. `--user=app123`) then you could check to see what user executed the last `start` command looking at the audit log. +If the last user was `app123` you're safe to stop the cluster, otherwise leave it running. From c037e5f62fb4e8c40bed7c44465779954d3d1b14 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 16 Jun 2021 15:29:50 -0700 Subject: [PATCH 086/122] Stop using sudo for check_install_gh. --- hack/jenkins/test-flake-chart/report_flakes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index a04c0d359c..16fc7a8800 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -82,6 +82,6 @@ if [[ "$FAILED_RATES_LINES" -gt 30 ]]; then fi # install gh if not present -sudo $DIR/../installers/check_install_gh.sh || true +$DIR/../installers/check_install_gh.sh gh issue comment "https://github.com/kubernetes/minikube/pull/$PR_NUMBER" --body "$(cat $TMP_COMMENT)" From c88dcec541e71fed4ead90da05ae105f57bf49db Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 16 Jun 2021 15:36:53 -0700 Subject: [PATCH 087/122] Stop ignoring pkg/minikube/assets/assets.go since it is not longer auto-generated. --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index e090af9bad..951196710e 100644 --- a/.gitignore +++ b/.gitignore @@ -35,8 +35,6 @@ _testmain.go #iso version file deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/etc/VERSION -/pkg/minikube/assets/assets.go-e -/pkg/minikube/assets/assets.go /pkg/minikube/translate/translations.go /pkg/minikube/translate/translations.go-e /minikube From 9f601ea39324ccde1d8f4e82b0b8fa9e661f7aed Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Wed, 16 Jun 2021 18:03:52 -0700 Subject: [PATCH 088/122] Fix commenting to a PR instead of an issue. --- hack/jenkins/test-flake-chart/report_flakes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index 16fc7a8800..0ffff11a79 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -84,4 +84,4 @@ fi # install gh if not present $DIR/../installers/check_install_gh.sh -gh issue comment "https://github.com/kubernetes/minikube/pull/$PR_NUMBER" --body "$(cat $TMP_COMMENT)" +gh pr comment "https://github.com/kubernetes/minikube/pull/$PR_NUMBER" --body "$(cat $TMP_COMMENT)" From 48709efc4dc347c3e2560809dbbd8a6e8a94e289 Mon Sep 17 00:00:00 2001 From: RA489 Date: Thu, 17 Jun 2021 15:15:04 +0530 Subject: [PATCH 089/122] change registery_mirror to registery-mirror --- cmd/minikube/cmd/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 0d4f574e29..71c7e32afa 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -162,7 +162,7 @@ func runStart(cmd *cobra.Command, args []string) { // can be configured as MINIKUBE_IMAGE_REPOSITORY and IMAGE_MIRROR_COUNTRY // this should be updated to documentation if len(registryMirror) == 0 { - registryMirror = viper.GetStringSlice("registry_mirror") + registryMirror = viper.GetStringSlice("registry-mirror") } if !config.ProfileNameValid(ClusterFlagValue()) { From f465a9684432d23c201e2c9947c4a34e5c1b65be Mon Sep 17 00:00:00 2001 From: Medya Ghazizadeh Date: Thu, 17 Jun 2021 12:05:36 -0400 Subject: [PATCH 090/122] site: how to run minikube on remote network --- site/content/en/docs/faq/_index.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index 9b5f9a6d95..3ce0a9a88c 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -92,3 +92,15 @@ Yes! If you prefer not having emoji in your minikube output 😔 , just set the MINIKUBE_IN_STYLE=0 minikube start ``` + +## How to access minikube cluster from on a remote network ? + +minikube is primary goal is to quickly sets up a local Kubernetes clusters, and we strongly discourge from using minikube in production or to listen on remote traffic. therefore by design minikube networking only listens on local network. + +however it possible to configure minikube to listen on a remote network. Please be aware this opens your network open to outside world and it is not recommended, and if you are not fully sure of the security implications, please avoid using this option. + +for docker/podman drivers you could use `--listen-address` +``` +minikube start --listen-address=0.0.0.0 +``` + From 5b8b5ce1024a5f3e3a2723550727f826ed21d6b4 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 17 Jun 2021 09:28:27 -0700 Subject: [PATCH 091/122] Fix flake rates being commented about when no failed tests are present. --- hack/jenkins/test-flake-chart/report_flakes.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/jenkins/test-flake-chart/report_flakes.sh b/hack/jenkins/test-flake-chart/report_flakes.sh index a04c0d359c..6238fa21b0 100755 --- a/hack/jenkins/test-flake-chart/report_flakes.sh +++ b/hack/jenkins/test-flake-chart/report_flakes.sh @@ -61,7 +61,7 @@ TMP_FAILED_RATES="$TMP_FLAKE_RATES\_filtered" > "$TMP_FAILED_RATES" FAILED_RATES_LINES=$(wc -l < "$TMP_FAILED_RATES") -if [[ "$FAILED_RATES_LINES" -gt 30 ]]; then +if [[ "$FAILED_RATES_LINES" -eq 0 ]]; then echo "No failed tests! Aborting without commenting..." 1>&2 exit 0 fi From 300230bd5c3f56012a00e5a665638cd0ab32aaed Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 17 Jun 2021 09:41:40 -0700 Subject: [PATCH 092/122] Update flake chart colors. --- hack/jenkins/test-flake-chart/flake_chart.js | 1 + 1 file changed, 1 insertion(+) diff --git a/hack/jenkins/test-flake-chart/flake_chart.js b/hack/jenkins/test-flake-chart/flake_chart.js index e18d5389a5..736fc7cd7a 100644 --- a/hack/jenkins/test-flake-chart/flake_chart.js +++ b/hack/jenkins/test-flake-chart/flake_chart.js @@ -184,6 +184,7 @@ async function init() { 0: { title: "Flake rate", minValue: 0, maxValue: 100 }, 1: { title: "Duration (seconds)" }, }, + colors: ['#dc3912', '#3366cc'], tooltip: { trigger: "selection", isHtml: true } }; const chart = new google.visualization.LineChart(document.getElementById('chart_div')); From ddea20b2608c0f105c93f61c48ee85a34928ef77 Mon Sep 17 00:00:00 2001 From: Medya Ghazizadeh Date: Thu, 17 Jun 2021 13:05:08 -0400 Subject: [PATCH 093/122] Update _index.md --- site/content/en/docs/faq/_index.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/site/content/en/docs/faq/_index.md b/site/content/en/docs/faq/_index.md index 3ce0a9a88c..ccd09b6c57 100644 --- a/site/content/en/docs/faq/_index.md +++ b/site/content/en/docs/faq/_index.md @@ -93,13 +93,14 @@ MINIKUBE_IN_STYLE=0 minikube start ``` -## How to access minikube cluster from on a remote network ? +## How can I access a minikube cluster from a remote network? -minikube is primary goal is to quickly sets up a local Kubernetes clusters, and we strongly discourge from using minikube in production or to listen on remote traffic. therefore by design minikube networking only listens on local network. +minikube's primary goal is to quickly set up local Kubernetes clusters, and therefore we strongly discourage using minikube in production or for listening to remote traffic. By design, minikube is meant to only listen on the local network. -however it possible to configure minikube to listen on a remote network. Please be aware this opens your network open to outside world and it is not recommended, and if you are not fully sure of the security implications, please avoid using this option. +However, it is possible to configure minikube to listen on a remote network. This will open your network to the outside world and is not recommended. If you are not fully aware of the security implications, please avoid using this. + +For the docker and podman driver, use `--listen-address` flag: -for docker/podman drivers you could use `--listen-address` ``` minikube start --listen-address=0.0.0.0 ``` From c1a7937184d70344b39f1fd7df10c12f911aee3f Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 12:08:50 -0700 Subject: [PATCH 094/122] change workflow condition --- .github/workflows/docs.yaml | 6 +++--- hack/update/golang_version/update_golang_version.go | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index dd1002a719..49e1df79a8 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,11 +1,11 @@ name: "generate-docs" on: - pull_request: - types: [closed] + push: + branch: + - master jobs: generate-docs: - if: github.event.pull_request.merged == true runs-on: ubuntu-18.04 steps: - uses: actions/setup-go@v2 diff --git a/hack/update/golang_version/update_golang_version.go b/hack/update/golang_version/update_golang_version.go index ca1096f203..53f5336da0 100644 --- a/hack/update/golang_version/update_golang_version.go +++ b/hack/update/golang_version/update_golang_version.go @@ -70,6 +70,11 @@ var ( `go-version: '.*`: `go-version: '{{.StableVersion}}'`, }, }, + ".github/workflows/docs.yml": { + Replace: map[string]string{ + `go-version: '.*`: `go-version: '{{.StableVersion}}'`, + }, + }, ".travis.yml": { Replace: map[string]string{ `go:\n - .*`: `go:{{printf "\n - %s" .StableVersion}}`, From f2684bc777f119282096f1622d5e5374ecbf3a4a Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 12:19:32 -0700 Subject: [PATCH 095/122] fix syntax --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 49e1df79a8..3552a5a9ac 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-18.04 steps: - uses: actions/setup-go@v2 - with: + with: go-version: 1.16.5 stable: true - name: gendocs From 0cabaf961e811b1fa9540f91369ccb6a0df5c98b Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 12:38:53 -0700 Subject: [PATCH 096/122] fix workflow --- .github/workflows/docs.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 3552a5a9ac..051c752d62 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -8,6 +8,7 @@ jobs: generate-docs: runs-on: ubuntu-18.04 steps: + - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: go-version: 1.16.5 From d37a3e0ba2936eaba102beb52b234d72039411a2 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 12:41:37 -0700 Subject: [PATCH 097/122] make script executable --- hack/generate_docs.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 hack/generate_docs.sh diff --git a/hack/generate_docs.sh b/hack/generate_docs.sh old mode 100644 new mode 100755 From f8b2ebcc63be5ae5f7dc5d51b19968f29790611e Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 13:25:13 -0700 Subject: [PATCH 098/122] do not run workflow if there is no secret --- hack/generate_docs.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hack/generate_docs.sh b/hack/generate_docs.sh index cae908cee7..f8fcc16445 100755 --- a/hack/generate_docs.sh +++ b/hack/generate_docs.sh @@ -16,6 +16,11 @@ set -e +if [ "$#" -ne 1 ]; then + # there's no secret and therefore no reason to run this script + exit 0 +fi + install_gh() { export access_token="$1" From 5816b2a0c78b3af861dce68f8ac3d794642e063c Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 13:51:37 -0700 Subject: [PATCH 099/122] golang 1.6.4 --- .github/workflows/docs.yaml | 4 ++-- .github/workflows/time-to-k8s.yml | 2 +- hack/update/golang_version/update_golang_version.go | 5 +++++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 051c752d62..1edb0da435 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,7 +1,7 @@ name: "generate-docs" on: push: - branch: + branches: - master jobs: @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: - go-version: 1.16.5 + go-version: 1.16.4 stable: true - name: gendocs run: | diff --git a/.github/workflows/time-to-k8s.yml b/.github/workflows/time-to-k8s.yml index 0b4103ac71..eeb3a65092 100644 --- a/.github/workflows/time-to-k8s.yml +++ b/.github/workflows/time-to-k8s.yml @@ -11,7 +11,7 @@ jobs: run: git submodule update --init - uses: actions/setup-go@v2 with: - go-version: 1.16.5 + go-version: 1.16.4 stable: true - name: Benchmark run: | diff --git a/hack/update/golang_version/update_golang_version.go b/hack/update/golang_version/update_golang_version.go index 53f5336da0..d4fc63799a 100644 --- a/hack/update/golang_version/update_golang_version.go +++ b/hack/update/golang_version/update_golang_version.go @@ -75,6 +75,11 @@ var ( `go-version: '.*`: `go-version: '{{.StableVersion}}'`, }, }, + ".github/workflows/time-to-k8s.yml": { + Replace: map[string]string{ + `go-version: '.*`: `go-version: '{{.StableVersion}}'`, + }, + }, ".travis.yml": { Replace: map[string]string{ `go:\n - .*`: `go:{{printf "\n - %s" .StableVersion}}`, From 95333ed1fe97f35b36098cbcc01baee12094695c Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 17 Jun 2021 15:01:11 -0700 Subject: [PATCH 100/122] Move daemon cache check before file cache check so cache doesn't need to be repopulated if daemon is already present. --- pkg/minikube/node/cache.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/minikube/node/cache.go b/pkg/minikube/node/cache.go index 30aade94ca..e05e788198 100644 --- a/pkg/minikube/node/cache.go +++ b/pkg/minikube/node/cache.go @@ -131,6 +131,15 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down }() for _, img := range append([]string{baseImg}, kic.FallbackImages...) { var err error + + if driver.IsDocker(cc.Driver) { + if download.ImageExistsInDaemon(img) { + klog.Infof("%s exists in daemon, skipping load", img) + finalImg = img + return nil + } + } + klog.Infof("Downloading %s to local cache", img) err = download.ImageToCache(img) if err == nil { @@ -141,14 +150,6 @@ func beginDownloadKicBaseImage(g *errgroup.Group, cc *config.ClusterConfig, down return err } - if driver.IsDocker(cc.Driver) { - if download.ImageExistsInDaemon(img) { - klog.Infof("%s exists in daemon, skipping load", img) - finalImg = img - return nil - } - } - if cc.Driver == driver.Podman { return fmt.Errorf("not yet implemented, see issue #8426") } From ec4dab338b9870c763567f4ca7c6c3483f9f0655 Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Thu, 17 Jun 2021 15:01:19 -0700 Subject: [PATCH 101/122] rename file for consistency --- .github/workflows/{docs.yaml => docs.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{docs.yaml => docs.yml} (100%) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yml similarity index 100% rename from .github/workflows/docs.yaml rename to .github/workflows/docs.yml From 92258d06d043f790362293b9882776e827b10034 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 17 Jun 2021 10:57:00 -0700 Subject: [PATCH 102/122] Remove uses of pkg/minikube/translate/translations.go --- Makefile | 55 ++++++++++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/Makefile b/Makefile index 0f320de213..0690e24366 100644 --- a/Makefile +++ b/Makefile @@ -74,8 +74,7 @@ GOLINT_GOGC ?= 100 GOLINT_OPTIONS = --timeout 7m \ --build-tags "${MINIKUBE_INTEGRATION_BUILD_TAGS}" \ --enable gofmt,goimports,gocritic,golint,gocyclo,misspell,nakedret,stylecheck,unconvert,unparam,dogsled \ - --exclude 'variable on range scope.*in function literal|ifElseChain' \ - --skip-files "pkg/minikube/translate/translations.go" + --exclude 'variable on range scope.*in function literal|ifElseChain' export GO111MODULE := on @@ -130,14 +129,15 @@ MINIKUBE_MARKDOWN_FILES := README.md CONTRIBUTING.md CHANGELOG.md MINIKUBE_BUILD_TAGS := MINIKUBE_INTEGRATION_BUILD_TAGS := integration $(MINIKUBE_BUILD_TAGS) -CMD_SOURCE_DIRS = cmd pkg deploy/addons +CMD_SOURCE_DIRS = cmd pkg deploy/addons translations SOURCE_DIRS = $(CMD_SOURCE_DIRS) test -SOURCE_PACKAGES = ./cmd/... ./pkg/... ./deploy/addons/... ./test/... +SOURCE_PACKAGES = ./cmd/... ./pkg/... ./deploy/addons/... ./translations/... ./test/... -SOURCE_GENERATED = pkg/minikube/translate/translations.go SOURCE_FILES = $(shell find $(CMD_SOURCE_DIRS) -type f -name "*.go" | grep -v _test.go) GOTEST_FILES = $(shell find $(CMD_SOURCE_DIRS) -type f -name "*.go" | grep _test.go) ADDON_FILES = $(shell find "deploy/addons" -type f | grep -v "\.go") +TRANSLATION_FILES = $(shell find "translations" -type f | grep -v "\.go") +ASSET_FILES = $(ADDON_FILES) $(TRANSLATION_FILES) # kvm2 ldflags KVM2_LDFLAGS := -X k8s.io/minikube/pkg/drivers/kvm.version=$(VERSION) -X k8s.io/minikube/pkg/drivers/kvm.gitCommitID=$(COMMIT) @@ -196,7 +196,7 @@ ifneq ($(TEST_FILES),) INTEGRATION_TESTS_TO_RUN := $(addprefix ./test/integration/, $(TEST_HELPERS) $(TEST_FILES)) endif -out/minikube$(IS_EXE): $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) go.mod +out/minikube$(IS_EXE): $(SOURCE_FILES) $(ASSET_FILES) go.mod ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) $(call DOCKER,$(BUILD_IMAGE),GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) /usr/bin/make $@) else @@ -245,7 +245,7 @@ minikube-windows-amd64.exe: out/minikube-windows-amd64.exe ## Build Minikube for eq = $(and $(findstring x$(1),x$(2)),$(findstring x$(2),x$(1))) -out/minikube-%: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) +out/minikube-%: $(SOURCE_FILES) $(ASSET_FILES) ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) $(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@) else @@ -254,7 +254,7 @@ else go build -tags "$(MINIKUBE_BUILD_TAGS)" -ldflags="$(MINIKUBE_LDFLAGS)" -a -o $@ k8s.io/minikube/cmd/minikube endif -out/minikube-linux-armv6: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) +out/minikube-linux-armv6: $(SOURCE_FILES) $(ASSET_FILES) $(Q)GOOS=linux GOARCH=arm GOARM=6 \ go build -tags "$(MINIKUBE_BUILD_TAGS)" -ldflags="$(MINIKUBE_LDFLAGS)" -a -o $@ k8s.io/minikube/cmd/minikube @@ -311,11 +311,11 @@ iso_in_docker: --user $(shell id -u):$(shell id -g) --env HOME=/tmp --env IN_DOCKER=1 \ $(ISO_BUILD_IMAGE) /bin/bash -test-iso: $(SOURCE_GENERATED) +test-iso: go test -v $(INTEGRATION_TESTS_TO_RUN) --tags=iso --minikube-start-args="--iso-url=file://$(shell pwd)/out/buildroot/output/images/rootfs.iso9660" .PHONY: test-pkg -test-pkg/%: $(SOURCE_GENERATED) ## Trigger packaging test +test-pkg/%: ## Trigger packaging test go test -v -test.timeout=60m ./$* --tags="$(MINIKUBE_BUILD_TAGS)" .PHONY: all @@ -365,7 +365,7 @@ else endif .PHONY: test -test: $(SOURCE_GENERATED) ## Trigger minikube test +test: ## Trigger minikube test MINIKUBE_LDFLAGS="${MINIKUBE_LDFLAGS}" ./test.sh .PHONY: generate-docs @@ -373,7 +373,7 @@ generate-docs: extract out/minikube ## Automatically generate commands documenta out/minikube generate-docs --path ./site/content/en/docs/commands/ --test-path ./site/content/en/docs/contrib/tests.en.md --code-path ./site/content/en/docs/contrib/errorcodes.en.md .PHONY: gotest -gotest: $(SOURCE_GENERATED) ## Trigger minikube test +gotest: ## Trigger minikube test $(if $(quiet),@echo " TEST $@") $(Q)go test -tags "$(MINIKUBE_BUILD_TAGS)" -ldflags="$(MINIKUBE_LDFLAGS)" $(MINIKUBE_TEST_FILES) @@ -398,17 +398,6 @@ out/coverage.html: out/coverage.out extract: ## extract internationalization words for translations go run cmd/extract/extract.go -pkg/minikube/translate/translations.go: $(shell find "translations/" -type f) -ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) - $(call DOCKER,$(BUILD_IMAGE),/usr/bin/make $@) -endif - @which go-bindata >/dev/null 2>&1 || GO111MODULE=off GOBIN="$(GOPATH)$(DIRSEP)bin" go get github.com/go-bindata/go-bindata/... - $(if $(quiet),@echo " GEN $@") - $(Q)PATH="$(PATH)$(PATHSEP)$(GOPATH)$(DIRSEP)bin" go-bindata -nomemcopy -o $@ -pkg translate translations/... - $(Q)-gofmt -s -w $@ - @#golint: Json should be JSON (compat sed) - @sed -i -e 's/Json/JSON/' $@ && rm -f ./-e - .PHONY: cross cross: minikube-linux-amd64 minikube-darwin-amd64 minikube-windows-amd64.exe ## Build minikube for all platform @@ -475,7 +464,7 @@ goimports: ## Run goimports and list the files differs from goimport's @test -z "`goimports -l $(SOURCE_DIRS)`" .PHONY: golint -golint: $(SOURCE_GENERATED) ## Run golint +golint: ## Run golint @golint -set_exit_status $(SOURCE_PACKAGES) .PHONY: gocyclo @@ -490,17 +479,17 @@ out/linters/golangci-lint-$(GOLINT_VERSION): # this one is meant for local use .PHONY: lint ifeq ($(MINIKUBE_BUILD_IN_DOCKER),y) -lint: $(SOURCE_GENERATED) +lint: docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:$(GOLINT_VERSION) \ golangci-lint run ${GOLINT_OPTIONS} --skip-dirs "cmd/drivers/kvm|cmd/drivers/hyperkit|pkg/drivers/kvm|pkg/drivers/hyperkit" ./... else -lint: $(SOURCE_GENERATED) out/linters/golangci-lint-$(GOLINT_VERSION) ## Run lint +lint: out/linters/golangci-lint-$(GOLINT_VERSION) ## Run lint ./out/linters/golangci-lint-$(GOLINT_VERSION) run ${GOLINT_OPTIONS} ./... endif # lint-ci is slower version of lint and is meant to be used in ci (travis) to avoid out of memory leaks. .PHONY: lint-ci -lint-ci: $(SOURCE_GENERATED) out/linters/golangci-lint-$(GOLINT_VERSION) ## Run lint-ci +lint-ci: out/linters/golangci-lint-$(GOLINT_VERSION) ## Run lint-ci GOGC=${GOLINT_GOGC} ./out/linters/golangci-lint-$(GOLINT_VERSION) run \ --concurrency ${GOLINT_JOBS} ${GOLINT_OPTIONS} ./... @@ -518,7 +507,7 @@ mdlint: verify-iso: # Make sure the current ISO exists in the expected bucket gsutil stat gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION).iso -out/docs/minikube.md: $(shell find "cmd") $(shell find "pkg/minikube/constants") $(SOURCE_GENERATED) +out/docs/minikube.md: $(shell find "cmd") $(shell find "pkg/minikube/constants") go run -ldflags="$(MINIKUBE_LDFLAGS)" -tags gendocs hack/help_text/gen_help_text.go @@ -647,7 +636,7 @@ release-hyperkit-driver: install-hyperkit-driver checksum ## Copy hyperkit using gsutil cp $(GOBIN)/docker-machine-driver-hyperkit.sha256 gs://minikube/drivers/hyperkit/$(VERSION)/ .PHONY: check-release -check-release: $(SOURCE_GENERATED) ## Execute go test +check-release: ## Execute go test go test -v ./deploy/minikube/release_sanity_test.go -tags=release buildroot-image: $(ISO_BUILD_IMAGE) # convenient alias to build the docker container @@ -753,7 +742,7 @@ endif docker push $(IMAGE) .PHONY: out/gvisor-addon -out/gvisor-addon: $(SOURCE_GENERATED) ## Build gvisor addon +out/gvisor-addon: ## Build gvisor addon $(if $(quiet),@echo " GO $@") $(Q)GOOS=linux CGO_ENABLED=0 go build -o $@ cmd/gvisor/gvisor.go @@ -882,16 +871,16 @@ out/mkcmp: GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $@ cmd/performance/mkcmp/main.go .PHONY: deploy/kicbase/auto-pause # auto pause binary to be used for kic image work around for not passing the whole repo as docker context -deploy/kicbase/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) +deploy/kicbase/auto-pause: $(SOURCE_FILES) $(ASSET_FILES) GOOS=linux GOARCH=$(GOARCH) go build -o $@ cmd/auto-pause/auto-pause.go # auto pause binary to be used for ISO -deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/usr/bin/auto-pause: $(SOURCE_GENERATED) $(SOURCE_FILES) $(ADDON_FILES) +deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/usr/bin/auto-pause: $(SOURCE_FILES) $(ASSET_FILES) GOOS=linux GOARCH=$(GOARCH) go build -o $@ cmd/auto-pause/auto-pause.go .PHONY: deploy/addons/auto-pause/auto-pause-hook -deploy/addons/auto-pause/auto-pause-hook: $(SOURCE_GENERATED) ## Build auto-pause hook addon +deploy/addons/auto-pause/auto-pause-hook: ## Build auto-pause hook addon $(if $(quiet),@echo " GO $@") $(Q)GOOS=linux CGO_ENABLED=0 go build -a --ldflags '-extldflags "-static"' -tags netgo -installsuffix netgo -o $@ cmd/auto-pause/auto-pause-hook/main.go cmd/auto-pause/auto-pause-hook/config.go cmd/auto-pause/auto-pause-hook/certs.go From 770d348e30c2406208006512f59f9097dca827b1 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 17 Jun 2021 11:27:44 -0700 Subject: [PATCH 103/122] Use goembed for translations. --- pkg/minikube/translate/translate.go | 5 +++-- translations/translations.go | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 translations/translations.go diff --git a/pkg/minikube/translate/translate.go b/pkg/minikube/translate/translate.go index 892450e604..9cae7bc053 100644 --- a/pkg/minikube/translate/translate.go +++ b/pkg/minikube/translate/translate.go @@ -26,6 +26,7 @@ import ( "golang.org/x/text/language" "k8s.io/klog/v2" + "k8s.io/minikube/translations" ) var ( @@ -70,13 +71,13 @@ func DetermineLocale() { // Load translations for preferred language into memory. p := preferredLanguage.String() translationFile := path.Join("translations", fmt.Sprintf("%s.json", p)) - t, err := Asset(translationFile) + t, err := translations.Translations.ReadFile(translationFile) if err != nil { // Attempt to find a more broad locale, e.g. fr instead of fr-FR. if strings.Contains(p, "-") { p = strings.Split(p, "-")[0] translationFile := path.Join("translations", fmt.Sprintf("%s.json", p)) - t, err = Asset(translationFile) + t, err = translations.Translations.ReadFile(translationFile) if err != nil { klog.V(1).Infof("Failed to load translation file for %s: %v", p, err) return diff --git a/translations/translations.go b/translations/translations.go new file mode 100644 index 0000000000..2407a74dc2 --- /dev/null +++ b/translations/translations.go @@ -0,0 +1,23 @@ +/* +Copyright 2021 The Kubernetes Authors All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package translations + +import "embed" + +// Translations contains all translation JSON files. +//go:embed *.json +var Translations embed.FS From c61550e96732682e0d32bc62fe4d5c8ea61ba782 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Thu, 17 Jun 2021 11:28:07 -0700 Subject: [PATCH 104/122] Remove translations.go from .gitignore. --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 951196710e..cf6f99bc49 100644 --- a/.gitignore +++ b/.gitignore @@ -35,8 +35,6 @@ _testmain.go #iso version file deploy/iso/minikube-iso/board/coreos/minikube/rootfs-overlay/etc/VERSION -/pkg/minikube/translate/translations.go -/pkg/minikube/translate/translations.go-e /minikube .DS_Store From 51564f8f941106b2ef4f314ecac053d06018ba62 Mon Sep 17 00:00:00 2001 From: Peixuan Ding Date: Thu, 17 Jun 2021 20:56:21 -0400 Subject: [PATCH 105/122] Changed minimum required Go version to 1.16 in docs --- site/content/en/docs/contrib/building/binaries.md | 2 +- site/content/en/docs/contrib/building/iso.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/en/docs/contrib/building/binaries.md b/site/content/en/docs/contrib/building/binaries.md index ade5f54f99..6254844a10 100644 --- a/site/content/en/docs/contrib/building/binaries.md +++ b/site/content/en/docs/contrib/building/binaries.md @@ -7,7 +7,7 @@ weight: 2 ## Prerequisites -* A recent Go distribution (>=1.12) +* A recent Go distribution (>=1.16) * If you are on Windows, you'll need Docker to be installed. * 4GB of RAM diff --git a/site/content/en/docs/contrib/building/iso.md b/site/content/en/docs/contrib/building/iso.md index 8fd818bd38..f739aef819 100644 --- a/site/content/en/docs/contrib/building/iso.md +++ b/site/content/en/docs/contrib/building/iso.md @@ -10,7 +10,7 @@ The minikube ISO is booted by each hypervisor to provide a stable minimal Linux ## Prerequisites -* A recent Go distribution (>=1.12) +* A recent Go distribution (>=1.16) * If you are on Windows, you'll need Docker to be installed. * 4GB of RAM * Build tools: From ab51f6fb70882c6f6ac615db96a614a2fbf4b89e Mon Sep 17 00:00:00 2001 From: Ilya Zuyev Date: Thu, 17 Jun 2021 19:57:25 -0700 Subject: [PATCH 106/122] Fix intersected log boxes when running with --alsologtostderr --- pkg/minikube/out/out.go | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pkg/minikube/out/out.go b/pkg/minikube/out/out.go index 2f449691c8..f2f6f8bc2f 100644 --- a/pkg/minikube/out/out.go +++ b/pkg/minikube/out/out.go @@ -114,17 +114,12 @@ func Styled(st style.Enum, format string, a ...V) { } func boxedCommon(printFunc func(format string, a ...interface{}), format string, a ...V) { - str := Sprintf(style.None, format, a...) - str = strings.TrimSpace(str) box := box.New(box.Config{Py: 1, Px: 4, Type: "Round"}) if useColor { box.Config.Color = "Red" } - str = box.String("", str) - lines := strings.Split(str, "\n") - for _, line := range lines { - printFunc(line + "\n") - } + str := Sprintf(style.None, format, a...) + printFunc(box.String("", strings.TrimSpace(str))) } // Boxed writes a stylized and templated message in a box to stdout From d5d55290bf353b0e7efeb3c0e728a9a012d4077d Mon Sep 17 00:00:00 2001 From: Peixuan Ding Date: Fri, 18 Jun 2021 01:21:02 -0400 Subject: [PATCH 107/122] Add proposal for tips Signed-off-by: Peixuan Ding --- enhancements/proposed/20210618-tips/tips.md | 215 ++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 enhancements/proposed/20210618-tips/tips.md diff --git a/enhancements/proposed/20210618-tips/tips.md b/enhancements/proposed/20210618-tips/tips.md new file mode 100644 index 0000000000..5abb6f3b80 --- /dev/null +++ b/enhancements/proposed/20210618-tips/tips.md @@ -0,0 +1,215 @@ +# Periodically tell user about minikube features/tips and tricks + +* First proposed: 2021-06-18 +* Authors: Peixuan Ding (@dinever) + +## Reviewer Priorities + +Please review this proposal with the following priorities: + +* Does this fit with minikube's [principles](https://minikube.sigs.k8s.io/docs/concepts/principles/)? +* Are there other approaches to consider? +* Could the implementation be made simpler? +* Are there usability, reliability, or technical debt concerns? + +Please leave the above text in your proposal as instructions to the reader. + +## Summary + +minikube has lots of great features. We want to proactively remind users that +those features are available. + +To achieve this, we can have a tips feature that randomly shows a tip +from a curated list whenever the user starts a new minikube profile. + +For example: + +![Screenshot from 2021-06-18 00-58-02](https://user-images.githubusercontent.com/1311594/122508665-53bd6380-cfd0-11eb-9e99-a6c5935514d5.png) + +## Goals + +* Store a list of tips in a static file +* Show a random minikube usage tip each time a user starts a minikube profile +* Have the tips synced to the Hugo docs website to make those available through docs +* Allow user to disable the Tips feature with minikube config + +## Non-Goals + +* Modify any existing functionalities or docs + +## Design Details + +First, we need a static file to store all the tips, we can have a YAML file at [pkg/generate/tips/tips.yaml](https://github.com/kubernetes/minikube/tree/master/pkg/generate): + +```YAML +tips: + - | + You can specify any Kubernetes version you want. For example: + + ``` + minikube start --kubernetes-version=v1.19.0 + ``` + - | + You can use minikube's built-in kubectl. For example: + + ``` + minikube kubectl -- get pods + ``` + - | + minikube has the built-in Kubernetes Dashboard UI. To access it: + + ``` + minikube dashboard + ``` +``` + +Use `goembed` to embed this file into the minikube binary. + +The current `out.Boxed` has a hard-coded style (red). I propose to add another `out.BoxedWithConfig` method to allow +output with customized style: + +```go +type BoxConfig struct { + // box.Config is the config struct of box-cli-maker + box.Config + // Title is a text that shows as a header of the box + Title string + // Icon is the optional emoji we want to show as a prefix for the title + Icon style.Enum +} + +// BoxedWithConfig writes a templated message in a box with customized style config to stdout +func BoxedWithConfig(cfg BoxConfig, format string, a ...V) { + boxedCommon(String, cfg, format, a...) +} +``` + +Whenever minikube successfully starts, we randomly choose a tip. + +Before printing it out, we need to do some regex replacement to strip the markdown syntax +for better view experience in Terminal: + +From this: + +``````markdown +You can specify any Kubernetes version you want. For example: + +``` +minikube start --kubernetes-version=v1.19.0 +``` +`````` + +To this: + +```markdown +You can specify any Kubernetes version you want. For example: + +minikube start --kubernetes-version=v1.19.0 +``` + +Then we can print out the tip: + + +```go +boxCfg := out.BoxConfig{ + Config: box.Config{ + Py: 1, + Px: 5, + TitlePos: "Top", + Type: "Round", + Color: tipBoxColor, + }, + Title: tipTitle, + Icon: style.Tip, +} + +out.BoxedWithConfig(boxCfg, tips.Tips[chosen] + "\n\n" + tipSuffix) +``` + +![Screenshot from 2021-06-18 00-58-02](https://user-images.githubusercontent.com/1311594/122508665-53bd6380-cfd0-11eb-9e99-a6c5935514d5.png) + +User can choose to disable this through `minikube config set disable-tips true` + +We will have `make generate-docs` generating the docs site based on this YAML file as well. + +We can have a `Nice to know` sub-page under `FAQ`? + +![Screenshot from 2021-06-18 01-00-30](https://user-images.githubusercontent.com/1311594/122508827-a139d080-cfd0-11eb-98bb-f7c3c1c604c2.png) + + +### About the tip collection + +I plan to start with the command lines and cover almost all CLI usages of minikube. + +That includes but not limited to: +- addons +- cached images +- command line completion +- config +- file copy +- dashboard +- delete minikube cluster +- configure minikube's docker/podman env +- image build / load / ls / rm +- ip +- logging +- kubectl +- mount file directory +- multi-node +- pause/unpause to save resource +- multi-profile +- surface URL to a k8s service +- ssh into minikube +- status +- tunnel to connect to LB +- update-check to check versions +- update-context + +### Implementation + +I plan to open at least 4 PRs: + +1. `out.Boxed` with custom style +2. random `tips` display with ability to disable through config, with an initial set of about 10 tips +3. `make generate-docs` to sync tips to docs +4. Add more tips + +## Alternatives Considered + +1. Is there a more preferred file format to YAML? + +2. Maybe we just want to sync the tips to the `FAQ` page list instead of creating a new page? + +3. Instead of the file format I proposed, maybe add a `question` field? + + ```yaml + tips: + - question: How to specify a different Kubernetes version? + answer: | + You can specify any Kubernetes version you want. For example: + + ``` + minikube start --kubernetes-version=v1.19.0 + ``` + - question: Do I have to install `kubectl` myself? + answer: | + You can use minikube's built-in kubectl. For example: + + ``` + minikube kubectl -- get pods + ``` + - question: How do I access the Kubernetes Dashboard UI? + answer: | + minikube has the built-in Kubernetes Dashboard UI. To access it: + + ``` + minikube dashboard + ``` + ``` + + On the docs side we should both questions and answers. On the CLI side + we can either show both questions and answers, or just show the answers + to make it more compact + + ![Screenshot from 2021-06-18 01-25-54](https://user-images.githubusercontent.com/1311594/122510785-2c689580-cfd4-11eb-9fd0-0a0ff344e3cc.png) + From 6d346e0b803ed39bf534b4759e567d88eab361f2 Mon Sep 17 00:00:00 2001 From: Peixuan Ding Date: Fri, 18 Jun 2021 09:24:42 -0400 Subject: [PATCH 108/122] Remove Hugo workaround for go1.16 --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0f320de213..ca348ac709 100644 --- a/Makefile +++ b/Makefile @@ -866,8 +866,7 @@ site/themes/docsy/assets/vendor/bootstrap/package.js: ## update the website docs out/hugo/hugo: mkdir -p out test -d out/hugo || git clone https://github.com/gohugoio/hugo.git out/hugo - go get golang.org/dl/go1.16 && go1.16 download - (cd out/hugo && go1.16 build --tags extended) + (cd out/hugo && go build --tags extended) .PHONY: site site: site/themes/docsy/assets/vendor/bootstrap/package.js out/hugo/hugo ## Serve the documentation site to localhost From cd1adcf35dda128dc2aa0a85e73acfd8b173fe73 Mon Sep 17 00:00:00 2001 From: Daehyeok Mun Date: Tue, 15 Jun 2021 22:18:17 -0700 Subject: [PATCH 109/122] Remove unused config options --- cmd/minikube/cmd/config/config.go | 20 -------------------- cmd/minikube/cmd/root.go | 5 ----- pkg/minikube/config/config.go | 10 ---------- site/content/en/docs/commands/config.md | 5 ----- 4 files changed, 40 deletions(-) diff --git a/cmd/minikube/cmd/config/config.go b/cmd/minikube/cmd/config/config.go index 8ef3630915..0751f52e77 100644 --- a/cmd/minikube/cmd/config/config.go +++ b/cmd/minikube/cmd/config/config.go @@ -122,18 +122,6 @@ var settings = []Setting{ name: config.ReminderWaitPeriodInHours, set: SetInt, }, - { - name: config.WantReportError, - set: SetBool, - }, - { - name: config.WantReportErrorPrompt, - set: SetBool, - }, - { - name: config.WantKubectlDownloadMsg, - set: SetBool, - }, { name: config.WantNoneDriverWarning, set: SetBool, @@ -146,14 +134,6 @@ var settings = []Setting{ name: Bootstrapper, set: SetString, }, - { - name: config.ShowDriverDeprecationNotification, - set: SetBool, - }, - { - name: config.ShowBootstrapperDeprecationNotification, - set: SetBool, - }, { name: "insecure-registry", set: SetString, diff --git a/cmd/minikube/cmd/root.go b/cmd/minikube/cmd/root.go index 5b81138d82..63753c3755 100644 --- a/cmd/minikube/cmd/root.go +++ b/cmd/minikube/cmd/root.go @@ -303,12 +303,7 @@ func setupViper() { viper.SetDefault(config.WantUpdateNotification, true) viper.SetDefault(config.ReminderWaitPeriodInHours, 24) - viper.SetDefault(config.WantReportError, false) - viper.SetDefault(config.WantReportErrorPrompt, true) - viper.SetDefault(config.WantKubectlDownloadMsg, true) viper.SetDefault(config.WantNoneDriverWarning, true) - viper.SetDefault(config.ShowDriverDeprecationNotification, true) - viper.SetDefault(config.ShowBootstrapperDeprecationNotification, true) } func addToPath(dir string) { diff --git a/pkg/minikube/config/config.go b/pkg/minikube/config/config.go index f194099266..9b76d84451 100644 --- a/pkg/minikube/config/config.go +++ b/pkg/minikube/config/config.go @@ -36,20 +36,10 @@ const ( WantBetaUpdateNotification = "WantBetaUpdateNotification" // ReminderWaitPeriodInHours is the key for ReminderWaitPeriodInHours ReminderWaitPeriodInHours = "ReminderWaitPeriodInHours" - // WantReportError is the key for WantReportError - WantReportError = "WantReportError" - // WantReportErrorPrompt is the key for WantReportErrorPrompt - WantReportErrorPrompt = "WantReportErrorPrompt" - // WantKubectlDownloadMsg is the key for WantKubectlDownloadMsg - WantKubectlDownloadMsg = "WantKubectlDownloadMsg" // WantNoneDriverWarning is the key for WantNoneDriverWarning WantNoneDriverWarning = "WantNoneDriverWarning" // ProfileName represents the key for the global profile parameter ProfileName = "profile" - // ShowDriverDeprecationNotification is the key for ShowDriverDeprecationNotification - ShowDriverDeprecationNotification = "ShowDriverDeprecationNotification" - // ShowBootstrapperDeprecationNotification is the key for ShowBootstrapperDeprecationNotification - ShowBootstrapperDeprecationNotification = "ShowBootstrapperDeprecationNotification" // UserFlag is the key for the global user flag (ex. --user=user1) UserFlag = "user" // AddonImages stores custom addon images config diff --git a/site/content/en/docs/commands/config.md b/site/content/en/docs/commands/config.md index 51ff431b20..44b3bb0716 100644 --- a/site/content/en/docs/commands/config.md +++ b/site/content/en/docs/commands/config.md @@ -29,14 +29,9 @@ Configurable fields: * WantUpdateNotification * WantBetaUpdateNotification * ReminderWaitPeriodInHours - * WantReportError - * WantReportErrorPrompt - * WantKubectlDownloadMsg * WantNoneDriverWarning * profile * bootstrapper - * ShowDriverDeprecationNotification - * ShowBootstrapperDeprecationNotification * insecure-registry * hyperv-virtual-switch * disable-driver-mounts From fa7c151fdb067fc79f428df99e3f4f9235f27f7f Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Fri, 18 Jun 2021 09:15:06 -0700 Subject: [PATCH 110/122] Fix translations not looking for correct file. --- pkg/minikube/translate/translate.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/minikube/translate/translate.go b/pkg/minikube/translate/translate.go index 9cae7bc053..2605870cd5 100644 --- a/pkg/minikube/translate/translate.go +++ b/pkg/minikube/translate/translate.go @@ -19,7 +19,6 @@ package translate import ( "encoding/json" "fmt" - "path" "strings" "github.com/cloudfoundry-attic/jibber_jabber" @@ -70,14 +69,12 @@ func DetermineLocale() { // Load translations for preferred language into memory. p := preferredLanguage.String() - translationFile := path.Join("translations", fmt.Sprintf("%s.json", p)) - t, err := translations.Translations.ReadFile(translationFile) + t, err := translations.Translations.ReadFile(fmt.Sprintf("%s.json", p)) if err != nil { // Attempt to find a more broad locale, e.g. fr instead of fr-FR. if strings.Contains(p, "-") { p = strings.Split(p, "-")[0] - translationFile := path.Join("translations", fmt.Sprintf("%s.json", p)) - t, err = translations.Translations.ReadFile(translationFile) + t, err = translations.Translations.ReadFile(fmt.Sprintf("%s.json", p)) if err != nil { klog.V(1).Infof("Failed to load translation file for %s: %v", p, err) return From d38f2f01498ca78c4dc1de69c85290da588d55b1 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Fri, 18 Jun 2021 09:55:58 -0700 Subject: [PATCH 111/122] Add functional test for ensuring international language is used. --- test/integration/functional_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go index 2616bf1535..a3c41bd4ef 100644 --- a/test/integration/functional_test.go +++ b/test/integration/functional_test.go @@ -116,6 +116,7 @@ func TestFunctional(t *testing.T) { {"ConfigCmd", validateConfigCmd}, {"DashboardCmd", validateDashboardCmd}, {"DryRun", validateDryRun}, + {"InternationalLanguage", validateInternationalLanguage}, {"StatusCmd", validateStatusCmd}, {"LogsCmd", validateLogsCmd}, {"LogsFileCmd", validateLogsFileCmd}, @@ -897,6 +898,32 @@ func validateDryRun(ctx context.Context, t *testing.T, profile string) { } } +// validateInternationalLanguage asserts that the language used can be changed with environment variables +func validateInternationalLanguage(ctx context.Context, t *testing.T, profile string) { + // dry-run mode should always be able to finish quickly (<5s) + mctx, cancel := context.WithTimeout(ctx, Seconds(5)) + defer cancel() + + // Too little memory! + startArgs := append([]string{"start", "-p", profile, "--dry-run", "--memory", "250MB", "--alsologtostderr"}, StartArgs()...) + c := exec.CommandContext(mctx, Target(), startArgs...) + c.Env = append(os.Environ(), "LC_ALL=fr") + + rr, err := Run(t, c) + + wantCode := reason.ExInsufficientMemory + if rr.ExitCode != wantCode { + if HyperVDriver() { + t.Skip("skipping this error on HyperV till this issue is solved https://github.com/kubernetes/minikube/issues/9785") + } else { + t.Errorf("dry-run(250MB) exit code = %d, wanted = %d: %v", rr.ExitCode, wantCode, err) + } + } + if !strings.Contains(rr.Stdout.String(), "Utilisation du pilote") { + t.Errorf("dry-run output was expected to be in French. Expected \"Utilisation du pilote\", but not present in output:\n%s", rr.Stdout.String()) + } +} + // validateCacheCmd tests functionality of cache command (cache add, delete, list) func validateCacheCmd(ctx context.Context, t *testing.T, profile string) { defer PostMortemLogs(t, profile) From ebb35cfdc6343197efd511a083b0d58b13eb4966 Mon Sep 17 00:00:00 2001 From: Andriy Dzikh Date: Fri, 18 Jun 2021 10:12:59 -0700 Subject: [PATCH 112/122] Run make generate-docs. --- site/content/en/docs/contrib/tests.en.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/site/content/en/docs/contrib/tests.en.md b/site/content/en/docs/contrib/tests.en.md index 47ea10dca5..67c78f1eca 100644 --- a/site/content/en/docs/contrib/tests.en.md +++ b/site/content/en/docs/contrib/tests.en.md @@ -130,6 +130,9 @@ asserts that the dashboard command works #### validateDryRun asserts that the dry-run mode quickly exits with the right code +#### validateInternationalLanguage +asserts that the language used can be changed with environment variables + #### validateCacheCmd tests functionality of cache command (cache add, delete, list) From 1200975bc78180e3ec705fe33ea5ce51bebf2bfd Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Fri, 18 Jun 2021 13:28:01 -0700 Subject: [PATCH 113/122] debug --- hack/generate_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/generate_docs.sh b/hack/generate_docs.sh index f8fcc16445..38e9685ecc 100755 --- a/hack/generate_docs.sh +++ b/hack/generate_docs.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -ex if [ "$#" -ne 1 ]; then # there's no secret and therefore no reason to run this script From 248942f830b1780cc9b99c179a1fc3b9b0ece31f Mon Sep 17 00:00:00 2001 From: Sharif Elgamal Date: Fri, 18 Jun 2021 13:46:30 -0700 Subject: [PATCH 114/122] move around check --- hack/generate_docs.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hack/generate_docs.sh b/hack/generate_docs.sh index 38e9685ecc..a116101fa1 100755 --- a/hack/generate_docs.sh +++ b/hack/generate_docs.sh @@ -36,7 +36,8 @@ config_git() { make generate-docs # If there are changes, open a PR -if ! git diff-index --quiet HEAD --; then +git diff-index --quiet HEAD -- +if [ $? -gt 0 ]; then install_gh $1 config_git From c8fb43220d2258b5f107662509309ef6697535d7 Mon Sep 17 00:00:00 2001 From: minikube-bot Date: Fri, 18 Jun 2021 13:56:02 -0700 Subject: [PATCH 115/122] remove exit on error --- hack/generate_docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/generate_docs.sh b/hack/generate_docs.sh index a116101fa1..c7ff38be05 100755 --- a/hack/generate_docs.sh +++ b/hack/generate_docs.sh @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -ex +set -x if [ "$#" -ne 1 ]; then # there's no secret and therefore no reason to run this script From 386561f694d2e052af7046ccd1886725baec676f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 19 Jun 2021 09:49:38 +0200 Subject: [PATCH 116/122] Upgrade podman to 3.1.2 --- deploy/iso/minikube-iso/package/podman/podman.hash | 1 + deploy/iso/minikube-iso/package/podman/podman.mk | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/deploy/iso/minikube-iso/package/podman/podman.hash b/deploy/iso/minikube-iso/package/podman/podman.hash index 4f5158b977..2d82781bac 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.hash +++ b/deploy/iso/minikube-iso/package/podman/podman.hash @@ -2,3 +2,4 @@ sha256 a16846fe076aaf2c9ea2e854c3baba9fb838d916be7fb4b5be332e6c92d907d4 v1.9.3.t sha256 5ebaa6e0dbd7fd1863f70d2bc71dc8a94e195c3339c17e3cac4560c9ec5747f8 v2.1.1.tar.gz sha256 ec5473e51fa28f29af323473fc484f742dc7df23d06d8ba9f217f13382893a71 v2.2.0.tar.gz sha256 3212bad60d945c1169b27da03959f36d92d1d8964645c701a5a82a89118e96d1 v2.2.1.tar.gz +sha256 5a0d42e03d15e32c5c54a147da5ef1b8928ec00982ac9e3f1edc82c5e614b6d2 v3.1.2.tar.gz diff --git a/deploy/iso/minikube-iso/package/podman/podman.mk b/deploy/iso/minikube-iso/package/podman/podman.mk index a2170ba395..ccc68876e5 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.mk +++ b/deploy/iso/minikube-iso/package/podman/podman.mk @@ -1,5 +1,5 @@ -PODMAN_VERSION = v2.2.1 -PODMAN_COMMIT = a0d478edea7f775b7ce32f8eb1a01e75374486cb +PODMAN_VERSION = v3.1.2 +PODMAN_COMMIT = 51b8ddbc22cf5b10dd76dd9243924aa66ad7db39 PODMAN_SITE = https://github.com/containers/podman/archive PODMAN_SOURCE = $(PODMAN_VERSION).tar.gz PODMAN_LICENSE = Apache-2.0 From c6c9cec51b2b0959a031bb355e86aef20c41d63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 19 Jun 2021 09:49:56 +0200 Subject: [PATCH 117/122] Stop using /etc/cni/net.d for podman network Kubernetes can't handle anything else using the same config directory, and doesn't have a method of choosing which cni. --- .../package/podman/containers.conf | 29 +++++++++++++++++++ .../iso/minikube-iso/package/podman/podman.mk | 7 +++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 deploy/iso/minikube-iso/package/podman/containers.conf diff --git a/deploy/iso/minikube-iso/package/podman/containers.conf b/deploy/iso/minikube-iso/package/podman/containers.conf new file mode 100644 index 0000000000..5374558935 --- /dev/null +++ b/deploy/iso/minikube-iso/package/podman/containers.conf @@ -0,0 +1,29 @@ +# The containers configuration file specifies all of the available configuration +# command-line options/flags for container engine tools like Podman & Buildah, +# but in a TOML format that can be easily modified and versioned. + +# Please refer to containers.conf(5) for details of all configuration options. +# Not all container engines implement all of the options. +# All of the options have hard coded defaults and these options will override +# the built in defaults. Users can then override these options via the command +# line. Container engines will read containers.conf files in up to three +# locations in the following order: +# 1. /usr/share/containers/containers.conf +# 2. /etc/containers/containers.conf +# 3. $HOME/.config/containers/containers.conf (Rootless containers ONLY) +# Items specified in the latter containers.conf, if they exist, override the +# previous containers.conf settings, or the default settings. + +[network] + +# Path to directory where CNI plugin binaries are located. +# +# cni_plugin_dirs = ["/usr/libexec/cni"] + +# The network name of the default CNI network to attach pods to. +# default_network = "podman" + +# Path to the directory where CNI configuration files are located. +# +# network_config_dir = "/etc/cni/net.d/" +network_config_dir = "/etc/containers/net.d/" diff --git a/deploy/iso/minikube-iso/package/podman/podman.mk b/deploy/iso/minikube-iso/package/podman/podman.mk index ccc68876e5..bef3e814fb 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.mk +++ b/deploy/iso/minikube-iso/package/podman/podman.mk @@ -47,8 +47,11 @@ endef define PODMAN_INSTALL_TARGET_CMDS $(INSTALL) -Dm755 $(@D)/bin/podman $(TARGET_DIR)/usr/bin/podman - $(INSTALL) -d -m 755 $(TARGET_DIR)/etc/cni/net.d/ - $(INSTALL) -m 644 $(@D)/cni/87-podman-bridge.conflist $(TARGET_DIR)/etc/cni/net.d/87-podman-bridge.conflist + # Don't use kubernetes /etc/cni, but use podman /etc/containers + $(INSTALL) -d -m 755 $(TARGET_DIR)/etc/containers/ + $(INSTALL) -m 644 $(PODMAN_PKGDIR)/containers.conf $(TARGET_DIR)/etc/containers/containers.conf + $(INSTALL) -d -m 755 $(TARGET_DIR)/etc/containers/net.d/ + $(INSTALL) -m 644 $(@D)/cni/87-podman-bridge.conflist $(TARGET_DIR)/etc/containers/net.d/87-podman-bridge.conflist endef define PODMAN_INSTALL_INIT_SYSTEMD From ab4cfc239d41bdde8727af646ae3c1defa84ada1 Mon Sep 17 00:00:00 2001 From: Medya Ghazizadeh Date: Mon, 21 Jun 2021 12:13:59 -0400 Subject: [PATCH 118/122] Revert "ISO: Upgrade podman to 3.1.2" --- .../package/podman/containers.conf | 29 ------------------- .../minikube-iso/package/podman/podman.hash | 1 - .../iso/minikube-iso/package/podman/podman.mk | 11 +++---- 3 files changed, 4 insertions(+), 37 deletions(-) delete mode 100644 deploy/iso/minikube-iso/package/podman/containers.conf diff --git a/deploy/iso/minikube-iso/package/podman/containers.conf b/deploy/iso/minikube-iso/package/podman/containers.conf deleted file mode 100644 index 5374558935..0000000000 --- a/deploy/iso/minikube-iso/package/podman/containers.conf +++ /dev/null @@ -1,29 +0,0 @@ -# The containers configuration file specifies all of the available configuration -# command-line options/flags for container engine tools like Podman & Buildah, -# but in a TOML format that can be easily modified and versioned. - -# Please refer to containers.conf(5) for details of all configuration options. -# Not all container engines implement all of the options. -# All of the options have hard coded defaults and these options will override -# the built in defaults. Users can then override these options via the command -# line. Container engines will read containers.conf files in up to three -# locations in the following order: -# 1. /usr/share/containers/containers.conf -# 2. /etc/containers/containers.conf -# 3. $HOME/.config/containers/containers.conf (Rootless containers ONLY) -# Items specified in the latter containers.conf, if they exist, override the -# previous containers.conf settings, or the default settings. - -[network] - -# Path to directory where CNI plugin binaries are located. -# -# cni_plugin_dirs = ["/usr/libexec/cni"] - -# The network name of the default CNI network to attach pods to. -# default_network = "podman" - -# Path to the directory where CNI configuration files are located. -# -# network_config_dir = "/etc/cni/net.d/" -network_config_dir = "/etc/containers/net.d/" diff --git a/deploy/iso/minikube-iso/package/podman/podman.hash b/deploy/iso/minikube-iso/package/podman/podman.hash index 2d82781bac..4f5158b977 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.hash +++ b/deploy/iso/minikube-iso/package/podman/podman.hash @@ -2,4 +2,3 @@ sha256 a16846fe076aaf2c9ea2e854c3baba9fb838d916be7fb4b5be332e6c92d907d4 v1.9.3.t sha256 5ebaa6e0dbd7fd1863f70d2bc71dc8a94e195c3339c17e3cac4560c9ec5747f8 v2.1.1.tar.gz sha256 ec5473e51fa28f29af323473fc484f742dc7df23d06d8ba9f217f13382893a71 v2.2.0.tar.gz sha256 3212bad60d945c1169b27da03959f36d92d1d8964645c701a5a82a89118e96d1 v2.2.1.tar.gz -sha256 5a0d42e03d15e32c5c54a147da5ef1b8928ec00982ac9e3f1edc82c5e614b6d2 v3.1.2.tar.gz diff --git a/deploy/iso/minikube-iso/package/podman/podman.mk b/deploy/iso/minikube-iso/package/podman/podman.mk index bef3e814fb..a2170ba395 100644 --- a/deploy/iso/minikube-iso/package/podman/podman.mk +++ b/deploy/iso/minikube-iso/package/podman/podman.mk @@ -1,5 +1,5 @@ -PODMAN_VERSION = v3.1.2 -PODMAN_COMMIT = 51b8ddbc22cf5b10dd76dd9243924aa66ad7db39 +PODMAN_VERSION = v2.2.1 +PODMAN_COMMIT = a0d478edea7f775b7ce32f8eb1a01e75374486cb PODMAN_SITE = https://github.com/containers/podman/archive PODMAN_SOURCE = $(PODMAN_VERSION).tar.gz PODMAN_LICENSE = Apache-2.0 @@ -47,11 +47,8 @@ endef define PODMAN_INSTALL_TARGET_CMDS $(INSTALL) -Dm755 $(@D)/bin/podman $(TARGET_DIR)/usr/bin/podman - # Don't use kubernetes /etc/cni, but use podman /etc/containers - $(INSTALL) -d -m 755 $(TARGET_DIR)/etc/containers/ - $(INSTALL) -m 644 $(PODMAN_PKGDIR)/containers.conf $(TARGET_DIR)/etc/containers/containers.conf - $(INSTALL) -d -m 755 $(TARGET_DIR)/etc/containers/net.d/ - $(INSTALL) -m 644 $(@D)/cni/87-podman-bridge.conflist $(TARGET_DIR)/etc/containers/net.d/87-podman-bridge.conflist + $(INSTALL) -d -m 755 $(TARGET_DIR)/etc/cni/net.d/ + $(INSTALL) -m 644 $(@D)/cni/87-podman-bridge.conflist $(TARGET_DIR)/etc/cni/net.d/87-podman-bridge.conflist endef define PODMAN_INSTALL_INIT_SYSTEMD From 33d3c75f1397661c628e2b375dac0a5140b4de5f Mon Sep 17 00:00:00 2001 From: Peixuan Ding Date: Mon, 21 Jun 2021 12:27:51 -0400 Subject: [PATCH 119/122] Fix typo and update details --- enhancements/proposed/20210618-tips/tips.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/enhancements/proposed/20210618-tips/tips.md b/enhancements/proposed/20210618-tips/tips.md index 5abb6f3b80..a42d21c59b 100644 --- a/enhancements/proposed/20210618-tips/tips.md +++ b/enhancements/proposed/20210618-tips/tips.md @@ -69,18 +69,8 @@ The current `out.Boxed` has a hard-coded style (red). I propose to add another ` output with customized style: ```go -type BoxConfig struct { - // box.Config is the config struct of box-cli-maker - box.Config - // Title is a text that shows as a header of the box - Title string - // Icon is the optional emoji we want to show as a prefix for the title - Icon style.Enum -} - // BoxedWithConfig writes a templated message in a box with customized style config to stdout -func BoxedWithConfig(cfg BoxConfig, format string, a ...V) { - boxedCommon(String, cfg, format, a...) +func BoxedWithConfig(cfg box.Config, st style.Enum, title string, format string, a ...V) { } ``` @@ -207,9 +197,9 @@ I plan to open at least 4 PRs: ``` ``` - On the docs side we should both questions and answers. On the CLI side + On the docs side we can show both questions and answers. On the CLI side we can either show both questions and answers, or just show the answers - to make it more compact + to make it more compact. ![Screenshot from 2021-06-18 01-25-54](https://user-images.githubusercontent.com/1311594/122510785-2c689580-cfd4-11eb-9fd0-0a0ff344e3cc.png) From caed7715a1ad89c14e028097ae3f33d35b65f8ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 18:25:50 +0000 Subject: [PATCH 120/122] Bump github.com/spf13/viper from 1.7.1 to 1.8.0 Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.7.1 to 1.8.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.7.1...v1.8.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 55 +++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 72a311e546..0c043f9848 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/shirou/gopsutil/v3 v3.21.5 github.com/spf13/cobra v1.1.3 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.7.1 + github.com/spf13/viper v1.8.0 github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097 go.opencensus.io v0.23.0 diff --git a/go.sum b/go.sum index de7f56d87e..a97d699e71 100644 --- a/go.sum +++ b/go.sum @@ -67,7 +67,6 @@ github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocm github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Delta456/box-cli-maker/v2 v2.2.1 h1:uTcuvT6Ty+LBHuRUdFrJBpqP9RhtLxI5+5ZpKYAUuVw= @@ -125,6 +124,7 @@ github.com/alonyb/spinner v1.12.7 h1:FflTMA9I2xRd8OQ5swyZY6Q1DFeaicA/bWo6/oM82a8 github.com/alonyb/spinner v1.12.7/go.mod h1:mQak9GHqbspjC/5iUx3qMlIho8xBS/ppAL/hX5SmPJU= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -149,6 +149,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -270,6 +271,7 @@ github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -422,6 +424,7 @@ github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblf github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -550,6 +553,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -627,8 +631,9 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -670,6 +675,7 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -699,8 +705,9 @@ github.com/machine-drivers/docker-machine-driver-vmware v0.1.3/go.mod h1:p2hY99U github.com/machine-drivers/machine v0.7.1-0.20210306082426-fcb2ad5bcb17 h1:fQoDTuCuJ30R+D6TSB9SALB+J3jUMa8ID8YPfmSDA20= github.com/machine-drivers/machine v0.7.1-0.20210306082426-fcb2ad5bcb17/go.mod h1:79Uwa2hGd5S39LDJt58s8JZcIhGEK6pkq9bsuTbFWbk= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -754,8 +761,9 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/hyperkit v0.0.0-20210108224842-2f061e447e14 h1:XGy4iMfaG4r1uZKZQmEPSYSH0Nj5JJuKgPNUhWGQ08E= github.com/moby/hyperkit v0.0.0-20210108224842-2f061e447e14/go.mod h1:aBcAEoy5u01cPAYvosR85gzSrMZ0TVVnkPytOQN+9z8= @@ -842,8 +850,9 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= @@ -859,6 +868,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v0.0.0-20161223203901-3a8809bd8a80 h1:DQFOykp5w+HOykOMzd2yOX5P6ty58Ggiu2rthHgcNQg= github.com/pkg/profile v0.0.0-20161223203901-3a8809bd8a80/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -904,6 +914,7 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= @@ -944,10 +955,12 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= @@ -965,8 +978,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.0 h1:QRwDgoG8xX+kp69di68D+YYTCWfYEckbZRfUlEIAal0= +github.com/spf13/viper v1.8.0/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1039,6 +1052,9 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -1062,12 +1078,15 @@ go.opentelemetry.io/otel/sdk v0.16.0/go.mod h1:Jb0B4wrxerxtBeapvstmAZvJGQmvah4dH go.opentelemetry.io/otel/trace v0.17.0 h1:SBOj64/GAOyWzs5F680yW1ITIfJkm6cJWL2YAvuL9xY= go.opentelemetry.io/otel/trace v0.17.0/go.mod h1:bIujpqg6ZL6xUTubIUgziI1jSaUPthmabA/ygf/6Cfg= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190927031335-2835ba2e683f h1:hXVePvSFG7tPGX4Pwk1d10ePFfoTCc0QmISfpKOHsS8= golang.org/x/build v0.0.0-20190927031335-2835ba2e683f/go.mod h1:fYw7AShPAhGMdXqA9gRadk/CcMsvLlClpE5oBwnS3dM= @@ -1087,6 +1106,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1211,6 +1231,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -1447,6 +1468,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0 h1:RDAPWfNFY06dffEXfn7hZF5Fr1ZbnChzfQZAPyBd1+I= @@ -1485,6 +1507,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1530,6 +1553,7 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= @@ -1571,8 +1595,9 @@ gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= @@ -1586,6 +1611,7 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1593,8 +1619,9 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= From dae5d1efb13a0e9a41c082fc13ba2feb3e1e5a7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Jun 2021 19:18:33 +0000 Subject: [PATCH 121/122] Bump github.com/hashicorp/go-getter from 1.5.2 to 1.5.4 Bumps [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) from 1.5.2 to 1.5.4. - [Release notes](https://github.com/hashicorp/go-getter/releases) - [Changelog](https://github.com/hashicorp/go-getter/blob/main/.goreleaser.yml) - [Commits](https://github.com/hashicorp/go-getter/compare/v1.5.2...v1.5.4) --- updated-dependencies: - dependency-name: github.com/hashicorp/go-getter dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 63 +++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 72a311e546..f3c3500fdb 100644 --- a/go.mod +++ b/go.mod @@ -33,7 +33,7 @@ require ( github.com/google/go-github/v32 v32.1.0 github.com/google/slowjam v0.0.0-20200530021616-df27e642fe7b github.com/google/uuid v1.2.0 - github.com/hashicorp/go-getter v1.5.2 + github.com/hashicorp/go-getter v1.5.4 github.com/hashicorp/go-retryablehttp v0.7.0 github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 // indirect github.com/hooklift/assert v0.0.0-20170704181755-9d1defd6d214 // indirect @@ -71,7 +71,7 @@ require ( github.com/shirou/gopsutil/v3 v3.21.5 github.com/spf13/cobra v1.1.3 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.7.1 + github.com/spf13/viper v1.8.0 github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f github.com/zchee/go-vmnet v0.0.0-20161021174912-97ebf9174097 go.opencensus.io v0.23.0 diff --git a/go.sum b/go.sum index de7f56d87e..b1b3e0bffb 100644 --- a/go.sum +++ b/go.sum @@ -67,7 +67,6 @@ github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocm github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Delta456/box-cli-maker/v2 v2.2.1 h1:uTcuvT6Ty+LBHuRUdFrJBpqP9RhtLxI5+5ZpKYAUuVw= @@ -125,6 +124,7 @@ github.com/alonyb/spinner v1.12.7 h1:FflTMA9I2xRd8OQ5swyZY6Q1DFeaicA/bWo6/oM82a8 github.com/alonyb/spinner v1.12.7/go.mod h1:mQak9GHqbspjC/5iUx3qMlIho8xBS/ppAL/hX5SmPJU= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -149,6 +149,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= @@ -270,6 +271,7 @@ github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -422,6 +424,7 @@ github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblf github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -550,15 +553,16 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-getter v1.5.2 h1:XDo8LiAcDisiqZdv0TKgz+HtX3WN7zA2JD1R1tjsabE= -github.com/hashicorp/go-getter v1.5.2/go.mod h1:orNH3BTYLu/fIxGIdLjLoAJHWMDQ/UKQr5O4m3iBuoo= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.5.4 h1:/A0xlardcuhx8SEe1rh1371xV7Yi4j3xeluu53VXeyg= +github.com/hashicorp/go-getter v1.5.4/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -627,8 +631,9 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -670,6 +675,7 @@ github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgo github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -699,8 +705,9 @@ github.com/machine-drivers/docker-machine-driver-vmware v0.1.3/go.mod h1:p2hY99U github.com/machine-drivers/machine v0.7.1-0.20210306082426-fcb2ad5bcb17 h1:fQoDTuCuJ30R+D6TSB9SALB+J3jUMa8ID8YPfmSDA20= github.com/machine-drivers/machine v0.7.1-0.20210306082426-fcb2ad5bcb17/go.mod h1:79Uwa2hGd5S39LDJt58s8JZcIhGEK6pkq9bsuTbFWbk= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= +github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -754,8 +761,9 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/hyperkit v0.0.0-20210108224842-2f061e447e14 h1:XGy4iMfaG4r1uZKZQmEPSYSH0Nj5JJuKgPNUhWGQ08E= github.com/moby/hyperkit v0.0.0-20210108224842-2f061e447e14/go.mod h1:aBcAEoy5u01cPAYvosR85gzSrMZ0TVVnkPytOQN+9z8= @@ -842,8 +850,9 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= @@ -859,6 +868,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v0.0.0-20161223203901-3a8809bd8a80 h1:DQFOykp5w+HOykOMzd2yOX5P6ty58Ggiu2rthHgcNQg= github.com/pkg/profile v0.0.0-20161223203901-3a8809bd8a80/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -904,6 +914,7 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= @@ -944,10 +955,12 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= @@ -965,8 +978,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= -github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.8.0 h1:QRwDgoG8xX+kp69di68D+YYTCWfYEckbZRfUlEIAal0= +github.com/spf13/viper v1.8.0/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -1039,6 +1052,9 @@ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -1062,12 +1078,15 @@ go.opentelemetry.io/otel/sdk v0.16.0/go.mod h1:Jb0B4wrxerxtBeapvstmAZvJGQmvah4dH go.opentelemetry.io/otel/trace v0.17.0 h1:SBOj64/GAOyWzs5F680yW1ITIfJkm6cJWL2YAvuL9xY= go.opentelemetry.io/otel/trace v0.17.0/go.mod h1:bIujpqg6ZL6xUTubIUgziI1jSaUPthmabA/ygf/6Cfg= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190927031335-2835ba2e683f h1:hXVePvSFG7tPGX4Pwk1d10ePFfoTCc0QmISfpKOHsS8= golang.org/x/build v0.0.0-20190927031335-2835ba2e683f/go.mod h1:fYw7AShPAhGMdXqA9gRadk/CcMsvLlClpE5oBwnS3dM= @@ -1087,6 +1106,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1211,6 +1231,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210413134643-5e61552d6c78/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -1447,6 +1468,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/api v0.45.0/go.mod h1:ISLIJCedJolbZvDfAk+Ctuq5hf+aJ33WgtUsfyFoLXA= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0 h1:RDAPWfNFY06dffEXfn7hZF5Fr1ZbnChzfQZAPyBd1+I= @@ -1485,6 +1507,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= @@ -1530,6 +1553,7 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= @@ -1571,8 +1595,9 @@ gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mcuadros/go-syslog.v2 v2.2.1/go.mod h1:l5LPIyOOyIdQquNg+oU6Z3524YwrcqEm0aKH+5zpt2U= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= @@ -1586,6 +1611,7 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1593,8 +1619,9 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= From f60117a2c4841955d1249788fc4cb0752e9e37d7 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Mon, 21 Jun 2021 13:52:21 -0700 Subject: [PATCH 122/122] add `How do I use minikube in a script` section --- site/content/en/docs/tutorials/user_flag.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/site/content/en/docs/tutorials/user_flag.md b/site/content/en/docs/tutorials/user_flag.md index 1db7833a00..55e8ee4752 100644 --- a/site/content/en/docs/tutorials/user_flag.md +++ b/site/content/en/docs/tutorials/user_flag.md @@ -41,10 +41,16 @@ Here you can see that passing `--user=mary` overwrote the OS user with `mary` as ## Example use case -A good use case for the `--user` flag is if you have an application that starts and stops minikube clusters. -Assume the application will use an exsiting cluster if available, otherwise, it will start a new one. -The problem comes when the application is finished using the cluster, you only want to stop the running cluster if the application started the cluster, not if it was already existing. +- Embedded use of minikube by multiple users (IDEs, Plugins, etc.) +- A machine shared by multiple users using the same home folder -This is where the user flag comes into play. -If the application was configured to pass a user flag on minikube commands (ex. `--user=app123`) then you could check to see what user executed the last `start` command looking at the audit log. -If the last user was `app123` you're safe to stop the cluster, otherwise leave it running. +## How do I use minikube in a script? + +If you are using minikube in a script or plugin it is recommeneded to add `--user=your_script_name` to all operations. + +Example: +``` +minikube start --user=plugin_name +minikube profile list --user=plugin_name +minikube stop --user=plugin_name +```