diff options
| author | Achilleas Pipinellis <axil@gitlab.com> | 2019-08-20 20:22:43 +0200 |
|---|---|---|
| committer | Achilleas Pipinellis <axil@gitlab.com> | 2019-08-20 20:22:43 +0200 |
| commit | e61308ce1d82e12e5087371469baea4a452875d1 (patch) | |
| tree | 62551a3ae4eab75e5af7e3b35358c07a51b2132f /scripts | |
| parent | 4f323bb62fbe71a4352de25cab141f361a3fe1a6 (diff) | |
| parent | 2989ed078c1d45b0959dcecb1bc3c8f4740a3c0d (diff) | |
| download | gitlab-ce-docs-patch-71.tar.gz | |
Merge branch 'master' into docs-patch-71docs-patch-71
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/create_mysql_user.sh | 7 | ||||
| -rwxr-xr-x | scripts/frontend/file_test_coverage.js | 88 | ||||
| -rwxr-xr-x | scripts/frontend/test.js | 23 | ||||
| -rwxr-xr-x | scripts/gather-test-memory-data | 21 | ||||
| -rwxr-xr-x | scripts/generate-gems-memory-metrics-static | 18 | ||||
| -rwxr-xr-x | scripts/generate-gems-size-metrics-static | 30 | ||||
| -rwxr-xr-x | scripts/generate-memory-metrics-on-boot | 11 | ||||
| -rw-r--r-- | scripts/gitaly_test.rb | 5 | ||||
| -rwxr-xr-x | scripts/insert-rspec-profiling-data | 4 | ||||
| -rwxr-xr-x | scripts/lint-changelog-yaml | 24 | ||||
| -rwxr-xr-x | scripts/lint-doc.sh | 4 | ||||
| -rwxr-xr-x | scripts/lint-rugged | 13 | ||||
| -rwxr-xr-x | scripts/merge-html-reports | 84 | ||||
| -rw-r--r-- | scripts/prepare_build.sh | 10 | ||||
| -rwxr-xr-x | scripts/review_apps/review-apps.sh | 249 | ||||
| -rwxr-xr-x | scripts/static-analysis | 5 | ||||
| -rwxr-xr-x | scripts/trigger-build | 10 | ||||
| -rwxr-xr-x | scripts/trigger-build-docs | 10 | ||||
| -rw-r--r-- | scripts/utils.sh | 2 |
19 files changed, 468 insertions, 150 deletions
diff --git a/scripts/create_mysql_user.sh b/scripts/create_mysql_user.sh deleted file mode 100644 index 35f68c581f3..00000000000 --- a/scripts/create_mysql_user.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -mysql --user=root --host=mysql <<EOF -CREATE USER IF NOT EXISTS 'gitlab'@'%'; -GRANT ALL PRIVILEGES ON gitlabhq_test.* TO 'gitlab'@'%'; -FLUSH PRIVILEGES; -EOF diff --git a/scripts/frontend/file_test_coverage.js b/scripts/frontend/file_test_coverage.js new file mode 100755 index 00000000000..7d1eb45d4bc --- /dev/null +++ b/scripts/frontend/file_test_coverage.js @@ -0,0 +1,88 @@ +#!/usr/bin/env node + +/** + * Counts the number of frontend test files and compares them against the number of application files. + * + * Example output: + * + * Source files: 1551 + * Test files: 716 + * Coverage: 46.16% + */ + +const fs = require('fs'); +const path = require('path'); + +const sourceDirectories = ['app/assets/javascripts']; +const testDirectories = ['spec/javascripts', 'spec/frontend']; + +if (fs.existsSync('ee')) { + sourceDirectories.forEach(dir => { + sourceDirectories.push(`ee/${dir}`); + }); + + testDirectories.forEach(dir => { + testDirectories.push(`ee/${dir}`); + }); +} + +let numSourceFiles = 0; +let numTestFiles = 0; + +const isVerbose = process.argv.some(arg => arg === '-v'); + +const countSourceFiles = path => + forEachFileIn(path, fileName => { + if (fileName.endsWith('.vue') || fileName.endsWith('.js')) { + if (isVerbose) { + console.log(`source file: ${fileName}`); + } + + numSourceFiles += 1; + } + }); + +const countTestFiles = path => + forEachFileIn(path, fileName => { + if (fileName.endsWith('_spec.js')) { + if (isVerbose) { + console.log(`test file: ${fileName}`); + } + + numTestFiles += 1; + } + }); + +function forEachFileIn(dirPath, callback) { + fs.readdir(dirPath, (err, files) => { + if (err) { + console.error(err); + } + + if (!files) { + return; + } + + files.forEach(fileName => { + const absolutePath = path.join(dirPath, fileName); + const stats = fs.statSync(absolutePath); + if (stats.isFile()) { + callback(absolutePath); + } else if (stats.isDirectory()) { + forEachFileIn(absolutePath, callback); + } + }); + }); +} + +console.log(`Source directories: ${sourceDirectories.join(', ')}`); +console.log(`Test directories: ${testDirectories.join(', ')}`); + +sourceDirectories.forEach(countSourceFiles); +testDirectories.forEach(countTestFiles); + +process.on('exit', () => { + console.log(`Source files: ${numSourceFiles}`); + console.log(`Test files: ${numTestFiles}`); + console.log(`Coverage: ${((100 * numTestFiles) / numSourceFiles).toFixed(2)}%`); +}); diff --git a/scripts/frontend/test.js b/scripts/frontend/test.js index dab7176f8c1..71a8bebf0f2 100755 --- a/scripts/frontend/test.js +++ b/scripts/frontend/test.js @@ -5,19 +5,24 @@ const { EOL } = require('os'); const program = require('commander'); const chalk = require('chalk'); +const SUCCESS_CODE = 0; const JEST_ROUTE = 'spec/frontend'; const KARMA_ROUTE = 'spec/javascripts'; const COMMON_ARGS = ['--colors']; -const JEST_ARGS = ['--passWithNoTests']; -const KARMA_ARGS = ['--no-fail-on-empty-test-suite']; -const SUCCESS_CODE = 0; +const jestArgs = [...COMMON_ARGS, '--passWithNoTests']; +const karmaArgs = [...COMMON_ARGS, '--no-fail-on-empty-test-suite']; program - .version('0.1.0') .usage('[options] <file ...>') .option('-p, --parallel', 'Run tests suites in parallel') + .option( + '-w, --watch', + 'Rerun tests when files change (tests will be run in parallel if this enabled)', + ) .parse(process.argv); +const shouldParallelize = program.parallel || program.watch; + const isSuccess = code => code === SUCCESS_CODE; const combineExitCodes = codes => { @@ -31,7 +36,7 @@ const skipIfFail = fn => code => (isSuccess(code) ? fn() : code); const endWithEOL = str => (str[str.length - 1] === '\n' ? str : `${str}${EOL}`); const runTests = paths => { - if (program.parallel) { + if (shouldParallelize) { return Promise.all([runJest(paths), runKarma(paths)]).then(combineExitCodes); } else { return runJest(paths).then(skipIfFail(() => runKarma(paths))); @@ -73,11 +78,11 @@ const spawnYarnScript = (cmd, args) => { }; const runJest = args => { - return spawnYarnScript('jest', [...JEST_ARGS, ...COMMON_ARGS, ...toJestArgs(args)]); + return spawnYarnScript('jest', [...jestArgs, ...toJestArgs(args)]); }; const runKarma = args => { - return spawnYarnScript('karma', [...KARMA_ARGS, ...COMMON_ARGS, ...toKarmaArgs(args)]); + return spawnYarnScript('karma', [...karmaArgs, ...toKarmaArgs(args)]); }; const replacePath = to => path => @@ -96,6 +101,10 @@ const toKarmaArgs = paths => paths.reduce((acc, path) => acc.concat('-f', replacePathForKarma(path)), []); const main = paths => { + if (program.watch) { + jestArgs.push('--watch'); + karmaArgs.push('--single-run', 'false', '--auto-watch'); + } runTests(paths).then(code => { console.log('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'); if (isSuccess(code)) { diff --git a/scripts/gather-test-memory-data b/scripts/gather-test-memory-data new file mode 100755 index 00000000000..9992a83e6a6 --- /dev/null +++ b/scripts/gather-test-memory-data @@ -0,0 +1,21 @@ +#!/usr/bin/env ruby + +require 'csv' + +def join_csv_files(output_path, input_paths) + return if input_paths.empty? + + input_csvs = input_paths.map do |input_path| + CSV.read(input_path, headers: true) + end + + CSV.open(output_path, "w", headers: input_csvs.first.headers, write_headers: true) do |output_csv| + input_csvs.each do |input_csv| + input_csv.each do |line| + output_csv << line + end + end + end +end + +join_csv_files('tmp/memory_test/report.csv', Dir['tmp/memory_test/*.csv'].sort) diff --git a/scripts/generate-gems-memory-metrics-static b/scripts/generate-gems-memory-metrics-static new file mode 100755 index 00000000000..aa7ce3615bf --- /dev/null +++ b/scripts/generate-gems-memory-metrics-static @@ -0,0 +1,18 @@ +#!/usr/bin/env ruby + +abort "usage: #{__FILE__} <memory_bundle_objects_file_name>" unless ARGV.length == 1 +memory_bundle_objects_file_name = ARGV.first + +full_report = File.readlines(memory_bundle_objects_file_name) + +allocated_str = full_report[1] +retained_str = full_report[2] +allocated_stats = /Total allocated: (?<bytes>.*) bytes \((?<objects>.*) objects\)/.match(allocated_str) +retained_stats = /Total retained: (?<bytes>.*) bytes \((?<objects>.*) objects\)/.match(retained_str) + +abort 'failed to process the benchmark output' unless allocated_stats && retained_stats + +puts "memory_static_objects_allocated_mb #{(allocated_stats[:bytes].to_f / (1024 * 1024)).round(1)}" +puts "memory_static_objects_retained_mb #{(retained_stats[:bytes].to_f / (1024 * 1024)).round(1)}" +puts "memory_static_objects_allocated_items #{allocated_stats[:objects]}" +puts "memory_static_objects_retained_items #{retained_stats[:objects]}" diff --git a/scripts/generate-gems-size-metrics-static b/scripts/generate-gems-size-metrics-static new file mode 100755 index 00000000000..ceec8aaccf1 --- /dev/null +++ b/scripts/generate-gems-size-metrics-static @@ -0,0 +1,30 @@ +#!/usr/bin/env ruby + +abort "usage: #{__FILE__} <memory_bundle_mem_file_name>" unless ARGV.length == 1 +memory_bundle_mem_file_name = ARGV.first + +full_report = File.readlines(memory_bundle_mem_file_name) + +def total_size(memory_bundle_mem_report) + stats = /TOP: (?<total_mibs_str>.*) MiB/.match(memory_bundle_mem_report.first) + abort 'failed to process the benchmark output' unless stats + "gem_total_size_mb #{stats[:total_mibs_str].to_f.round(1)}" +end + +TOP_LEVEL_GEM_LOG_FORMAT = /^ (?<gem_name>\S.*):\s*(?<gem_size>\d[.\d]*)\s*MiB/.freeze +def all_gems(memory_bundle_mem_report) + memory_bundle_mem_report.map do |line| + TOP_LEVEL_GEM_LOG_FORMAT.match(line) + end.compact +end + +def gems_as_metrics(gems_match_data) + gems_match_data.map do |gem| + gem_name = gem[:gem_name] + gem_size_mb = gem[:gem_size].to_f.round(1) + "gem_size_mb{name=\"#{gem_name}\"} #{gem_size_mb}" + end +end + +puts total_size(full_report) +puts gems_as_metrics(all_gems(full_report)).sort(&:casecmp) diff --git a/scripts/generate-memory-metrics-on-boot b/scripts/generate-memory-metrics-on-boot new file mode 100755 index 00000000000..5197a8fcdcd --- /dev/null +++ b/scripts/generate-memory-metrics-on-boot @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby + +abort "usage: #{__FILE__} <memory_bundle_mem_file_name>" unless ARGV.length == 1 +memory_bundle_mem_file_name = ARGV.first + +full_report = File.open(memory_bundle_mem_file_name).read + +stats = /TOP: (?<total_mibs_str>.*) MiB/.match(full_report) +abort 'failed to process the benchmark output' unless stats + +puts "total_memory_used_by_dependencies_on_boot_prod_env_mb #{stats[:total_mibs_str].to_f.round(1)}" diff --git a/scripts/gitaly_test.rb b/scripts/gitaly_test.rb index b5d3facd18a..b5cc5118530 100644 --- a/scripts/gitaly_test.rb +++ b/scripts/gitaly_test.rb @@ -23,7 +23,10 @@ module GitalyTest 'BUNDLE_FLAGS' => "--jobs=4 --retry=3", 'BUNDLE_INSTALL_FLAGS' => nil, 'BUNDLE_GEMFILE' => gemfile, - 'RUBYOPT' => nil + 'RUBYOPT' => nil, + + # Git hooks can't run during tests as the internal API is not running. + 'GITALY_TESTING_NO_GIT_HOOKS' => "1" } if ENV['CI'] diff --git a/scripts/insert-rspec-profiling-data b/scripts/insert-rspec-profiling-data index b34379764e0..88c9d8c12b1 100755 --- a/scripts/insert-rspec-profiling-data +++ b/scripts/insert-rspec-profiling-data @@ -14,10 +14,6 @@ module RspecProfiling Result.establish_connection(results_url) end - def prepared? - connection.data_source_exists?(table) - end - def results_url ENV['RSPEC_PROFILING_POSTGRES_URL'] end diff --git a/scripts/lint-changelog-yaml b/scripts/lint-changelog-yaml deleted file mode 100755 index 06d502c4676..00000000000 --- a/scripts/lint-changelog-yaml +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env ruby - -require 'yaml' - -invalid_changelogs = Dir['changelogs/**/*'].reject do |changelog| - next true if changelog =~ /((README|archive)\.md|unreleased(-ee)?)$/ - next false unless changelog.end_with?('.yml') - - begin - YAML.load_file(changelog) - rescue => exception - puts exception - end -end - -if invalid_changelogs.any? - puts - puts "Invalid changelogs found!\n" - puts invalid_changelogs.sort - exit 1 -else - puts "All changelogs are valid YAML.\n" - exit 0 -end diff --git a/scripts/lint-doc.sh b/scripts/lint-doc.sh index 2055ce7f09d..8c9b8b9fb02 100755 --- a/scripts/lint-doc.sh +++ b/scripts/lint-doc.sh @@ -45,7 +45,7 @@ then then echo echo ' ✖ ERROR: New README.md file(s) detected, prefer index.md over README.md.' >&2 - echo ' https://docs.gitlab.com/ee/development/writing_documentation.html#location-and-naming-documents' + echo ' https://docs.gitlab.com/ee/development/documentation/styleguide.html#working-with-directories-and-files' echo exit 1 fi @@ -55,7 +55,7 @@ then then echo echo ' ✖ ERROR: New README.md file(s) detected, prefer index.md over README.md.' >&2 - echo ' https://docs.gitlab.com/ee/development/writing_documentation.html#location-and-naming-documents' + echo ' https://docs.gitlab.com/ee/development/documentation/styleguide.html#working-with-directories-and-files' echo exit 1 fi diff --git a/scripts/lint-rugged b/scripts/lint-rugged index 9466c62a415..1b3fb54f70b 100755 --- a/scripts/lint-rugged +++ b/scripts/lint-rugged @@ -1,6 +1,9 @@ #!/usr/bin/env ruby ALLOWED = [ + # https://gitlab.com/gitlab-org/gitaly/issues/760 + 'lib/elasticsearch/git/repository.rb', + # Needed to handle repositories that are not in any storage 'lib/gitlab/bare_repository_import/repository.rb', @@ -10,7 +13,15 @@ ALLOWED = [ # Reverted Rugged calls due to Gitaly atop NFS performance # See https://docs.gitlab.com/ee/development/gitaly.html#legacy-rugged-code. 'lib/gitlab/git/rugged_impl/', - 'lib/gitlab/gitaly_client/storage_settings.rb' + 'lib/gitlab/gitaly_client/storage_settings.rb', + + # Needed for logging + 'config/initializers/peek.rb', + 'config/initializers/lograge.rb', + 'lib/gitlab/grape_logging/loggers/perf_logger.rb', + 'lib/gitlab/instrumentation_helper.rb', + 'lib/gitlab/rugged_instrumentation.rb', + 'lib/peek/views/rugged.rb' ].freeze rugged_lines = IO.popen(%w[git grep -i -n rugged -- app config lib], &:read).lines diff --git a/scripts/merge-html-reports b/scripts/merge-html-reports new file mode 100755 index 00000000000..7d1e15186c8 --- /dev/null +++ b/scripts/merge-html-reports @@ -0,0 +1,84 @@ +#!/usr/bin/env ruby + +require 'nokogiri' + +main_report_file = ARGV.shift +unless main_report_file + puts 'usage: merge-html-reports <main-report> <base-artifact-url> [parallel reports...]' + exit 1 +end + +base_artifact_url = ARGV.shift +unless base_artifact_url + puts 'usage: merge-html-reports <main-report> <base-artifact-url> [parallel reports...]' + exit 1 +end + +# Create the base report with empty body tag +new_report = Nokogiri::HTML.parse(File.read(ARGV[0])) +new_report.at_css('body').remove +empty_body = Nokogiri::XML::Node.new('body', new_report) +new_report.at_css('head').add_next_sibling(empty_body) + +ARGV.each do |report_file| + report = Nokogiri::HTML.parse(File.read(report_file)) + + report.css('a').each do |link| + link_suffix = link['href'].slice(19..-1) + link['href'] = base_artifact_url + link_suffix + end + + header = report.css('div #rspec-header') + tests = report.css('dt[id^="example_group_"]') + + tests.each do |test| + title = test.parent + group = title.parent + script = title.css('script') + + if script.inner_html.include? 'makeYellow' + test.remove_class('passed') + test.add_class('not_implemented') + + group.remove_class('passed') + group.add_class('not_implemented') + header.add_class('not_implemented') + + script.remove + test.next_sibling.remove + test.next_sibling.remove + + elsif script.inner_html.include? 'makeRed' + test.remove_class('passed') + test.add_class('failed') + + group.remove_class('passed') + group.add_class('failed') + header.add_class('failed') + + script.remove + test.next_sibling.remove + test.next_sibling.remove + end + end + + duration = report.at_css('p#duration') + totals = report.at_css('p#totals') + + duration_script = report.css('div.results script')[-2] + totals_script = report.css('div.results script')[-1] + + duration_text = duration_script.text.slice(49..-3) + totals_text = totals_script.text.slice(47..-3) + + duration.inner_html = duration_text + totals.inner_html = totals_text + + duration_script.remove + totals_script.remove + + # Add the new result after the last one to keep the test order + new_report.css('body')[-1].add_next_sibling(report.at_css('body')) +end + +File.write(main_report_file, new_report) diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index 9b0d5d4f719..0950ec272a5 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -35,9 +35,11 @@ sed -i 's/username: root/username: gitlab/g' config/database.yml if [ "$GITLAB_DATABASE" = 'postgresql' ]; then sed -i 's/localhost/postgres/g' config/database.yml + sed -i 's/username: git/username: postgres/g' config/database.yml if [ -f config/database_geo.yml ]; then sed -i 's/localhost/postgres/g' config/database_geo.yml + sed -i 's/username: git/username: postgres/g' config/database_geo.yml fi else # Assume it's mysql sed -i 's/localhost/mysql/g' config/database.yml @@ -48,16 +50,16 @@ else # Assume it's mysql fi cp config/resque.yml.example config/resque.yml -sed -i 's/localhost/redis/g' config/resque.yml +sed -i 's|url:.*$|url: redis://redis:6379|g' config/resque.yml cp config/redis.cache.yml.example config/redis.cache.yml -sed -i 's/localhost/redis/g' config/redis.cache.yml +sed -i 's|url:.*$|url: redis://redis:6379/10|g' config/redis.cache.yml cp config/redis.queues.yml.example config/redis.queues.yml -sed -i 's/localhost/redis/g' config/redis.queues.yml +sed -i 's|url:.*$|url: redis://redis:6379/11|g' config/redis.queues.yml cp config/redis.shared_state.yml.example config/redis.shared_state.yml -sed -i 's/localhost/redis/g' config/redis.shared_state.yml +sed -i 's|url:.*$|url: redis://redis:6379/12|g' config/redis.shared_state.yml if [ "$SETUP_DB" != "false" ]; then setup_db diff --git a/scripts/review_apps/review-apps.sh b/scripts/review_apps/review-apps.sh index 9455e462617..4935c1342a3 100755 --- a/scripts/review_apps/review-apps.sh +++ b/scripts/review_apps/review-apps.sh @@ -1,7 +1,7 @@ [[ "$TRACE" ]] && set -x export TILLER_NAMESPACE="$KUBE_NAMESPACE" -function deployExists() { +function deploy_exists() { local namespace="${1}" local deploy="${2}" echoinfo "Checking if ${deploy} exists in the ${namespace} namespace..." true @@ -13,8 +13,7 @@ function deployExists() { return $deploy_exists } -function previousDeployFailed() { - set +e +function previous_deploy_failed() { local deploy="${1}" echoinfo "Checking for previous deployment of ${deploy}" true @@ -34,7 +33,6 @@ function previousDeployFailed() { else echoerr "Previous deployment NOT found." fi - set -e return $status } @@ -51,49 +49,34 @@ function delete() { helm delete --purge "$name" } -function cleanup() { - if [ -z "$CI_ENVIRONMENT_SLUG" ]; then - echoerr "No release given, aborting the delete!" - return - fi - - echoinfo "Cleaning up '$CI_ENVIRONMENT_SLUG'..." true - - kubectl -n "$KUBE_NAMESPACE" delete \ - ingress,svc,pdb,hpa,deploy,statefulset,job,pod,secret,configmap,pvc,secret,clusterrole,clusterrolebinding,role,rolebinding,sa \ - --now --ignore-not-found --include-uninitialized \ - -l release="$CI_ENVIRONMENT_SLUG" -} - function get_pod() { local app_name="${1}" local status="${2-Running}" - get_pod_cmd="kubectl get pods -n ${KUBE_NAMESPACE} --field-selector=status.phase=${status} -lapp=${app_name},release=${CI_ENVIRONMENT_SLUG} --no-headers -o=custom-columns=NAME:.metadata.name" - echoinfo "Running '${get_pod_cmd}'" true + get_pod_cmd="kubectl get pods -n ${KUBE_NAMESPACE} --field-selector=status.phase=${status} -lapp=${app_name},release=${CI_ENVIRONMENT_SLUG} --no-headers -o=custom-columns=NAME:.metadata.name | tail -n 1" + echoinfo "Waiting till '${app_name}' pod is ready" true + echoinfo "Running '${get_pod_cmd}'" + local interval=5 + local elapsed_seconds=0 + local max_seconds=$((2 * 60)) while true; do local pod_name pod_name="$(eval "${get_pod_cmd}")" [[ "${pod_name}" == "" ]] || break - echoinfo "Waiting till '${app_name}' pod is ready"; - sleep 5; + if [[ "${elapsed_seconds}" -gt "${max_seconds}" ]]; then + echoerr "The pod name couldn't be found after ${elapsed_seconds} seconds, aborting." + break + fi + + let "elapsed_seconds+=interval" + sleep ${interval} done echoinfo "The pod name is '${pod_name}'." echo "${pod_name}" } -function perform_review_app_deployment() { - check_kube_domain - ensure_namespace - install_tiller - install_external_dns - time deploy - wait_for_review_app_to_be_accessible - add_license -} - function check_kube_domain() { echoinfo "Checking that Kube domain exists..." true @@ -119,9 +102,16 @@ function install_tiller() { echoinfo "Initiating the Helm client..." helm init --client-only + # Set toleration for Tiller to be installed on a specific node pool helm init \ + --wait \ --upgrade \ - --replicas 2 + --node-selectors "app=helm" \ + --replicas 3 \ + --override "spec.template.spec.tolerations[0].key"="dedicated" \ + --override "spec.template.spec.tolerations[0].operator"="Equal" \ + --override "spec.template.spec.tolerations[0].value"="helm" \ + --override "spec.template.spec.tolerations[0].effect"="NoSchedule" kubectl rollout status -n "$TILLER_NAMESPACE" -w "deployment/tiller-deploy" @@ -137,26 +127,32 @@ function install_external_dns() { domain=$(echo "${REVIEW_APPS_DOMAIN}" | awk -F. '{printf "%s.%s", $(NF-1), $NF}') echoinfo "Installing external DNS for domain ${domain}..." true - if ! deployExists "${KUBE_NAMESPACE}" "${release_name}" || previousDeployFailed "${release_name}" ; then + if ! deploy_exists "${KUBE_NAMESPACE}" "${release_name}" || previous_deploy_failed "${release_name}" ; then echoinfo "Installing external-dns Helm chart" helm repo update - helm install stable/external-dns \ + # Default requested: CPU => 0, memory => 0 + helm install stable/external-dns --version '^2.2.1' \ -n "${release_name}" \ --namespace "${KUBE_NAMESPACE}" \ --set provider="aws" \ - --set aws.secretKey="${REVIEW_APPS_AWS_SECRET_KEY}" \ - --set aws.accessKey="${REVIEW_APPS_AWS_ACCESS_KEY}" \ + --set aws.credentials.secretKey="${REVIEW_APPS_AWS_SECRET_KEY}" \ + --set aws.credentials.accessKey="${REVIEW_APPS_AWS_ACCESS_KEY}" \ --set aws.zoneType="public" \ + --set aws.batchChangeSize=400 \ --set domainFilters[0]="${domain}" \ --set txtOwnerId="${KUBE_NAMESPACE}" \ --set rbac.create="true" \ - --set policy="sync" + --set policy="sync" \ + --set resources.requests.cpu=50m \ + --set resources.limits.cpu=100m \ + --set resources.requests.memory=100M \ + --set resources.limits.memory=200M else echoinfo "The external-dns Helm chart is already successfully deployed." fi } -function create_secret() { +function create_application_secret() { echoinfo "Creating the ${CI_ENVIRONMENT_SLUG}-gitlab-initial-root-password secret in the ${KUBE_NAMESPACE} namespace..." true kubectl create secret generic -n "$KUBE_NAMESPACE" \ @@ -165,7 +161,7 @@ function create_secret() { --dry-run -o json | kubectl apply -f - } -function download_gitlab_chart() { +function download_chart() { echoinfo "Downloading the GitLab chart..." true curl -o gitlab.tar.bz2 "https://gitlab.com/charts/gitlab/-/archive/${GITLAB_HELM_CHART_REF}/gitlab-${GITLAB_HELM_CHART_REF}.tar.bz2" @@ -193,89 +189,154 @@ function deploy() { gitlab_shell_image_repository="${IMAGE_REPOSITORY}/gitlab-shell" gitlab_workhorse_image_repository="${IMAGE_REPOSITORY}/gitlab-workhorse-${IMAGE_VERSION}" - # Cleanup and previous installs, as FAILED and PENDING_UPGRADE will cause errors with `upgrade` - if [ "$CI_ENVIRONMENT_SLUG" != "production" ] && previousDeployFailed "$CI_ENVIRONMENT_SLUG" ; then - echo "Deployment in bad state, cleaning up $CI_ENVIRONMENT_SLUG" - delete - cleanup - fi - - create_secret - download_gitlab_chart + create_application_secret HELM_CMD=$(cat << EOF helm upgrade --install \ - --wait \ - --timeout 600 \ - --set global.appConfig.enableUsagePing=false \ + --atomic \ + --timeout 900 \ --set releaseOverride="$CI_ENVIRONMENT_SLUG" \ + --set global.appConfig.enableUsagePing=false \ + --set global.imagePullPolicy=Always \ --set global.hosts.hostSuffix="$HOST_SUFFIX" \ --set global.hosts.domain="$REVIEW_APPS_DOMAIN" \ - --set certmanager.install=false \ - --set prometheus.install=false \ --set global.ingress.configureCertmanager=false \ --set global.ingress.tls.secretName=tls-cert \ - --set global.ingress.annotations."external-dns\.alpha\.kubernetes\.io/ttl"="10" + --set global.ingress.annotations."external-dns\.alpha\.kubernetes\.io/ttl"="10" \ + --set certmanager.install=false \ + --set prometheus.install=false \ --set nginx-ingress.controller.service.enableHttp=false \ - --set nginx-ingress.defaultBackend.resources.requests.memory=7Mi \ - --set nginx-ingress.controller.resources.requests.memory=440M \ --set nginx-ingress.controller.replicaCount=2 \ - --set gitlab.unicorn.resources.requests.cpu=200m \ - --set gitlab.sidekiq.resources.requests.cpu=100m \ - --set gitlab.sidekiq.resources.requests.memory=800M \ - --set gitlab.gitlab-shell.resources.requests.cpu=100m \ - --set redis.resources.requests.cpu=100m \ - --set minio.resources.requests.cpu=100m \ + --set nginx-ingress.controller.config.ssl-ciphers="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4" \ --set gitlab.migrations.image.repository="$gitlab_migrations_image_repository" \ --set gitlab.migrations.image.tag="$CI_COMMIT_REF_SLUG" \ - --set gitlab.sidekiq.image.repository="$gitlab_sidekiq_image_repository" \ - --set gitlab.sidekiq.image.tag="$CI_COMMIT_REF_SLUG" \ - --set gitlab.unicorn.image.repository="$gitlab_unicorn_image_repository" \ - --set gitlab.unicorn.image.tag="$CI_COMMIT_REF_SLUG" \ - --set gitlab.task-runner.image.repository="$gitlab_task_runner_image_repository" \ - --set gitlab.task-runner.image.tag="$CI_COMMIT_REF_SLUG" \ --set gitlab.gitaly.image.repository="$gitlab_gitaly_image_repository" \ --set gitlab.gitaly.image.tag="v$GITALY_VERSION" \ --set gitlab.gitlab-shell.image.repository="$gitlab_shell_image_repository" \ --set gitlab.gitlab-shell.image.tag="v$GITLAB_SHELL_VERSION" \ + --set gitlab.sidekiq.image.repository="$gitlab_sidekiq_image_repository" \ + --set gitlab.sidekiq.image.tag="$CI_COMMIT_REF_SLUG" \ + --set gitlab.unicorn.image.repository="$gitlab_unicorn_image_repository" \ + --set gitlab.unicorn.image.tag="$CI_COMMIT_REF_SLUG" \ --set gitlab.unicorn.workhorse.image="$gitlab_workhorse_image_repository" \ --set gitlab.unicorn.workhorse.tag="$CI_COMMIT_REF_SLUG" \ - --set nginx-ingress.controller.config.ssl-ciphers="ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4" \ - --namespace="$KUBE_NAMESPACE" \ - --version="$CI_PIPELINE_ID-$CI_JOB_ID" \ - "$name" \ - . + --set gitlab.task-runner.image.repository="$gitlab_task_runner_image_repository" \ + --set gitlab.task-runner.image.tag="$CI_COMMIT_REF_SLUG" +EOF +) + +# Default requested: CPU => 100m, memory => 100Mi +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set nginx-ingress.controller.resources.limits.cpu=200m \ + --set nginx-ingress.controller.resources.requests.memory=210M \ + --set nginx-ingress.controller.resources.limits.memory=420M +EOF +) + +# Default requested: CPU => 5m, memory => 5Mi +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set nginx-ingress.defaultBackend.resources.limits.cpu=10m \ + --set nginx-ingress.defaultBackend.resources.requests.memory=12M \ + --set nginx-ingress.defaultBackend.resources.limits.memory=24M +EOF +) + +# Default requested: CPU => 100m, memory => 200Mi +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set gitlab.gitaly.resources.requests.cpu=150m \ + --set gitlab.gitaly.resources.limits.cpu=300m \ + --set gitlab.gitaly.resources.limits.memory=420M +EOF +) + +# Default requested: CPU => 0, memory => 6M +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set gitlab.gitlab-shell.resources.requests.cpu=70m \ + --set gitlab.gitlab-shell.resources.limits.cpu=140m \ + --set gitlab.gitlab-shell.resources.requests.memory=20M \ + --set gitlab.gitlab-shell.resources.limits.memory=40M +EOF +) + +# Default requested: CPU => 50m, memory => 650M +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set gitlab.sidekiq.resources.requests.cpu=200m \ + --set gitlab.sidekiq.resources.limits.cpu=300m \ + --set gitlab.sidekiq.resources.requests.memory=800M \ + --set gitlab.sidekiq.resources.limits.memory=1.2G +EOF +) + +# Default requested: CPU => 300m + 100m (workhorse), memory => 1.2G + 100M (workhorse) +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set gitlab.unicorn.resources.limits.cpu=800m \ + --set gitlab.unicorn.resources.limits.memory=2.6G +EOF +) + +# Default requested: CPU => 100m, memory => 64Mi +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set redis.resources.limits.cpu=200m \ + --set redis.resources.limits.memory=130M +EOF +) + +# Default requested: CPU => 100m, memory => 128Mi +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set minio.resources.limits.cpu=200m \ + --set minio.resources.limits.memory=280M +EOF +) + +# Default requested: CPU => 0, memory => 0 +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --set gitlab-runner.resources.requests.cpu=300m \ + --set gitlab-runner.resources.limits.cpu=600m \ + --set gitlab-runner.resources.requests.memory=300M \ + --set gitlab-runner.resources.limits.memory=600M +EOF +) + +HELM_CMD=$(cat << EOF + $HELM_CMD \ + --namespace="$KUBE_NAMESPACE" \ + --version="$CI_PIPELINE_ID-$CI_JOB_ID" \ + "$name" . EOF ) echoinfo "Deploying with:" echoinfo "${HELM_CMD}" - eval $HELM_CMD || true + eval "${HELM_CMD}" } -function wait_for_review_app_to_be_accessible() { - # In case the Review App isn't completely available yet. Keep trying for 5 minutes. - local interval=5 - local elapsed_seconds=0 - local max_seconds=$((5 * 60)) - while true; do - local review_app_http_code - review_app_http_code=$(curl --silent --output /dev/null --max-time 5 --write-out "%{http_code}" "${CI_ENVIRONMENT_URL}/users/sign_in") - if [[ "${review_app_http_code}" -eq "200" ]] || [[ "${elapsed_seconds}" -gt "${max_seconds}" ]]; then - break - fi +function display_deployment_debug() { + migrations_pod=$(get_pod "migrations"); + if [ -z "${migrations_pod}" ]; then + echoerr "Migrations pod not found." + else + echoinfo "Logs tail of the ${migrations_pod} pod..." - printf "." - let "elapsed_seconds+=interval" - sleep ${interval} - done + kubectl logs -n "$KUBE_NAMESPACE" "${migrations_pod}" | sed "s/${REVIEW_APPS_ROOT_PASSWORD}/[REDACTED]/g" + fi - if [[ "${review_app_http_code}" == "200" ]]; then - echoinfo "The Review App at ${CI_ENVIRONMENT_URL} is ready!" + unicorn_pod=$(get_pod "unicorn"); + if [ -z "${unicorn_pod}" ]; then + echoerr "Unicorn pod not found." else - echoerr "The Review App at ${CI_ENVIRONMENT_URL} isn't ready after 5 minutes of polling..." - exit 1 + echoinfo "Logs tail of the ${unicorn_pod} pod..." + + kubectl logs -n "$KUBE_NAMESPACE" -c unicorn "${unicorn_pod}" | sed "s/${REVIEW_APPS_ROOT_PASSWORD}/[REDACTED]/g" fi } diff --git a/scripts/static-analysis b/scripts/static-analysis index 642c50ec0a8..6fd64fbf9da 100755 --- a/scripts/static-analysis +++ b/scripts/static-analysis @@ -1,6 +1,7 @@ #!/usr/bin/env ruby # We don't have auto-loading here +require_relative '../lib/gitlab' require_relative '../lib/gitlab/popen' require_relative '../lib/gitlab/popen/runner' @@ -36,6 +37,10 @@ tasks = [ %w[scripts/lint-rugged] ] +if Gitlab.ee? + tasks.unshift(%w[ruby -rbundler/setup scripts/ee_specific_check/ee_specific_check.rb]) +end + static_analysis = Gitlab::Popen::Runner.new static_analysis.run(tasks) do |cmd, &run| diff --git a/scripts/trigger-build b/scripts/trigger-build index 9c5fc3c76a5..4d8110fce10 100755 --- a/scripts/trigger-build +++ b/scripts/trigger-build @@ -122,7 +122,14 @@ module Trigger end def ref - ENV['CNG_BRANCH'] || 'master' + default_ref = + if ENV['CI_COMMIT_REF_NAME'] =~ /^[\d-]+-stable(-ee)?$/ + ENV['CI_COMMIT_REF_NAME'] + else + 'master' + end + + ENV['CNG_BRANCH'] || default_ref end def trigger_token @@ -142,6 +149,7 @@ module Trigger "GITLAB_VERSION" => ENV['CI_COMMIT_REF_NAME'], "GITLAB_TAG" => ENV['CI_COMMIT_TAG'], "GITLAB_ASSETS_TAG" => ENV['CI_COMMIT_TAG'] ? ENV['CI_COMMIT_REF_NAME'] : ENV['CI_COMMIT_REF_SLUG'], + "FORCE_RAILS_IMAGE_BUILDS" => 'true', "#{edition}_PIPELINE" => 'true' } end diff --git a/scripts/trigger-build-docs b/scripts/trigger-build-docs index dfc8ee6050a..83841512f1c 100755 --- a/scripts/trigger-build-docs +++ b/scripts/trigger-build-docs @@ -13,7 +13,7 @@ end # # The remote docs project # -GITLAB_DOCS_REPO = 'gitlab-com/gitlab-docs'.freeze +GITLAB_DOCS_REPO = 'gitlab-org/gitlab-docs'.freeze # # Truncate the remote docs branch name otherwise we hit the filesystem @@ -31,7 +31,7 @@ end # to avoid race conditions, since a triggered pipeline will also run right # after the branch creation. This only happens the very first time a branch # is created and will be skipped in subsequent runs. Read more in -# https://gitlab.com/gitlab-com/gitlab-docs/issues/154. +# https://gitlab.com/gitlab-org/gitlab-docs/issues/154. # def create_remote_branch Gitlab.create_branch(GITLAB_DOCS_REPO, docs_branch, 'master') @@ -81,7 +81,7 @@ def slug end # -# Overriding vars in https://gitlab.com/gitlab-com/gitlab-docs/blob/master/.gitlab-ci.yml +# Overriding vars in https://gitlab.com/gitlab-org/gitlab-docs/blob/master/.gitlab-ci.yml # def param_name "BRANCH_#{slug.upcase}" @@ -105,8 +105,8 @@ def trigger_pipeline puts "" puts app_url puts "" - puts "=> For more information, read the documentation" - puts "=> https://docs.gitlab.com/ee/development/writing_documentation.html#previewing-the-changes-live" + puts "=> For more information, see the documentation" + puts "=> https://docs.gitlab.com/ee/development/documentation/index.html#previewing-the-changes-live" puts "" puts "=> If something doesn't work, drop a line in the #docs chat channel." puts "" diff --git a/scripts/utils.sh b/scripts/utils.sh index 4a6567b8a62..f0f08e2e1c5 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -29,6 +29,8 @@ function setup_db() { if [ "$GITLAB_DATABASE" = "mysql" ]; then bundle exec rake add_limits_mysql fi + + bundle exec rake gitlab:db:setup_ee } function install_api_client_dependencies_with_apk() { |
