diff options
189 files changed, 2456 insertions, 1193 deletions
diff --git a/.flayignore b/.flayignore index 47597025115..e2d0a2e50c5 100644 --- a/.flayignore +++ b/.flayignore @@ -3,3 +3,4 @@ lib/gitlab/sanitizers/svg/whitelist.rb lib/gitlab/diff/position_tracer.rb app/policies/project_policy.rb app/models/concerns/relative_positioning.rb +lib/gitlab/redis/*.rb diff --git a/.gitignore b/.gitignore index 0d6194dd1e5..3baf640a9c3 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,9 @@ eslint-report.html /config/initializers/smtp_settings.rb /config/initializers/relative_url.rb /config/resque.yml +/config/redis.cache.yml +/config/redis.queues.yml +/config/redis.shared_state.yml /config/unicorn.rb /config/secrets.yml /config/sidekiq.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f7ab0259448..a54b38d284d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -203,69 +203,69 @@ setup-test-env: - public/assets - tmp/tests -rspec-pg 0 20: *rspec-knapsack-pg -rspec-pg 1 20: *rspec-knapsack-pg -rspec-pg 2 20: *rspec-knapsack-pg -rspec-pg 3 20: *rspec-knapsack-pg -rspec-pg 4 20: *rspec-knapsack-pg -rspec-pg 5 20: *rspec-knapsack-pg -rspec-pg 6 20: *rspec-knapsack-pg -rspec-pg 7 20: *rspec-knapsack-pg -rspec-pg 8 20: *rspec-knapsack-pg -rspec-pg 9 20: *rspec-knapsack-pg -rspec-pg 10 20: *rspec-knapsack-pg -rspec-pg 11 20: *rspec-knapsack-pg -rspec-pg 12 20: *rspec-knapsack-pg -rspec-pg 13 20: *rspec-knapsack-pg -rspec-pg 14 20: *rspec-knapsack-pg -rspec-pg 15 20: *rspec-knapsack-pg -rspec-pg 16 20: *rspec-knapsack-pg -rspec-pg 17 20: *rspec-knapsack-pg -rspec-pg 18 20: *rspec-knapsack-pg -rspec-pg 19 20: *rspec-knapsack-pg - -rspec-mysql 0 20: *rspec-knapsack-mysql -rspec-mysql 1 20: *rspec-knapsack-mysql -rspec-mysql 2 20: *rspec-knapsack-mysql -rspec-mysql 3 20: *rspec-knapsack-mysql -rspec-mysql 4 20: *rspec-knapsack-mysql -rspec-mysql 5 20: *rspec-knapsack-mysql -rspec-mysql 6 20: *rspec-knapsack-mysql -rspec-mysql 7 20: *rspec-knapsack-mysql -rspec-mysql 8 20: *rspec-knapsack-mysql -rspec-mysql 9 20: *rspec-knapsack-mysql -rspec-mysql 10 20: *rspec-knapsack-mysql -rspec-mysql 11 20: *rspec-knapsack-mysql -rspec-mysql 12 20: *rspec-knapsack-mysql -rspec-mysql 13 20: *rspec-knapsack-mysql -rspec-mysql 14 20: *rspec-knapsack-mysql -rspec-mysql 15 20: *rspec-knapsack-mysql -rspec-mysql 16 20: *rspec-knapsack-mysql -rspec-mysql 17 20: *rspec-knapsack-mysql -rspec-mysql 18 20: *rspec-knapsack-mysql -rspec-mysql 19 20: *rspec-knapsack-mysql - -spinach-pg 0 10: *spinach-knapsack-pg -spinach-pg 1 10: *spinach-knapsack-pg -spinach-pg 2 10: *spinach-knapsack-pg -spinach-pg 3 10: *spinach-knapsack-pg -spinach-pg 4 10: *spinach-knapsack-pg -spinach-pg 5 10: *spinach-knapsack-pg -spinach-pg 6 10: *spinach-knapsack-pg -spinach-pg 7 10: *spinach-knapsack-pg -spinach-pg 8 10: *spinach-knapsack-pg -spinach-pg 9 10: *spinach-knapsack-pg - -spinach-mysql 0 10: *spinach-knapsack-mysql -spinach-mysql 1 10: *spinach-knapsack-mysql -spinach-mysql 2 10: *spinach-knapsack-mysql -spinach-mysql 3 10: *spinach-knapsack-mysql -spinach-mysql 4 10: *spinach-knapsack-mysql -spinach-mysql 5 10: *spinach-knapsack-mysql -spinach-mysql 6 10: *spinach-knapsack-mysql -spinach-mysql 7 10: *spinach-knapsack-mysql -spinach-mysql 8 10: *spinach-knapsack-mysql -spinach-mysql 9 10: *spinach-knapsack-mysql +rspec-pg 0 25: *rspec-knapsack-pg +rspec-pg 1 25: *rspec-knapsack-pg +rspec-pg 2 25: *rspec-knapsack-pg +rspec-pg 3 25: *rspec-knapsack-pg +rspec-pg 4 25: *rspec-knapsack-pg +rspec-pg 5 25: *rspec-knapsack-pg +rspec-pg 6 25: *rspec-knapsack-pg +rspec-pg 7 25: *rspec-knapsack-pg +rspec-pg 8 25: *rspec-knapsack-pg +rspec-pg 9 25: *rspec-knapsack-pg +rspec-pg 10 25: *rspec-knapsack-pg +rspec-pg 11 25: *rspec-knapsack-pg +rspec-pg 12 25: *rspec-knapsack-pg +rspec-pg 13 25: *rspec-knapsack-pg +rspec-pg 14 25: *rspec-knapsack-pg +rspec-pg 15 25: *rspec-knapsack-pg +rspec-pg 16 25: *rspec-knapsack-pg +rspec-pg 17 25: *rspec-knapsack-pg +rspec-pg 18 25: *rspec-knapsack-pg +rspec-pg 19 25: *rspec-knapsack-pg +rspec-pg 20 25: *rspec-knapsack-pg +rspec-pg 21 25: *rspec-knapsack-pg +rspec-pg 22 25: *rspec-knapsack-pg +rspec-pg 23 25: *rspec-knapsack-pg +rspec-pg 24 25: *rspec-knapsack-pg + +rspec-mysql 0 25: *rspec-knapsack-mysql +rspec-mysql 1 25: *rspec-knapsack-mysql +rspec-mysql 2 25: *rspec-knapsack-mysql +rspec-mysql 3 25: *rspec-knapsack-mysql +rspec-mysql 4 25: *rspec-knapsack-mysql +rspec-mysql 5 25: *rspec-knapsack-mysql +rspec-mysql 6 25: *rspec-knapsack-mysql +rspec-mysql 7 25: *rspec-knapsack-mysql +rspec-mysql 8 25: *rspec-knapsack-mysql +rspec-mysql 9 25: *rspec-knapsack-mysql +rspec-mysql 10 25: *rspec-knapsack-mysql +rspec-mysql 11 25: *rspec-knapsack-mysql +rspec-mysql 12 25: *rspec-knapsack-mysql +rspec-mysql 13 25: *rspec-knapsack-mysql +rspec-mysql 14 25: *rspec-knapsack-mysql +rspec-mysql 15 25: *rspec-knapsack-mysql +rspec-mysql 16 25: *rspec-knapsack-mysql +rspec-mysql 17 25: *rspec-knapsack-mysql +rspec-mysql 18 25: *rspec-knapsack-mysql +rspec-mysql 19 25: *rspec-knapsack-mysql +rspec-mysql 20 25: *rspec-knapsack-mysql +rspec-mysql 21 25: *rspec-knapsack-mysql +rspec-mysql 22 25: *rspec-knapsack-mysql +rspec-mysql 23 25: *rspec-knapsack-mysql +rspec-mysql 24 25: *rspec-knapsack-mysql + +spinach-pg 0 5: *spinach-knapsack-pg +spinach-pg 1 5: *spinach-knapsack-pg +spinach-pg 2 5: *spinach-knapsack-pg +spinach-pg 3 5: *spinach-knapsack-pg +spinach-pg 4 5: *spinach-knapsack-pg + +spinach-mysql 0 5: *spinach-knapsack-mysql +spinach-mysql 1 5: *spinach-knapsack-mysql +spinach-mysql 2 5: *spinach-knapsack-mysql +spinach-mysql 3 5: *spinach-knapsack-mysql +spinach-mysql 4 5: *spinach-knapsack-mysql # Static analysis jobs .ruby-static-analysis: &ruby-static-analysis diff --git a/.scss-lint.yml b/.scss-lint.yml index db234ad739c..b38e8b90c09 100644 --- a/.scss-lint.yml +++ b/.scss-lint.yml @@ -93,7 +93,7 @@ linters: # The basenames of @imported SCSS partials should not begin with an # underscore and should not include the filename extension. ImportPath: - enabled: false + enabled: true # Avoid using !important in properties. It is usually indicative of a # misunderstanding of CSS specificity and can lead to brittle code. @@ -133,7 +133,7 @@ linters: # Reports when you use an unknown or disabled CSS property # (ignoring vendor-prefixed properties). PropertySpelling: - enabled: false + enabled: true # Configure which units are allowed for property values. PropertyUnits: @@ -176,6 +176,10 @@ linters: # Commas in lists should be followed by a space. SpaceAfterComma: + enabled: true + + # Comment literals should be followed by a space. + SpaceAfterComment: enabled: false # Properties should be formatted with a single space separating the colon diff --git a/CHANGELOG.md b/CHANGELOG.md index c15a59d25d4..c181aba0205 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ documentation](doc/development/changelog.md) for instructions on adding your own entry. +## 9.3.6 (2017-07-12) + +- Fix API Scoping. !12300 +- Username and password are no longer stripped from import url on mirror update. !12725 +- Fix issues with non-UTF8 filenames by always fixing the encoding of tree and blob paths. +- Fixed GFM references not being included when updating issues inline. + ## 9.3.5 (2017-07-05) - Remove "Remove from board" button from backlog and closed list. !12430 diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 04a373efe6b..c5523bd09b1 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0.16.0 +0.17.0 diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION index ac14c3dfaa8..e230c8396d1 100644 --- a/GITLAB_SHELL_VERSION +++ b/GITLAB_SHELL_VERSION @@ -1 +1 @@ -5.1.1 +5.3.0
\ No newline at end of file @@ -250,7 +250,6 @@ gem 'jquery-rails', '~> 4.1.0' gem 'request_store', '~> 1.3' gem 'select2-rails', '~> 3.5.9' gem 'virtus', '~> 1.0.1' -gem 'net-ssh', '~> 3.0.1' gem 'base32', '~> 0.3.0' # Sentry integration @@ -335,7 +334,7 @@ group :development, :test do gem 'rubocop', '~> 0.47.1', require: false gem 'rubocop-rspec', '~> 1.15.0', require: false - gem 'scss_lint', '~> 0.47.0', require: false + gem 'scss_lint', '~> 0.54.0', require: false gem 'haml_lint', '~> 0.21.0', require: false gem 'simplecov', '~> 0.14.0', require: false gem 'flay', '~> 2.8.0', require: false diff --git a/Gemfile.lock b/Gemfile.lock index deaf3ded2f9..c27c06e9c34 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -472,7 +472,6 @@ GEM mustermann (= 0.4.0) mysql2 (0.3.20) net-ldap (0.12.1) - net-ssh (3.0.1) netrc (0.11.0) nokogiri (1.6.8.1) mini_portile2 (~> 2.1.0) @@ -763,9 +762,9 @@ GEM sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) - scss_lint (0.47.1) - rake (>= 0.9, < 11) - sass (~> 3.4.15) + scss_lint (0.54.0) + rake (>= 0.9, < 13) + sass (~> 3.4.20) securecompare (1.0.0) seed-fu (2.3.6) activerecord (>= 3.1) @@ -780,7 +779,7 @@ GEM rack shoulda-matchers (2.8.0) activesupport (>= 3.0.0) - sidekiq (5.0.0) + sidekiq (5.0.4) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) @@ -1013,7 +1012,6 @@ DEPENDENCIES minitest (~> 5.7.0) mousetrap-rails (~> 1.4.6) mysql2 (~> 0.3.16) - net-ssh (~> 3.0.1) nokogiri (~> 1.6.7, >= 1.6.7.2) oauth2 (~> 1.4) octokit (~> 4.6.2) @@ -1083,7 +1081,7 @@ DEPENDENCIES rugged (~> 0.25.1.1) sanitize (~> 2.0) sass-rails (~> 5.0.6) - scss_lint (~> 0.47.0) + scss_lint (~> 0.54.0) seed-fu (~> 2.3.5) select2-rails (~> 3.5.9) sentry-raven (~> 2.5.3) diff --git a/app/assets/images/new_nav.png b/app/assets/images/new_nav.png Binary files differindex 8879d26d341..f98ca15d787 100644 --- a/app/assets/images/new_nav.png +++ b/app/assets/images/new_nav.png diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 83a8eeaafde..0665622fe4a 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -42,4 +42,4 @@ /* * Styles for JS behaviors. */ -@import "behaviors.scss"; +@import "behaviors"; diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss index 9dc9f9a9068..6ce331a9129 100644 --- a/app/assets/stylesheets/framework.scss +++ b/app/assets/stylesheets/framework.scss @@ -4,49 +4,49 @@ @import 'framework/tw_bootstrap'; @import "framework/layout"; -@import "framework/animations.scss"; -@import "framework/avatar.scss"; -@import "framework/asciidoctor.scss"; -@import "framework/blocks.scss"; -@import "framework/buttons.scss"; -@import "framework/badges.scss"; -@import "framework/calendar.scss"; -@import "framework/callout.scss"; -@import "framework/common.scss"; -@import "framework/dropdowns.scss"; -@import "framework/files.scss"; -@import "framework/filters.scss"; -@import "framework/flash.scss"; -@import "framework/forms.scss"; -@import "framework/gfm.scss"; -@import "framework/header.scss"; -@import "framework/highlight.scss"; -@import "framework/issue_box.scss"; -@import "framework/jquery.scss"; -@import "framework/lists.scss"; -@import "framework/logo.scss"; -@import "framework/markdown_area.scss"; -@import "framework/mobile.scss"; -@import "framework/modal.scss"; -@import "framework/nav.scss"; -@import "framework/pagination.scss"; -@import "framework/panels.scss"; -@import "framework/selects.scss"; -@import "framework/sidebar.scss"; -@import "framework/tables.scss"; -@import "framework/notes.scss"; -@import "framework/timeline.scss"; -@import "framework/typography.scss"; -@import "framework/zen.scss"; +@import "framework/animations"; +@import "framework/avatar"; +@import "framework/asciidoctor"; +@import "framework/blocks"; +@import "framework/buttons"; +@import "framework/badges"; +@import "framework/calendar"; +@import "framework/callout"; +@import "framework/common"; +@import "framework/dropdowns"; +@import "framework/files"; +@import "framework/filters"; +@import "framework/flash"; +@import "framework/forms"; +@import "framework/gfm"; +@import "framework/header"; +@import "framework/highlight"; +@import "framework/issue_box"; +@import "framework/jquery"; +@import "framework/lists"; +@import "framework/logo"; +@import "framework/markdown_area"; +@import "framework/mobile"; +@import "framework/modal"; +@import "framework/nav"; +@import "framework/pagination"; +@import "framework/panels"; +@import "framework/selects"; +@import "framework/sidebar"; +@import "framework/tables"; +@import "framework/notes"; +@import "framework/timeline"; +@import "framework/typography"; +@import "framework/zen"; @import "framework/blank"; -@import "framework/wells.scss"; -@import "framework/page-header.scss"; -@import "framework/awards.scss"; -@import "framework/images.scss"; +@import "framework/wells"; +@import "framework/page-header"; +@import "framework/awards"; +@import "framework/images"; @import "framework/broadcast-messages"; -@import "framework/emojis.scss"; -@import "framework/emoji-sprites.scss"; -@import "framework/icons.scss"; -@import "framework/snippets.scss"; -@import "framework/memory_graph.scss"; -@import "framework/responsive-tables.scss"; +@import "framework/emojis"; +@import "framework/emoji-sprites"; +@import "framework/icons"; +@import "framework/snippets"; +@import "framework/memory_graph"; +@import "framework/responsive-tables"; diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss index 19166757e64..e474839d95c 100644 --- a/app/assets/stylesheets/framework/awards.scss +++ b/app/assets/stylesheets/framework/awards.scss @@ -24,7 +24,7 @@ opacity: 0; transform: scale(.2); transform-origin: 0 -45px; - transition: .3s cubic-bezier(.67,.06,.19,1.44); + transition: .3s cubic-bezier(.67, .06, .19, 1.44); transition-property: transform, opacity; &.is-aligned-right { diff --git a/app/assets/stylesheets/framework/blank.scss b/app/assets/stylesheets/framework/blank.scss index c0224d3bfa9..6bb096fc5bd 100644 --- a/app/assets/stylesheets/framework/blank.scss +++ b/app/assets/stylesheets/framework/blank.scss @@ -1,9 +1,5 @@ .blank-state-parent-container { - display: flex; - .section-container { - display: flex; - flex: 1; padding: 10px; } @@ -13,91 +9,42 @@ padding-bottom: 25px; border: 1px solid $border-color; border-radius: $border-radius-default; - - &.section-ee-trial { - display: flex; - align-items: center; - justify-content: center; - } - } -} - -.blank-state-welcome { - text-align: center; - - .blank-state-text { - margin-bottom: 0; } } .blank-state { padding-top: 20px; padding-bottom: 20px; -} - -.blank-state.ee-trial { - padding: 20px; text-align: center; -} - -.blank-state-no-icon { - padding-top: 40px; - padding-bottom: 40px; -} - -.blank-state-icon { - padding-bottom: 20px; - font-size: 56px; - svg { - display: block; - margin: auto; - } -} - -@media (min-width: $screen-sm-max) { - .section-welcome .blank-state-icon svg { - width: 130%; - } -} - -.blank-state-title { - margin-top: 0; - margin-bottom: 10px; - font-size: 18px; -} - -.blank-state-text { - margin-top: 0; - margin-bottom: $gl-padding; - font-size: 14px; + &.blank-state-welcome { + .blank-state-welcome-title { + font-size: 24px; + } - > strong { - font-weight: 600; + .blank-state-text { + margin-bottom: 0; + } } -} -.blank-state-welcome-title { - font-size: 24px; -} + .blank-state-icon { + padding-bottom: 20px; -@media (max-width: $screen-md-min) { - .blank-state-parent-container { - &, - .section-container { + svg { display: block; + margin: auto; } } - .blank-state { - text-align: center; + .blank-state-title { + margin-top: 0; + margin-bottom: 10px; + font-size: 18px; } - .blank-state-icon { - padding-bottom: 0; - } - - .blank-state-body { - margin-top: 15px; + .blank-state-text { + max-width: $container-text-max-width; + margin: 0 auto $gl-padding; + font-size: 14px; } } diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index 00c981f64c5..5e374360359 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -336,11 +336,6 @@ table { text-align: center; } -#nprogress .spinner { - top: 15px !important; - right: 10px !important; -} - .header-with-avatar { h3 { margin: 0; @@ -450,4 +445,3 @@ table { pointer-events: none; opacity: .5; } - diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index 3f032776d82..3405f142428 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -176,6 +176,7 @@ $header-height: 50px; $fixed-layout-width: 1280px; $limited-layout-width: 990px; $limited-layout-width-sm: 790px; +$container-text-max-width: 540px; $gl-avatar-size: 40px; $error-exclamation-point: $red-500; $border-radius-default: 3px; @@ -316,7 +317,7 @@ $badge-color: $gl-text-color-secondary; /* * Award emoji */ -$award-emoji-menu-shadow: rgba(0,0,0,.175); +$award-emoji-menu-shadow: rgba(0, 0, 0, .175); $award-emoji-positive-add-bg: #fed159; $award-emoji-positive-add-lines: #bb9c13; @@ -567,7 +568,7 @@ $kdb-color: #555; $kdb-border: #ccc; $kdb-border-bottom: #bbb; $kdb-shadow: #bbb; -$body-text-shadow: rgba(255,255,255,0.01); +$body-text-shadow: rgba(255, 255, 255, 0.01); /* * UI Dev Kit diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 1daa10aef24..578f1902cce 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -113,7 +113,7 @@ $white-gc-bg: #eaf2f5; border-color: $line-removed-dark; a { - color: scale-color($line-number-old,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-old, $red: -30%, $green: -30%, $blue: -30%); } } @@ -122,7 +122,7 @@ $white-gc-bg: #eaf2f5; border-color: $line-added-dark; a { - color: scale-color($line-number-new,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-new, $red: -30%, $green: -30%, $blue: -30%); } } @@ -163,7 +163,7 @@ $white-gc-bg: #eaf2f5; background-color: $line-removed; &::before { - color: scale-color($line-number-old,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-old, $red: -30%, $green: -30%, $blue: -30%); } span.idiff { @@ -175,7 +175,7 @@ $white-gc-bg: #eaf2f5; background-color: $line-added; &::before { - color: scale-color($line-number-new,$red: -30%, $green: -30%, $blue: -30%); + color: scale-color($line-number-new, $red: -30%, $green: -30%, $blue: -30%); } span.idiff { diff --git a/app/assets/stylesheets/new_sidebar.scss b/app/assets/stylesheets/new_sidebar.scss index 96459fe31cc..07b487cd090 100644 --- a/app/assets/stylesheets/new_sidebar.scss +++ b/app/assets/stylesheets/new_sidebar.scss @@ -2,12 +2,12 @@ @import 'framework/tw_bootstrap_variables'; @import "bootstrap/variables"; -$active-background: rgba(0,0,0,.04); +$active-background: rgba(0, 0, 0, .04); $active-border: $indigo-500; $active-color: $indigo-700; $active-hover-background: $active-background; $active-hover-color: $gl-text-color; -$inactive-badge-background: rgba(0,0,0,.08); +$inactive-badge-background: rgba(0, 0, 0, .08); $hover-background: $indigo-700; $hover-color: $white-light; $inactive-color: $gl-text-color-secondary; diff --git a/app/assets/stylesheets/pages/builds.scss b/app/assets/stylesheets/pages/builds.scss index 23c06eca3c3..0393820dee6 100644 --- a/app/assets/stylesheets/pages/builds.scss +++ b/app/assets/stylesheets/pages/builds.scss @@ -6,26 +6,26 @@ @keyframes blinking-dots { 0% { background-color: rgba($white-light, 1); - box-shadow: 12px 0 0 0 rgba($white-light,0.2), - 24px 0 0 0 rgba($white-light,0.2); + box-shadow: 12px 0 0 0 rgba($white-light, 0.2), + 24px 0 0 0 rgba($white-light, 0.2); } 25% { background-color: rgba($white-light, 0.4); - box-shadow: 12px 0 0 0 rgba($white-light,2), - 24px 0 0 0 rgba($white-light,0.2); + box-shadow: 12px 0 0 0 rgba($white-light, 2), + 24px 0 0 0 rgba($white-light, 0.2); } 75% { background-color: rgba($white-light, 0.4); - box-shadow: 12px 0 0 0 rgba($white-light,0.2), - 24px 0 0 0 rgba($white-light,1); + box-shadow: 12px 0 0 0 rgba($white-light, 0.2), + 24px 0 0 0 rgba($white-light, 1); } 100% { background-color: rgba($white-light, 1); - box-shadow: 12px 0 0 0 rgba($white-light,0.2), - 24px 0 0 0 rgba($white-light,0.2); + box-shadow: 12px 0 0 0 rgba($white-light, 0.2), + 24px 0 0 0 rgba($white-light, 0.2); } } diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index 7adf17dddb8..d48dec8fe7a 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -125,7 +125,7 @@ .dropdown-menu { margin-top: 11px; - z-index: 200; + z-index: 300; } .ci-action-icon-wrapper { diff --git a/app/controllers/concerns/requires_health_token.rb b/app/controllers/concerns/requires_health_token.rb deleted file mode 100644 index 34ab1a97649..00000000000 --- a/app/controllers/concerns/requires_health_token.rb +++ /dev/null @@ -1,25 +0,0 @@ -module RequiresHealthToken - extend ActiveSupport::Concern - included do - before_action :validate_health_check_access! - end - - private - - def validate_health_check_access! - render_404 unless token_valid? - end - - def token_valid? - token = params[:token].presence || request.headers['TOKEN'] - token.present? && - ActiveSupport::SecurityUtils.variable_size_secure_compare( - token, - current_application_settings.health_check_access_token - ) - end - - def render_404 - render file: Rails.root.join('public', '404'), layout: false, status: '404' - end -end diff --git a/app/controllers/concerns/requires_whitelisted_monitoring_client.rb b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb new file mode 100644 index 00000000000..ad2f4bbc486 --- /dev/null +++ b/app/controllers/concerns/requires_whitelisted_monitoring_client.rb @@ -0,0 +1,33 @@ +module RequiresWhitelistedMonitoringClient + extend ActiveSupport::Concern + included do + before_action :validate_ip_whitelisted_or_valid_token! + end + + private + + def validate_ip_whitelisted_or_valid_token! + render_404 unless client_ip_whitelisted? || valid_token? + end + + def client_ip_whitelisted? + ip_whitelist.any? { |e| e.include?(Gitlab::RequestContext.client_ip) } + end + + def ip_whitelist + @ip_whitelist ||= Settings.monitoring.ip_whitelist.map(&IPAddr.method(:new)) + end + + def valid_token? + token = params[:token].presence || request.headers['TOKEN'] + token.present? && + ActiveSupport::SecurityUtils.variable_size_secure_compare( + token, + current_application_settings.health_check_access_token + ) + end + + def render_404 + render file: Rails.root.join('public', '404'), layout: false, status: '404' + end +end diff --git a/app/controllers/health_check_controller.rb b/app/controllers/health_check_controller.rb index 5d3109b7187..c3d18991fd4 100644 --- a/app/controllers/health_check_controller.rb +++ b/app/controllers/health_check_controller.rb @@ -1,3 +1,3 @@ class HealthCheckController < HealthCheck::HealthCheckController - include RequiresHealthToken + include RequiresWhitelistedMonitoringClient end diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index abc832e6ddc..98c2aaa3526 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,10 +1,13 @@ class HealthController < ActionController::Base protect_from_forgery with: :exception - include RequiresHealthToken + include RequiresWhitelistedMonitoringClient CHECKS = [ Gitlab::HealthChecks::DbCheck, - Gitlab::HealthChecks::RedisCheck, + Gitlab::HealthChecks::Redis::RedisCheck, + Gitlab::HealthChecks::Redis::CacheCheck, + Gitlab::HealthChecks::Redis::QueuesCheck, + Gitlab::HealthChecks::Redis::SharedStateCheck, Gitlab::HealthChecks::FsShardsCheck ].freeze diff --git a/app/controllers/metrics_controller.rb b/app/controllers/metrics_controller.rb index 0e9a19c0b6f..37587a52eaf 100644 --- a/app/controllers/metrics_controller.rb +++ b/app/controllers/metrics_controller.rb @@ -1,12 +1,12 @@ class MetricsController < ActionController::Base - include RequiresHealthToken + include RequiresWhitelistedMonitoringClient protect_from_forgery with: :exception before_action :validate_prometheus_metrics def index - render text: metrics_service.metrics_text, content_type: 'text/plain; verssion=0.0.4' + render text: metrics_service.metrics_text, content_type: 'text/plain; version=0.0.4' end private diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb index fb0fbb43fb1..c6d23898560 100644 --- a/app/models/ci/runner.rb +++ b/app/models/ci/runner.rb @@ -149,7 +149,7 @@ module Ci private def cleanup_runner_queue - Gitlab::Redis.with do |redis| + Gitlab::Redis::Queues.with do |redis| redis.del(runner_queue_key) end end diff --git a/app/models/project.rb b/app/models/project.rb index d5760164663..e50818e3dff 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1386,15 +1386,15 @@ class Project < ActiveRecord::Base end def pushes_since_gc - Gitlab::Redis.with { |redis| redis.get(pushes_since_gc_redis_key).to_i } + Gitlab::Redis::SharedState.with { |redis| redis.get(pushes_since_gc_redis_shared_state_key).to_i } end def increment_pushes_since_gc - Gitlab::Redis.with { |redis| redis.incr(pushes_since_gc_redis_key) } + Gitlab::Redis::SharedState.with { |redis| redis.incr(pushes_since_gc_redis_shared_state_key) } end def reset_pushes_since_gc - Gitlab::Redis.with { |redis| redis.del(pushes_since_gc_redis_key) } + Gitlab::Redis::SharedState.with { |redis| redis.del(pushes_since_gc_redis_shared_state_key) } end def route_map_for(commit_sha) @@ -1457,7 +1457,7 @@ class Project < ActiveRecord::Base from && self != from end - def pushes_since_gc_redis_key + def pushes_since_gc_redis_shared_state_key "projects/#{id}/pushes_since_gc" end diff --git a/app/services/metrics_service.rb b/app/services/metrics_service.rb index d726db4e99b..c92f070601c 100644 --- a/app/services/metrics_service.rb +++ b/app/services/metrics_service.rb @@ -3,7 +3,10 @@ require 'prometheus/client/formats/text' class MetricsService CHECKS = [ Gitlab::HealthChecks::DbCheck, - Gitlab::HealthChecks::RedisCheck, + Gitlab::HealthChecks::Redis::RedisCheck, + Gitlab::HealthChecks::Redis::CacheCheck, + Gitlab::HealthChecks::Redis::QueuesCheck, + Gitlab::HealthChecks::Redis::SharedStateCheck, Gitlab::HealthChecks::FsShardsCheck ].freeze diff --git a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml index 0319838bdb4..209afd4aab4 100644 --- a/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml +++ b/app/views/dashboard/projects/_blank_state_admin_welcome.html.haml @@ -1,7 +1,7 @@ -.row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon +.blank-state + .blank-state-icon = custom_icon("add_new_user", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Add user %p.blank-state-text @@ -9,10 +9,10 @@ = link_to new_admin_user_path, class: "btn btn-new" do New user -.row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon +.blank-state + .blank-state-icon = custom_icon("configure_server", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Configure GitLab %p.blank-state-text @@ -21,10 +21,10 @@ Configure - if current_user.can_create_group? - .row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon + .blank-state + .blank-state-icon = custom_icon("add_new_group", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Create a group %p.blank-state-text diff --git a/app/views/dashboard/projects/_blank_state_welcome.html.haml b/app/views/dashboard/projects/_blank_state_welcome.html.haml index a079f0ac1a4..a93a3415ee1 100644 --- a/app/views/dashboard/projects/_blank_state_welcome.html.haml +++ b/app/views/dashboard/projects/_blank_state_welcome.html.haml @@ -1,10 +1,10 @@ - public_project_count = ProjectsFinder.new(current_user: current_user).execute.count - if current_user.can_create_group? - .row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon + .blank-state + .blank-state-icon = custom_icon("add_new_group", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Create a group for several dependent projects. %p.blank-state-text @@ -12,10 +12,10 @@ = link_to new_group_path, class: "btn btn-new" do New group -.row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon +.blank-state + .blank-state-icon = custom_icon("add_new_project", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Create a project %p.blank-state-text @@ -32,10 +32,10 @@ New project - if public_project_count > 0 - .row.blank-state.clearfix - .col-md-1.col-md-offset-3.blank-state-icon + .blank-state + .blank-state-icon = custom_icon("globe", size: 50) - .col-md-5.blank-state-body + .blank-state-body %h3.blank-state-title Explore public projects %p.blank-state-text diff --git a/app/views/dashboard/projects/_zero_authorized_projects.html.haml b/app/views/dashboard/projects/_zero_authorized_projects.html.haml index 94af033c1e3..ad3fac6d164 100644 --- a/app/views/dashboard/projects/_zero_authorized_projects.html.haml +++ b/app/views/dashboard/projects/_zero_authorized_projects.html.haml @@ -1,6 +1,6 @@ .row.blank-state-parent-container - .section-container - .container.section-body.section-welcome{ class: "#{ 'section-admin-welcome' if current_user.admin? }" } + .section-container.section-welcome{ class: "#{ 'section-admin-welcome' if current_user.admin? }" } + .container.section-body .blank-state.blank-state-welcome %h2.blank-state-welcome-title Welcome to GitLab diff --git a/app/views/help/ui.html.haml b/app/views/help/ui.html.haml index 615dd56afbd..48edbb8c16f 100644 --- a/app/views/help/ui.html.haml +++ b/app/views/help/ui.html.haml @@ -525,7 +525,7 @@ %h4 %code .file-holder - - blob = Snippet.new(content: "Wow\nSuch\nFile") + - blob = Snippet.new(content: "Wow\nSuch\nFile").blob .example .file-holder .js-file-title.file-title diff --git a/app/views/layouts/nav/_breadcrumbs.html.haml b/app/views/layouts/nav/_breadcrumbs.html.haml index 5f1641f4300..b0c1ab7420f 100644 --- a/app/views/layouts/nav/_breadcrumbs.html.haml +++ b/app/views/layouts/nav/_breadcrumbs.html.haml @@ -2,7 +2,7 @@ - hide_top_links = @hide_top_links || false %nav.breadcrumbs{ role: "navigation" } - .breadcrumbs-container{ class: container_class } + .breadcrumbs-container{ class: [container_class, @content_class] } .breadcrumbs-links.js-title-container - unless hide_top_links .title diff --git a/app/views/layouts/nav/_new_project_sidebar.html.haml b/app/views/layouts/nav/_new_project_sidebar.html.haml index cc731db3cc1..8838852803b 100644 --- a/app/views/layouts/nav/_new_project_sidebar.html.haml +++ b/app/views/layouts/nav/_new_project_sidebar.html.haml @@ -74,9 +74,9 @@ = nav_link(controller: @project.default_issues_tracker? ? [:issues, :labels, :milestones, :boards] : :issues) do = link_to project_issues_path(@project), title: 'Issues', class: 'shortcuts-issues' do %span - Issues - if @project.default_issues_tracker? %span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count) + Issues %ul.sidebar-sub-level-items - if project_nav_tab?(:issues) && !current_controller?(:merge_requests) @@ -112,8 +112,8 @@ = nav_link(controller: @project.default_issues_tracker? ? :merge_requests : [:merge_requests, :labels, :milestones]) do = link_to project_merge_requests_path(@project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do %span - Merge Requests %span.badge.count.merge_counter.js-merge-counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count) + Merge Requests - if project_nav_tab? :pipelines = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :environments, :artifacts]) do diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index b778e8af121..07c83c0a590 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,6 +1,7 @@ - @no_container = true - container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : '' - limited_container_width = fluid_layout ? '' : 'limit-container-width' +- @content_class = limited_container_width - page_title "#{@commit.title} (#{@commit.short_id})", "Commits" - page_description @commit.description = render "projects/commits/head" diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml index 7b8be58554a..b0b7575f0d1 100644 --- a/app/views/projects/new.html.haml +++ b/app/views/projects/new.html.haml @@ -9,8 +9,9 @@ .col-lg-3.profile-settings-sidebar %h4.prepend-top-0 New project - %p - Create or Import your project from popular Git services + - if import_sources_enabled? + %p + Create or Import your project from popular Git services .col-lg-9 = form_for @project, html: { class: 'new_project' } do |f| .row diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml index 05fe80e5fed..c4ee064ac43 100644 --- a/app/views/projects/pipeline_schedules/index.html.haml +++ b/app/views/projects/pipeline_schedules/index.html.haml @@ -12,9 +12,10 @@ - schedule_path_proc = ->(scope) { pipeline_schedules_path(@project, scope: scope) } = render "tabs", schedule_path_proc: schedule_path_proc, all_schedules: @all_schedules, scope: @scope - .nav-controls - = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do - %span= _('New schedule') + - if can?(current_user, :create_pipeline_schedule, @project) + .nav-controls + = link_to new_project_pipeline_schedule_path(@project), class: 'btn btn-create' do + %span= _('New schedule') - if @schedules.present? %ul.content-list diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml index d413c4619be..a73e111ad6d 100644 --- a/app/views/projects/show.html.haml +++ b/app/views/projects/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- @content_class = "limit-container-width" unless fluid_layout - flash_message_container = show_new_nav? ? :new_global_flash : :flash_message = content_for :meta_tags do diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml index 130980556c1..f727f340bb9 100644 --- a/app/views/projects/tree/show.html.haml +++ b/app/views/projects/tree/show.html.haml @@ -1,4 +1,5 @@ - @no_container = true +- @content_class = "limit-container-width" unless fluid_layout - page_title @path.presence || _("Files"), @ref = content_for :meta_tags do diff --git a/changelogs/unreleased/33580-fix-api-scoping.yml b/changelogs/unreleased/33580-fix-api-scoping.yml deleted file mode 100644 index f4ebb13c082..00000000000 --- a/changelogs/unreleased/33580-fix-api-scoping.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fix API Scoping -merge_request: 12300 -author: diff --git a/changelogs/unreleased/33949-deprecate-healthcheck-access-token.yml b/changelogs/unreleased/33949-deprecate-healthcheck-access-token.yml new file mode 100644 index 00000000000..a08795e1a26 --- /dev/null +++ b/changelogs/unreleased/33949-deprecate-healthcheck-access-token.yml @@ -0,0 +1,4 @@ +--- +title: Deprecate Healthcheck Access Token in favor of IP whitelist +merge_request: +author: diff --git a/changelogs/unreleased/34729-blob.yml b/changelogs/unreleased/34729-blob.yml new file mode 100644 index 00000000000..15a469d3af0 --- /dev/null +++ b/changelogs/unreleased/34729-blob.yml @@ -0,0 +1,4 @@ +--- +title: Fix crash on /help/ui +merge_request: +author: diff --git a/changelogs/unreleased/34858-bump-scss-lint-to-0-54-0.yml b/changelogs/unreleased/34858-bump-scss-lint-to-0-54-0.yml new file mode 100644 index 00000000000..e6cd834aed2 --- /dev/null +++ b/changelogs/unreleased/34858-bump-scss-lint-to-0-54-0.yml @@ -0,0 +1,4 @@ +--- +title: Bump scss-lint to 0.54.0 +merge_request: 12733 +author: Takuya Noguchi diff --git a/changelogs/unreleased/34867-remove-net-ssh-gem.yml b/changelogs/unreleased/34867-remove-net-ssh-gem.yml new file mode 100644 index 00000000000..f5648d62467 --- /dev/null +++ b/changelogs/unreleased/34867-remove-net-ssh-gem.yml @@ -0,0 +1,4 @@ +--- +title: Remove net-ssh gem +merge_request: +author: Takuya Noguchi diff --git a/changelogs/unreleased/34907-dont-show-pipeline-schedule-button-for-non-member.yml b/changelogs/unreleased/34907-dont-show-pipeline-schedule-button-for-non-member.yml new file mode 100644 index 00000000000..22c9c45bc75 --- /dev/null +++ b/changelogs/unreleased/34907-dont-show-pipeline-schedule-button-for-non-member.yml @@ -0,0 +1,4 @@ +--- +title: Do not show pipeline schedule button for non-member +merge_request: 12757 +author: Takuya Noguchi diff --git a/changelogs/unreleased/dm-encode-tree-and-blob-paths.yml b/changelogs/unreleased/dm-encode-tree-and-blob-paths.yml deleted file mode 100644 index c1a026e1f29..00000000000 --- a/changelogs/unreleased/dm-encode-tree-and-blob-paths.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: Fix issues with non-UTF8 filenames by always fixing the encoding of tree and - blob paths -merge_request: -author: diff --git a/changelogs/unreleased/enable-scss-lint-import-path.yml b/changelogs/unreleased/enable-scss-lint-import-path.yml new file mode 100644 index 00000000000..d158cf5b5f3 --- /dev/null +++ b/changelogs/unreleased/enable-scss-lint-import-path.yml @@ -0,0 +1,4 @@ +--- +title: Enable ImportPath in scss-lint +merge_request: 12749 +author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-property-spelling.yml b/changelogs/unreleased/enable-scss-lint-property-spelling.yml new file mode 100644 index 00000000000..c5a5a4dddb6 --- /dev/null +++ b/changelogs/unreleased/enable-scss-lint-property-spelling.yml @@ -0,0 +1,4 @@ +--- +title: Enable PropertySpelling in scss-lint +merge_request: 12752 +author: Takuya Noguchi diff --git a/changelogs/unreleased/enable-scss-lint-space-after-comma.yml b/changelogs/unreleased/enable-scss-lint-space-after-comma.yml new file mode 100644 index 00000000000..210f34fbb87 --- /dev/null +++ b/changelogs/unreleased/enable-scss-lint-space-after-comma.yml @@ -0,0 +1,4 @@ +--- +title: Enable SpaceAfterComma in scss-lint +merge_request: 12734 +author: Takuya Noguchi diff --git a/changelogs/unreleased/fix-n-plus-one-in-url-builder.yml b/changelogs/unreleased/fix-n-plus-one-in-url-builder.yml new file mode 100644 index 00000000000..5781316cfd9 --- /dev/null +++ b/changelogs/unreleased/fix-n-plus-one-in-url-builder.yml @@ -0,0 +1,4 @@ +--- +title: Improve issue rendering performance with lots of notes from other users +merge_request: +author: diff --git a/changelogs/unreleased/issue-description-gfm.yml b/changelogs/unreleased/issue-description-gfm.yml deleted file mode 100644 index 4d421bff677..00000000000 --- a/changelogs/unreleased/issue-description-gfm.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fixed GFM references not being included when updating issues inline -merge_request: -author: diff --git a/changelogs/unreleased/remove-nprogress-gleaning.yml b/changelogs/unreleased/remove-nprogress-gleaning.yml new file mode 100644 index 00000000000..78e4dc82dd4 --- /dev/null +++ b/changelogs/unreleased/remove-nprogress-gleaning.yml @@ -0,0 +1,4 @@ +--- +title: Remove CSS for nprogress removed +merge_request: 12737 +author: Takuya Noguchi diff --git a/changelogs/unreleased/sh-add-mr-simple-mode.yml b/changelogs/unreleased/sh-add-mr-simple-mode.yml new file mode 100644 index 00000000000..0033ca28444 --- /dev/null +++ b/changelogs/unreleased/sh-add-mr-simple-mode.yml @@ -0,0 +1,4 @@ +--- +title: Add a simple mode to merge request API +merge_request: +author: diff --git a/changelogs/unreleased/toggle-new-project-import-description.yml b/changelogs/unreleased/toggle-new-project-import-description.yml new file mode 100644 index 00000000000..8f0d09e0540 --- /dev/null +++ b/changelogs/unreleased/toggle-new-project-import-description.yml @@ -0,0 +1,4 @@ +--- +title: Toggle import description with import_sources_enabled +merge_request: 12691 +author: Brianna Kicia
\ No newline at end of file diff --git a/changelogs/unreleased/username-password-stripped-from-import-url-fix.yml b/changelogs/unreleased/username-password-stripped-from-import-url-fix.yml deleted file mode 100644 index 571279d3dc7..00000000000 --- a/changelogs/unreleased/username-password-stripped-from-import-url-fix.yml +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Username and password are no longer stripped from import url on mirror update -merge_request: 12725 -author: diff --git a/config/README.md b/config/README.md index 0a5ea2424e0..2778d0d4f02 100644 --- a/config/README.md +++ b/config/README.md @@ -19,4 +19,132 @@ an ERB file and then loads the resulting YML as its configuration. This file is called `resque.yml` for historical reasons. We are **NOT** using Resque at the moment. It is used to specify Redis configuration -values instead. +values when a single database instance of Redis is desired. + +# Advanced Redis configuration files + +In more advanced configurations of Redis key-value storage, it is desirable +to separate the keys by lifecycle and intended use to ease provisioning and +management of scalable Redis clusters. + +These settings provide routing and other configuration data (such as sentinel, +persistence policies, and other Redis customization) for connections +to Redis single instances, Redis sentinel, and Redis clusters. + +If desired, the routing URL provided by these settings can be used with: +1. Unix Socket + 1. named socket for each Redis instance desired. + 2. `database number` for each Redis instance desired. +2. TCP Socket + 1. `host name` or IP for each Redis instance desired + 2. TCP port number for each Redis instance desired + 3. `database number` for each Redis instance desired + +## Example URL attribute formats for GitLab Redis `.yml` configuration files +* Unix Socket, default Redis database (0) + * `url: unix:/path/to/redis.sock` + * `url: unix:/path/to/redis.sock?db=` +* Unix Socket, Redis database 44 + * `url: unix:/path/to/redis.sock?db=44` + * `url: unix:/path/to/redis.sock?extra=foo&db=44` +* TCP Socket for Redis on localhost, port 6379, database 33 + * `url: redis://:mynewpassword@localhost:6379/33` +* TCP Socket for Redis on remote host `myserver`, port 6379, database 33 + * `url: redis://:mynewpassword@myserver:6379/33` + +## redis.cache.yml + +If configured, `redis.cache.yml` overrides the +`resque.yml` settings to configure the Redis database instance +used for `Rails.cache` and other volatile non-persistent data which enhances +the performance of GitLab. +Settings here can be overridden by the environment variable +`GITLAB_REDIS_CACHE_CONFIG_FILE` which provides +an alternate location for configuration settings. + +The order of precedence for the URL used to connect to the Redis instance +used for `cache` is: +1. URL from a configuration file pointed to by the +`GITLAB_REDIS_CACHE_CONFIG_FILE` environment variable +2. URL from `redis.cache.yml` +3. URL from a configuration file pointed to by the +`GITLAB_REDIS_CONFIG_FILE` environment variable +4. URL from `resque.yml` +5. `redis://localhost:6380` + +The order of precedence for all other configuration settings for `cache` +are selected from only the first of the following files found (if a setting +is not provided in an earlier file, the remainder of the files are not +searched): +1. the configuration file pointed to by the +`GITLAB_REDIS_CACHE_CONFIG_FILE` environment variable +2. the configuration file `redis.cache.yml` +3. the configuration file pointed to by the +`GITLAB_REDIS_CONFIG_FILE` environment variable +4. the configuration file `resque.yml` + +## redis.queues.yml + +If configured, `redis.queues.yml` overrides the +`resque.yml` settings to configure the Redis database instance +used for clients of `::Gitlab::Redis::Queues`. +These queues are intended to be the foundation +of reliable inter-process communication between modules, whether on the same +host node, or within a cluster. The primary clients of the queues are +SideKiq, Mailroom, CI Runner, Workhorse, and push services. Settings here can +be overridden by the environment variable +`GITLAB_REDIS_QUEUES_CONFIG_FILE` which provides an alternate location for +configuration settings. + +The order of precedence for the URL used to connect to the Redis instance +used for `queues` is: +1. URL from a configuration file pointed to by the +`GITLAB_REDIS_QUEUES_CONFIG_FILE` environment variable +2. URL from `redis.queues.yml` +3. URL from a configuration file pointed to by the +`GITLAB_REDIS_CONFIG_FILE` environment variable +4. URL from `resque.yml` +5. `redis://localhost:6381` + +The order of precedence for all other configuration settings for `queues` +are selected from only the first of the following files found (if a setting +is not provided in an earlier file, the remainder of the files are not +searched): +1. the configuration file pointed to by the +`GITLAB_REDIS_QUEUES_CONFIG_FILE` environment variable +2. the configuration file `redis.queues.yml` +3. the configuration file pointed to by the +`GITLAB_REDIS_CONFIG_FILE` environment variable +4. the configuration file `resque.yml` + +## redis.shared_state.yml + +If configured, `redis.shared_state.yml` overrides the +`resque.yml` settings to configure the Redis database instance +used for clients of `::Gitlab::Redis::SharedState` such as session state, +and rate limiting. +Settings here can be overridden by the environment variable +`GITLAB_REDIS_SHARED_STATE_CONFIG_FILE` which provides +an alternate location for configuration settings. + +The order of precedence for the URL used to connect to the Redis instance +used for `shared_state` is: +1. URL from a configuration file pointed to by the +`GITLAB_REDIS_SHARED_STATE_CONFIG_FILE` environment variable +2. URL from `redis.shared_state.yml` +3. URL from a configuration file pointed to by the +`GITLAB_REDIS_CONFIG_FILE` environment variable +4. URL from `resque.yml` +5. `redis://localhost:6382` + +The order of precedence for all other configuration settings for `shared_state` +are selected from only the first of the following files found (if a setting +is not provided in an earlier file, the remainder of the files are not +searched): +1. the configuration file pointed to by the +`GITLAB_REDIS_SHARED_STATE_CONFIG_FILE` environment variable +2. the configuration file `redis.shared_state.yml` +3. the configuration file pointed to by the +`GITLAB_REDIS_CONFIG_FILE` environment variable +4. the configuration file `resque.yml` + diff --git a/config/application.rb b/config/application.rb index 2f4e2624195..1c13cc81270 100644 --- a/config/application.rb +++ b/config/application.rb @@ -6,7 +6,9 @@ Bundler.require(:default, Rails.env) module Gitlab class Application < Rails::Application - require_dependency Rails.root.join('lib/gitlab/redis') + require_dependency Rails.root.join('lib/gitlab/redis/cache') + require_dependency Rails.root.join('lib/gitlab/redis/queues') + require_dependency Rails.root.join('lib/gitlab/redis/shared_state') require_dependency Rails.root.join('lib/gitlab/request_context') # Settings in config/environments/* take precedence over those specified here. @@ -142,15 +144,15 @@ module Gitlab end end - # Use Redis caching across all environments - redis_config_hash = Gitlab::Redis.params - redis_config_hash[:namespace] = Gitlab::Redis::CACHE_NAMESPACE - redis_config_hash[:expires_in] = 2.weeks # Cache should not grow forever + # Use caching across all environments + caching_config_hash = Gitlab::Redis::Cache.params + caching_config_hash[:namespace] = Gitlab::Redis::Cache::CACHE_NAMESPACE + caching_config_hash[:expires_in] = 2.weeks # Cache should not grow forever if Sidekiq.server? # threaded context - redis_config_hash[:pool_size] = Sidekiq.options[:concurrency] + 5 - redis_config_hash[:pool_timeout] = 1 + caching_config_hash[:pool_size] = Sidekiq.options[:concurrency] + 5 + caching_config_hash[:pool_timeout] = 1 end - config.cache_store = :redis_store, redis_config_hash + config.cache_store = :redis_store, caching_config_hash config.active_record.raise_in_transactional_callbacks = true diff --git a/config/database.yml.mysql b/config/database.yml.mysql index db1b712d3bc..eb71d3f5fe1 100644 --- a/config/database.yml.mysql +++ b/config/database.yml.mysql @@ -42,3 +42,4 @@ test: &test password: # host: localhost # socket: /tmp/mysql.sock + prepared_statements: false diff --git a/config/database.yml.postgresql b/config/database.yml.postgresql index c517a4c0cb8..4b30982fe82 100644 --- a/config/database.yml.postgresql +++ b/config/database.yml.postgresql @@ -46,3 +46,4 @@ test: &test username: postgres password: # host: localhost + prepared_statements: false diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 221e3d6e03b..d0ab2dab0af 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -539,10 +539,15 @@ production: &base # enabled: true # host: localhost # port: 3808 - prometheus: + + ## Monitoring + # Built in monitoring settings + monitoring: # Time between sampling of unicorn socket metrics, in seconds # unicorn_sampler_interval: 10 - + # IP whitelist to access monitoring endpoints + ip_whitelist: + - 127.0.0.0/8 # # 5. Extra customization diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index fa33e602e93..eb4a1e390a9 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -494,10 +494,11 @@ Settings.webpack.dev_server['host'] ||= 'localhost' Settings.webpack.dev_server['port'] ||= 3808 # -# Prometheus metrics settings +# Monitoring settings # -Settings['prometheus'] ||= Settingslogic.new({}) -Settings.prometheus['unicorn_sampler_interval'] ||= 10 +Settings['monitoring'] ||= Settingslogic.new({}) +Settings.monitoring['ip_whitelist'] ||= ['127.0.0.1/8'] +Settings.monitoring['unicorn_sampler_interval'] ||= 10 # # Testing settings diff --git a/config/initializers/7_redis.rb b/config/initializers/7_redis.rb index ae2ca258df1..af4967521b8 100644 --- a/config/initializers/7_redis.rb +++ b/config/initializers/7_redis.rb @@ -1,3 +1,8 @@ -# Make sure we initialize a Redis connection pool before Sidekiq starts -# multi-threaded execution. -Gitlab::Redis.with { nil } +# Make sure we initialize a Redis connection pool before multi-threaded +# execution starts by +# 1. Sidekiq +# 2. Rails.cache +# 3. HTTP clients +Gitlab::Redis::Cache.with { nil } +Gitlab::Redis::Queues.with { nil } +Gitlab::Redis::SharedState.with { nil } diff --git a/config/initializers/8_metrics.rb b/config/initializers/8_metrics.rb index d56fd7a6cfa..5e34aac6527 100644 --- a/config/initializers/8_metrics.rb +++ b/config/initializers/8_metrics.rb @@ -119,7 +119,7 @@ def instrument_classes(instrumentation) end # rubocop:enable Metrics/AbcSize -Gitlab::Metrics::UnicornSampler.initialize_instance(Settings.prometheus.unicorn_sampler_interval).start +Gitlab::Metrics::UnicornSampler.initialize_instance(Settings.monitoring.unicorn_sampler_interval).start Gitlab::Application.configure do |config| # 0 should be Sentry to catch errors in this middleware diff --git a/config/initializers/peek.rb b/config/initializers/peek.rb index 65432caac2a..da8282ec924 100644 --- a/config/initializers/peek.rb +++ b/config/initializers/peek.rb @@ -1,4 +1,4 @@ -Rails.application.config.peek.adapter = :redis, { client: ::Redis.new(Gitlab::Redis.params) } +Rails.application.config.peek.adapter = :redis, { client: ::Redis.new(Gitlab::Redis::Cache.params) } Peek.into Peek::Views::Host Peek.into Peek::Views::PerformanceBar diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 8919f7640fe..e8213ac8ba4 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -19,12 +19,12 @@ cookie_key = if Rails.env.development? if Rails.env.test? Gitlab::Application.config.session_store :cookie_store, key: "_gitlab_session" else - redis_config = Gitlab::Redis.params - redis_config[:namespace] = Gitlab::Redis::SESSION_NAMESPACE + sessions_config = Gitlab::Redis::SharedState.params + sessions_config[:namespace] = Gitlab::Redis::SharedState::SESSION_NAMESPACE Gitlab::Application.config.session_store( :redis_store, # Using the cookie_store would enable session replay attacks. - servers: redis_config, + servers: sessions_config, key: cookie_key, secure: Gitlab.config.gitlab.https, httponly: true, diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 3be4cd797aa..a1cc9655319 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,12 +1,12 @@ -# Custom Redis configuration -redis_config_hash = Gitlab::Redis.params -redis_config_hash[:namespace] = Gitlab::Redis::SIDEKIQ_NAMESPACE +# Custom Queues configuration +queues_config_hash = Gitlab::Redis::Queues.params +queues_config_hash[:namespace] = Gitlab::Redis::Queues::SIDEKIQ_NAMESPACE # Default is to retry 25 times with exponential backoff. That's too much. Sidekiq.default_worker_options = { retry: 3 } Sidekiq.configure_server do |config| - config.redis = redis_config_hash + config.redis = queues_config_hash config.server_middleware do |chain| chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger if ENV['SIDEKIQ_LOG_ARGUMENTS'] @@ -54,7 +54,7 @@ Sidekiq.configure_server do |config| end Sidekiq.configure_client do |config| - config.redis = redis_config_hash + config.redis = queues_config_hash config.client_middleware do |chain| chain.add Gitlab::SidekiqStatus::ClientMiddleware diff --git a/config/mail_room.yml b/config/mail_room.yml index 88d93d4bc6b..c3a5be8d38c 100644 --- a/config/mail_room.yml +++ b/config/mail_room.yml @@ -21,7 +21,7 @@ :delivery_method: sidekiq :delivery_options: :redis_url: <%= config[:redis_url].to_json %> - :namespace: <%= Gitlab::Redis::SIDEKIQ_NAMESPACE %> + :namespace: <%= Gitlab::Redis::Queues::SIDEKIQ_NAMESPACE %> :queue: email_receiver :worker: EmailReceiverWorker <% if config[:sentinels] %> @@ -36,7 +36,7 @@ :arbitration_method: redis :arbitration_options: :redis_url: <%= config[:redis_url].to_json %> - :namespace: <%= Gitlab::Redis::MAILROOM_NAMESPACE %> + :namespace: <%= Gitlab::Redis::Queues::MAILROOM_NAMESPACE %> <% if config[:sentinels] %> :sentinels: <% config[:sentinels].each do |sentinel| %> diff --git a/config/redis.cache.yml.example b/config/redis.cache.yml.example new file mode 100644 index 00000000000..27478f0a93e --- /dev/null +++ b/config/redis.cache.yml.example @@ -0,0 +1,38 @@ +# If you change this file in a Merge Request, please also create +# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# +development: + url: redis://localhost:6379/10 + # + # url: redis://localhost:6380 + # sentinels: + # - + # host: localhost + # port: 26380 # point to sentinel, not to redis port + # - + # host: slave2 + # port: 26380 # point to sentinel, not to redis port +test: + url: redis://localhost:6379/10 + # + # url: redis://localhost:6380 +production: + # Redis (single instance) + url: unix:/var/run/redis/redis.cache.sock + ## + # Redis + Sentinel (for HA) + # + # Please read instructions carefully before using it as you may lose data: + # http://redis.io/topics/sentinel + # + # You must specify a list of a few sentinels that will handle client connection + # please read here for more information: https://docs.gitlab.com/ce/administration/high_availability/redis.html + ## + # url: redis://master:6380 + # sentinels: + # - + # host: slave1 + # port: 26380 # point to sentinel, not to redis port + # - + # host: slave2 + # port: 26380 # point to sentinel, not to redis port diff --git a/config/redis.queues.yml.example b/config/redis.queues.yml.example new file mode 100644 index 00000000000..dab1f26b096 --- /dev/null +++ b/config/redis.queues.yml.example @@ -0,0 +1,38 @@ +# If you change this file in a Merge Request, please also create +# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# +development: + url: redis://localhost:6379/11 + # + # url: redis://localhost:6381 + # sentinels: + # - + # host: localhost + # port: 26381 # point to sentinel, not to redis port + # - + # host: slave2 + # port: 26381 # point to sentinel, not to redis port +test: + url: redis://localhost:6379/11 + # + # url: redis://localhost:6381 +production: + # Redis (single instance) + url: unix:/var/run/redis/redis.queues.sock + ## + # Redis + Sentinel (for HA) + # + # Please read instructions carefully before using it as you may lose data: + # http://redis.io/topics/sentinel + # + # You must specify a list of a few sentinels that will handle client connection + # please read here for more information: https://docs.gitlab.com/ce/administration/high_availability/redis.html + ## + # url: redis://master:6381 + # sentinels: + # - + # host: slave1 + # port: 26381 # point to sentinel, not to redis port + # - + # host: slave2 + # port: 26381 # point to sentinel, not to redis port diff --git a/config/redis.shared_state.yml.example b/config/redis.shared_state.yml.example new file mode 100644 index 00000000000..9371e3619b7 --- /dev/null +++ b/config/redis.shared_state.yml.example @@ -0,0 +1,38 @@ +# If you change this file in a Merge Request, please also create +# a Merge Request on https://gitlab.com/gitlab-org/omnibus-gitlab/merge_requests +# +development: + url: redis://localhost:6379/12 + # + # url: redis://localhost:6382 + # sentinels: + # - + # host: localhost + # port: 26382 # point to sentinel, not to redis port + # - + # host: slave2 + # port: 26382 # point to sentinel, not to redis port +test: + url: redis://localhost:6379/12 + # + # url: redis://localhost:6382 +production: + # Redis (single instance) + url: unix:/var/run/redis/redis.shared_state.sock + ## + # Redis + Sentinel (for HA) + # + # Please read instructions carefully before using it as you may lose data: + # http://redis.io/topics/sentinel + # + # You must specify a list of a few sentinels that will handle client connection + # please read here for more information: https://docs.gitlab.com/ce/administration/high_availability/redis.html + ## + # url: redis://master:6382 + # sentinels: + # - + # host: slave1 + # port: 26382 # point to sentinel, not to redis port + # - + # host: slave2 + # port: 26382 # point to sentinel, not to redis port diff --git a/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb b/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb index 397a9a2d28e..cb1b4f1855d 100644 --- a/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb +++ b/db/post_migrate/20170324160416_migrate_user_activities_to_users_last_activity_on.rb @@ -56,7 +56,7 @@ class MigrateUserActivitiesToUsersLastActivityOn < ActiveRecord::Migration end def activities(from, to, page: 1) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.zrangebyscore(USER_ACTIVITY_SET_KEY, from.to_i, to.to_i, with_scores: true, limit: limit(page)) @@ -64,7 +64,7 @@ class MigrateUserActivitiesToUsersLastActivityOn < ActiveRecord::Migration end def activities_count(from, to) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.zcount(USER_ACTIVITY_SET_KEY, from.to_i, to.to_i) end end diff --git a/doc/administration/high_availability/redis_source.md b/doc/administration/high_availability/redis_source.md index fe982ea83c2..8b7a515a076 100644 --- a/doc/administration/high_availability/redis_source.md +++ b/doc/administration/high_availability/redis_source.md @@ -4,6 +4,11 @@ This is the documentation for configuring a Highly Available Redis setup when you have installed Redis all by yourself and not using the bundled one that comes with the Omnibus packages. +Note also that you may elect to override all references to +`/home/git/gitlab/config/resque.yml` in accordance with the advanced Redis +settings outlined in +[Configuration Files Documentation](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/README.md). + We cannot stress enough the importance of reading the [Overview section](redis.md#overview) of the Omnibus Redis HA as it provides some invaluable information to the configuration of Redis. Please proceed to diff --git a/doc/administration/operations/cleaning_up_redis_sessions.md b/doc/administration/operations/cleaning_up_redis_sessions.md index 93521e976d5..3a35aff8366 100644 --- a/doc/administration/operations/cleaning_up_redis_sessions.md +++ b/doc/administration/operations/cleaning_up_redis_sessions.md @@ -15,6 +15,12 @@ prefixed with 'session:gitlab:', so they would look like 'session:gitlab:976aa289e2189b17d7ef525a6702ace9'. Below we describe how to remove the keys in the old format. +**Note:** the instructions below must be modified in accordance with your +configuration settings if you have used the advanced Redis +settings outlined in +[Configuration Files Documentation](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/config/README.md). + + First we define a shell function with the proper Redis connection details. ``` diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 3dc808c196d..c90d95e4dd0 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -25,6 +25,7 @@ Parameters: | `order_by`| string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | | `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | | `milestone` | string | no | Return merge requests for a specific milestone | +| `view` | string | no | If `simple`, returns the `iid`, URL, title, description, and basic state of merge request | | `labels` | string | no | Return merge requests matching a comma separated list of labels | | `created_after` | datetime | no | Return merge requests created after the given time (inclusive) | | `created_before` | datetime | no | Return merge requests created before the given time (inclusive) | diff --git a/doc/install/installation.md b/doc/install/installation.md index dfa25deb961..5e981b0b3e7 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -294,9 +294,9 @@ sudo usermod -aG redis git ### Clone the Source # Clone GitLab repository - sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-3-stable gitlab + sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-4-stable gitlab -**Note:** You can change `9-3-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! +**Note:** You can change `9-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! ### Configure It diff --git a/doc/update/9.3-to-9.4.md b/doc/update/9.3-to-9.4.md index bbb7f4a8d48..6962d124c80 100644 --- a/doc/update/9.3-to-9.4.md +++ b/doc/update/9.3-to-9.4.md @@ -72,8 +72,8 @@ More information can be found on the [yarn website](https://yarnpkg.com/en/docs/ ### 5. Update Go -NOTE: GitLab 9.4 and higher only supports Go 1.8.3 and dropped support for Go 1.5.x through 1.7.x. Be -sure to upgrade your installation if necessary +NOTE: GitLab 9.2 and higher only supports Go 1.8.3 and dropped support for Go +1.5.x through 1.7.x. Be sure to upgrade your installation if necessary. You can check which version you are running with `go version`. @@ -117,7 +117,7 @@ cd /home/git/gitlab sudo -u git -H git checkout 9-4-stable-ee ``` -### 5. Update gitlab-shell +### 7. Update gitlab-shell ```bash cd /home/git/gitlab-shell @@ -127,11 +127,10 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_SHELL_VERSION) sudo -u git -H bin/compile ``` -### 6. Update gitlab-workhorse +### 8. Update gitlab-workhorse -Install and compile gitlab-workhorse. This requires -[Go 1.8](https://golang.org/dl) which should already be on your system from -GitLab 8.1. GitLab-Workhorse uses [GNU Make](https://www.gnu.org/software/make/). +Install and compile gitlab-workhorse. GitLab-Workhorse uses +[GNU Make](https://www.gnu.org/software/make/). If you are not using Linux you may have to run `gmake` instead of `make` below. @@ -143,7 +142,7 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITLAB_WORKHORSE_VERSION) sudo -u git -H make ``` -### 7. Update Gitaly +### 9. Update Gitaly If you have not yet set up Gitaly then follow [Gitaly section of the installation guide](../install/installation.md#install-gitaly). @@ -171,7 +170,29 @@ sudo -u git -H git checkout v$(</home/git/gitlab/GITALY_SERVER_VERSION) sudo -u git -H make ``` -### 10. Update configuration files +### 10. Update MySQL permissions + +If you are using MySQL you need to grant the GitLab user the necessary +permissions on the database: + +```bash +mysql -u root -p -e "GRANT TRIGGER ON \`gitlabhq_production\`.* TO 'git'@'localhost';" +``` + +If you use MySQL with replication, or just have MySQL configured with binary logging, +you will need to also run the following on all of your MySQL servers: + +```bash +mysql -u root -p -e "SET GLOBAL log_bin_trust_function_creators = 1;" +``` + +You can make this setting permanent by adding it to your `my.cnf`: + +``` +log_bin_trust_function_creators=1 +``` + +### 11. Update configuration files #### New configuration options for `gitlab.yml` @@ -245,7 +266,7 @@ For Ubuntu 16.04.1 LTS: sudo systemctl daemon-reload ``` -### 11. Install libs, migrations, etc. +### 12. Install libs, migrations, etc. ```bash cd /home/git/gitlab @@ -271,14 +292,14 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production **MySQL installations**: Run through the `MySQL strings limits` and `Tables and data conversion to utf8mb4` [tasks](../install/database_mysql.md). -### 12. Start application +### 13. Start application ```bash sudo service gitlab start sudo service nginx restart ``` -### 13. Check application status +### 14. Check application status Check if GitLab and its environment are configured correctly: diff --git a/doc/user/admin_area/monitoring/health_check.md b/doc/user/admin_area/monitoring/health_check.md index a954840b8a6..69a9dfc3500 100644 --- a/doc/user/admin_area/monitoring/health_check.md +++ b/doc/user/admin_area/monitoring/health_check.md @@ -5,6 +5,8 @@ - The `health_check` endpoint was [introduced][ce-3888] in GitLab 8.8 and will be deprecated in GitLab 9.1. Read more in the [old behavior](#old-behavior) section. + - [Access token](#access-token) has been deprecated in GitLab 9.4 + in favor of [IP Whitelist](#ip-whitelist) GitLab provides liveness and readiness probes to indicate service health and reachability to required services. These probes report on the status of the @@ -12,7 +14,19 @@ database connection, Redis connection, and access to the filesystem. These endpoints [can be provided to schedulers like Kubernetes][kubernetes] to hold traffic until the system is ready or restart the container as needed. -## Access Token +## IP Whitelist + +To access monitoring resources the client IP needs to be included in the whitelist. +To add or remove hosts or IP ranges from the list you can edit `gitlab.rb` or `gitlab.yml`. + +Example whitelist configuration: +```yaml +monitoring: + ip_whitelist: + - 127.0.0.0/8 # by default only local IPs are allowed to access monitoring resources +``` + +## Access Token (Deprecated) An access token needs to be provided while accessing the probe endpoints. The current accepted token can be found under the **Admin area ➔ Monitoring ➔ Health check** @@ -47,10 +61,10 @@ which will then provide a report of system health in JSON format: ## Using the Endpoint -Once you have the access token, the probes can be accessed: +With default whitelist settings, the probes can be accessed from localhost: -- `https://gitlab.example.com/-/readiness?token=ACCESS_TOKEN` -- `https://gitlab.example.com/-/liveness?token=ACCESS_TOKEN` +- `http://localhost/-/readiness` +- `http://localhost/-/liveness` ## Status @@ -71,8 +85,8 @@ the database connection, the state of the database migrations, and the ability t and access the cache. This endpoint can be provided to uptime monitoring services like [Pingdom][pingdom], [Nagios][nagios-health], and [NewRelic][newrelic-health]. -Once you have the [access token](#access-token), health information can be -retrieved as plain text, JSON, or XML using the `health_check` endpoint: +Once you have the [access token](#access-token) or your client IP is [whitelisted](#ip-whitelist), +health information can be retrieved as plain text, JSON, or XML using the `health_check` endpoint: - `https://gitlab.example.com/health_check?token=ACCESS_TOKEN` - `https://gitlab.example.com/health_check.json?token=ACCESS_TOKEN` diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 945f2821d72..47742a164fc 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -314,6 +314,13 @@ module API expose :id end + class MergeRequestSimple < ProjectEntity + expose :title + expose :web_url do |merge_request, options| + Gitlab::UrlBuilder.build(merge_request) + end + end + class MergeRequestBasic < ProjectEntity expose :target_branch, :source_branch expose :upvotes do |merge_request, options| diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 4ad1eef4ff1..ac33b2b801c 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -44,9 +44,14 @@ module API args[:label_name] = args.delete(:labels) merge_requests = MergeRequestsFinder.new(current_user, args).execute - .preload(:notes, :target_project, :author, :assignee, :milestone, :merge_request_diff, :labels) + .reorder(args[:order_by] => args[:sort]) + merge_requests = paginate(merge_requests) + .preload(:target_project) - merge_requests.reorder(args[:order_by] => args[:sort]) + return merge_requests if args[:view] == 'simple' + + merge_requests + .preload(:notes, :author, :assignee, :milestone, :merge_request_diff, :labels) end params :optional_params_ce do @@ -77,15 +82,25 @@ module API optional :labels, type: String, desc: 'Comma-separated list of label names' optional :created_after, type: DateTime, desc: 'Return merge requests created after the specified time' optional :created_before, type: DateTime, desc: 'Return merge requests created before the specified time' + optional :view, type: String, values: %w[simple], desc: 'If simple, returns the `iid`, URL, title, description, and basic state of merge request' use :pagination end get ":id/merge_requests" do authorize! :read_merge_request, user_project merge_requests = find_merge_requests(project_id: user_project.id) - issuable_metadata = issuable_meta_data(merge_requests, 'MergeRequest') - present paginate(merge_requests), with: Entities::MergeRequestBasic, current_user: current_user, project: user_project, issuable_metadata: issuable_metadata + options = { with: Entities::MergeRequestBasic, + current_user: current_user, + project: user_project } + + if params[:view] == 'simple' + options[:with] = Entities::MergeRequestSimple + else + options[:issuable_metadata] = issuable_meta_data(merge_requests, 'MergeRequest') + end + + present merge_requests, options end desc 'Create a merge request' do diff --git a/lib/gitlab/auth/unique_ips_limiter.rb b/lib/gitlab/auth/unique_ips_limiter.rb index bf2239ca150..baa1f802d8a 100644 --- a/lib/gitlab/auth/unique_ips_limiter.rb +++ b/lib/gitlab/auth/unique_ips_limiter.rb @@ -27,7 +27,7 @@ module Gitlab time = Time.now.utc.to_i key = "#{USER_UNIQUE_IPS_PREFIX}:#{user_id}" - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| unique_ips_count = nil redis.multi do |r| r.zadd(key, time, ip) diff --git a/lib/gitlab/cache/ci/project_pipeline_status.rb b/lib/gitlab/cache/ci/project_pipeline_status.rb index 9c2e09943b0..dba37892863 100644 --- a/lib/gitlab/cache/ci/project_pipeline_status.rb +++ b/lib/gitlab/cache/ci/project_pipeline_status.rb @@ -23,7 +23,7 @@ module Gitlab end def self.cached_results_for_projects(projects) - result = Gitlab::Redis.with do |redis| + result = Gitlab::Redis::Cache.with do |redis| redis.multi do projects.each do |project| cache_key = cache_key_for_project(project) @@ -100,19 +100,19 @@ module Gitlab end def load_from_cache - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| self.sha, self.status, self.ref = redis.hmget(cache_key, :sha, :status, :ref) end end def store_in_cache - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref }) end end def delete_from_cache - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| redis.del(cache_key) end end @@ -120,7 +120,7 @@ module Gitlab def has_cache? return self.loaded unless self.loaded.nil? - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| redis.exists(cache_key) end end diff --git a/lib/gitlab/chat_name_token.rb b/lib/gitlab/chat_name_token.rb index 1b081aa9b1d..e63e5437331 100644 --- a/lib/gitlab/chat_name_token.rb +++ b/lib/gitlab/chat_name_token.rb @@ -12,23 +12,23 @@ module Gitlab end def get - Gitlab::Redis.with do |redis| - data = redis.get(redis_key) + Gitlab::Redis::SharedState.with do |redis| + data = redis.get(redis_shared_state_key) JSON.parse(data, symbolize_names: true) if data end end def store!(params) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| params = params.to_json - redis.set(redis_key, params, ex: EXPIRY_TIME) + redis.set(redis_shared_state_key, params, ex: EXPIRY_TIME) token end end def delete - Gitlab::Redis.with do |redis| - redis.del(redis_key) + Gitlab::Redis::SharedState.with do |redis| + redis.del(redis_shared_state_key) end end @@ -38,7 +38,7 @@ module Gitlab Devise.friendly_token(TOKEN_LENGTH) end - def redis_key + def redis_shared_state_key "gitlab:chat_names:#{token}" end end diff --git a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb index 33f8939bc61..1a697396ff1 100644 --- a/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb +++ b/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base.rb @@ -145,7 +145,7 @@ module Gitlab def track_rename(type, old_path, new_path) key = redis_key_for_type(type) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.lpush(key, [old_path, new_path].to_json) redis.expire(key, 2.weeks.to_i) end @@ -155,7 +155,7 @@ module Gitlab def reverts_for_type(type) key = redis_key_for_type(type) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| failed_reverts = [] while rename_info = redis.lpop(key) diff --git a/lib/gitlab/etag_caching/store.rb b/lib/gitlab/etag_caching/store.rb index 072fcfc65e6..21172ff8d93 100644 --- a/lib/gitlab/etag_caching/store.rb +++ b/lib/gitlab/etag_caching/store.rb @@ -2,17 +2,17 @@ module Gitlab module EtagCaching class Store EXPIRY_TIME = 20.minutes - REDIS_NAMESPACE = 'etag:'.freeze + SHARED_STATE_NAMESPACE = 'etag:'.freeze def get(key) - Gitlab::Redis.with { |redis| redis.get(redis_key(key)) } + Gitlab::Redis::SharedState.with { |redis| redis.get(redis_shared_state_key(key)) } end def touch(key, only_if_missing: false) etag = generate_etag - Gitlab::Redis.with do |redis| - redis.set(redis_key(key), etag, ex: EXPIRY_TIME, nx: only_if_missing) + Gitlab::Redis::SharedState.with do |redis| + redis.set(redis_shared_state_key(key), etag, ex: EXPIRY_TIME, nx: only_if_missing) end etag @@ -24,10 +24,10 @@ module Gitlab SecureRandom.hex end - def redis_key(key) + def redis_shared_state_key(key) raise 'Invalid key' if !Rails.env.production? && !Gitlab::EtagCaching::Router.match(key) - "#{REDIS_NAMESPACE}#{key}" + "#{SHARED_STATE_NAMESPACE}#{key}" end end end diff --git a/lib/gitlab/exclusive_lease.rb b/lib/gitlab/exclusive_lease.rb index a0f46594eb1..3784f6c4947 100644 --- a/lib/gitlab/exclusive_lease.rb +++ b/lib/gitlab/exclusive_lease.rb @@ -26,17 +26,17 @@ module Gitlab EOS def self.cancel(key, uuid) - Gitlab::Redis.with do |redis| - redis.eval(LUA_CANCEL_SCRIPT, keys: [redis_key(key)], argv: [uuid]) + Gitlab::Redis::SharedState.with do |redis| + redis.eval(LUA_CANCEL_SCRIPT, keys: [redis_shared_state_key(key)], argv: [uuid]) end end - def self.redis_key(key) + def self.redis_shared_state_key(key) "gitlab:exclusive_lease:#{key}" end def initialize(key, timeout:) - @redis_key = self.class.redis_key(key) + @redis_shared_state_key = self.class.redis_shared_state_key(key) @timeout = timeout @uuid = SecureRandom.uuid end @@ -45,24 +45,24 @@ module Gitlab # false if the lease is already taken. def try_obtain # Performing a single SET is atomic - Gitlab::Redis.with do |redis| - redis.set(@redis_key, @uuid, nx: true, ex: @timeout) && @uuid + Gitlab::Redis::SharedState.with do |redis| + redis.set(@redis_shared_state_key, @uuid, nx: true, ex: @timeout) && @uuid end end # Try to renew an existing lease. Return lease UUID on success, # false if the lease is taken by a different UUID or inexistent. def renew - Gitlab::Redis.with do |redis| - result = redis.eval(LUA_RENEW_SCRIPT, keys: [@redis_key], argv: [@uuid, @timeout]) + Gitlab::Redis::SharedState.with do |redis| + result = redis.eval(LUA_RENEW_SCRIPT, keys: [@redis_shared_state_key], argv: [@uuid, @timeout]) result == @uuid end end # Returns true if the key for this lease is set. def exists? - Gitlab::Redis.with do |redis| - redis.exists(@redis_key) + Gitlab::Redis::SharedState.with do |redis| + redis.exists(@redis_shared_state_key) end end end diff --git a/lib/gitlab/health_checks/redis/cache_check.rb b/lib/gitlab/health_checks/redis/cache_check.rb new file mode 100644 index 00000000000..a28658d42d4 --- /dev/null +++ b/lib/gitlab/health_checks/redis/cache_check.rb @@ -0,0 +1,31 @@ +module Gitlab + module HealthChecks + module Redis + class CacheCheck + extend SimpleAbstractCheck + + class << self + def check_up + check + end + + private + + def metric_prefix + 'redis_cache_ping' + end + + def is_successful?(result) + result == 'PONG' + end + + def check + catch_timeout 10.seconds do + Gitlab::Redis::Cache.with(&:ping) + end + end + end + end + end + end +end diff --git a/lib/gitlab/health_checks/redis/queues_check.rb b/lib/gitlab/health_checks/redis/queues_check.rb new file mode 100644 index 00000000000..f97d50d3947 --- /dev/null +++ b/lib/gitlab/health_checks/redis/queues_check.rb @@ -0,0 +1,31 @@ +module Gitlab + module HealthChecks + module Redis + class QueuesCheck + extend SimpleAbstractCheck + + class << self + def check_up + check + end + + private + + def metric_prefix + 'redis_queues_ping' + end + + def is_successful?(result) + result == 'PONG' + end + + def check + catch_timeout 10.seconds do + Gitlab::Redis::Queues.with(&:ping) + end + end + end + end + end + end +end diff --git a/lib/gitlab/health_checks/redis/redis_check.rb b/lib/gitlab/health_checks/redis/redis_check.rb new file mode 100644 index 00000000000..fe4e3c4a3ab --- /dev/null +++ b/lib/gitlab/health_checks/redis/redis_check.rb @@ -0,0 +1,27 @@ +module Gitlab + module HealthChecks + module Redis + class RedisCheck + extend SimpleAbstractCheck + + class << self + private + + def metric_prefix + 'redis_ping' + end + + def is_successful?(result) + result == 'PONG' + end + + def check + ::Gitlab::HealthChecks::Redis::CacheCheck.check_up && + ::Gitlab::HealthChecks::Redis::QueuesCheck.check_up && + ::Gitlab::HealthChecks::Redis::SharedStateCheck.check_up + end + end + end + end + end +end diff --git a/lib/gitlab/health_checks/redis/shared_state_check.rb b/lib/gitlab/health_checks/redis/shared_state_check.rb new file mode 100644 index 00000000000..e3244392902 --- /dev/null +++ b/lib/gitlab/health_checks/redis/shared_state_check.rb @@ -0,0 +1,31 @@ +module Gitlab + module HealthChecks + module Redis + class SharedStateCheck + extend SimpleAbstractCheck + + class << self + def check_up + check + end + + private + + def metric_prefix + 'redis_shared_state_ping' + end + + def is_successful?(result) + result == 'PONG' + end + + def check + catch_timeout 10.seconds do + Gitlab::Redis::SharedState.with(&:ping) + end + end + end + end + end + end +end diff --git a/lib/gitlab/health_checks/redis_check.rb b/lib/gitlab/health_checks/redis_check.rb deleted file mode 100644 index 57bbe5b3ad0..00000000000 --- a/lib/gitlab/health_checks/redis_check.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Gitlab - module HealthChecks - class RedisCheck - extend SimpleAbstractCheck - - class << self - private - - def metric_prefix - 'redis_ping' - end - - def is_successful?(result) - result == 'PONG' - end - - def check - catch_timeout 10.seconds do - Gitlab::Redis.with(&:ping) - end - end - end - end - end -end diff --git a/lib/gitlab/lfs_token.rb b/lib/gitlab/lfs_token.rb index 5f67e97fa2a..8e57ba831c5 100644 --- a/lib/gitlab/lfs_token.rb +++ b/lib/gitlab/lfs_token.rb @@ -18,10 +18,10 @@ module Gitlab end def token - Gitlab::Redis.with do |redis| - token = redis.get(redis_key) + Gitlab::Redis::SharedState.with do |redis| + token = redis.get(redis_shared_state_key) token ||= Devise.friendly_token(TOKEN_LENGTH) - redis.set(redis_key, token, ex: EXPIRY_TIME) + redis.set(redis_shared_state_key, token, ex: EXPIRY_TIME) token end @@ -41,7 +41,7 @@ module Gitlab private - def redis_key + def redis_shared_state_key "gitlab:lfs_token:#{actor.class.name.underscore}_#{actor.id}" if actor end end diff --git a/lib/gitlab/mail_room.rb b/lib/gitlab/mail_room.rb index 3503fac40e8..9f432673a6e 100644 --- a/lib/gitlab/mail_room.rb +++ b/lib/gitlab/mail_room.rb @@ -1,6 +1,6 @@ require 'yaml' require 'json' -require_relative 'redis' unless defined?(Gitlab::Redis) +require_relative 'redis/queues' unless defined?(Gitlab::Redis::Queues) module Gitlab module MailRoom @@ -34,11 +34,11 @@ module Gitlab config[:idle_timeout] = 60 if config[:idle_timeout].nil? if config[:enabled] && config[:address] - gitlab_redis = Gitlab::Redis.new(rails_env) - config[:redis_url] = gitlab_redis.url + gitlab_redis_queues = Gitlab::Redis::Queues.new(rails_env) + config[:redis_url] = gitlab_redis_queues.url - if gitlab_redis.sentinels? - config[:sentinels] = gitlab_redis.sentinels + if gitlab_redis_queues.sentinels? + config[:sentinels] = gitlab_redis_queues.sentinels end end diff --git a/lib/gitlab/redis.rb b/lib/gitlab/redis.rb deleted file mode 100644 index bc5370de32a..00000000000 --- a/lib/gitlab/redis.rb +++ /dev/null @@ -1,102 +0,0 @@ -# This file should not have any direct dependency on Rails environment -# please require all dependencies below: -require 'active_support/core_ext/hash/keys' -require 'active_support/core_ext/module/delegation' - -module Gitlab - class Redis - CACHE_NAMESPACE = 'cache:gitlab'.freeze - SESSION_NAMESPACE = 'session:gitlab'.freeze - SIDEKIQ_NAMESPACE = 'resque:gitlab'.freeze - MAILROOM_NAMESPACE = 'mail_room:gitlab'.freeze - DEFAULT_REDIS_URL = 'redis://localhost:6379'.freeze - - class << self - delegate :params, :url, to: :new - - def with - @pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) } - @pool.with { |redis| yield redis } - end - - def pool_size - if Sidekiq.server? - # the pool will be used in a multi-threaded context - Sidekiq.options[:concurrency] + 5 - else - # probably this is a Unicorn process, so single threaded - 5 - end - end - - def _raw_config - return @_raw_config if defined?(@_raw_config) - - begin - @_raw_config = ERB.new(File.read(config_file)).result.freeze - rescue Errno::ENOENT - @_raw_config = false - end - - @_raw_config - end - - def config_file - ENV['GITLAB_REDIS_CONFIG_FILE'] || File.expand_path('../../config/resque.yml', __dir__) - end - end - - def initialize(rails_env = nil) - @rails_env = rails_env || ::Rails.env - end - - def params - redis_store_options - end - - def url - raw_config_hash[:url] - end - - def sentinels - raw_config_hash[:sentinels] - end - - def sentinels? - sentinels && !sentinels.empty? - end - - private - - def redis_store_options - config = raw_config_hash - redis_url = config.delete(:url) - redis_uri = URI.parse(redis_url) - - if redis_uri.scheme == 'unix' - # Redis::Store does not handle Unix sockets well, so let's do it for them - config[:path] = redis_uri.path - config - else - redis_hash = ::Redis::Store::Factory.extract_host_options_from_uri(redis_url) - # order is important here, sentinels must be after the connection keys. - # {url: ..., port: ..., sentinels: [...]} - redis_hash.merge(config) - end - end - - def raw_config_hash - config_data = fetch_config - - if config_data - config_data.is_a?(String) ? { url: config_data } : config_data.deep_symbolize_keys - else - { url: DEFAULT_REDIS_URL } - end - end - - def fetch_config - self.class._raw_config ? YAML.load(self.class._raw_config)[@rails_env] : false - end - end -end diff --git a/lib/gitlab/redis/cache.rb b/lib/gitlab/redis/cache.rb new file mode 100644 index 00000000000..b0da516ff83 --- /dev/null +++ b/lib/gitlab/redis/cache.rb @@ -0,0 +1,34 @@ +# please require all dependencies below: +require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper) + +module Gitlab + module Redis + class Cache < ::Gitlab::Redis::Wrapper + CACHE_NAMESPACE = 'cache:gitlab'.freeze + DEFAULT_REDIS_CACHE_URL = 'redis://localhost:6380'.freeze + REDIS_CACHE_CONFIG_ENV_VAR_NAME = 'GITLAB_REDIS_CACHE_CONFIG_FILE'.freeze + if defined?(::Rails) && ::Rails.root.present? + DEFAULT_REDIS_CACHE_CONFIG_FILE_NAME = ::Rails.root.join('config', 'redis.cache.yml').freeze + end + + class << self + def default_url + DEFAULT_REDIS_CACHE_URL + end + + def config_file_name + # if ENV set for this class, use it even if it points to a file does not exist + file_name = ENV[REDIS_CACHE_CONFIG_ENV_VAR_NAME] + return file_name unless file_name.nil? + + # otherwise, if config files exists for this class, use it + file_name = File.expand_path(DEFAULT_REDIS_CACHE_CONFIG_FILE_NAME, __dir__) + return file_name if File.file?(file_name) + + # this will force use of DEFAULT_REDIS_QUEUES_URL when config file is absent + super + end + end + end + end +end diff --git a/lib/gitlab/redis/queues.rb b/lib/gitlab/redis/queues.rb new file mode 100644 index 00000000000..f9249d05565 --- /dev/null +++ b/lib/gitlab/redis/queues.rb @@ -0,0 +1,35 @@ +# please require all dependencies below: +require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper) + +module Gitlab + module Redis + class Queues < ::Gitlab::Redis::Wrapper + SIDEKIQ_NAMESPACE = 'resque:gitlab'.freeze + MAILROOM_NAMESPACE = 'mail_room:gitlab'.freeze + DEFAULT_REDIS_QUEUES_URL = 'redis://localhost:6381'.freeze + REDIS_QUEUES_CONFIG_ENV_VAR_NAME = 'GITLAB_REDIS_QUEUES_CONFIG_FILE'.freeze + if defined?(::Rails) && ::Rails.root.present? + DEFAULT_REDIS_QUEUES_CONFIG_FILE_NAME = ::Rails.root.join('config', 'redis.queues.yml').freeze + end + + class << self + def default_url + DEFAULT_REDIS_QUEUES_URL + end + + def config_file_name + # if ENV set for this class, use it even if it points to a file does not exist + file_name = ENV[REDIS_QUEUES_CONFIG_ENV_VAR_NAME] + return file_name if file_name + + # otherwise, if config files exists for this class, use it + file_name = File.expand_path(DEFAULT_REDIS_QUEUES_CONFIG_FILE_NAME, __dir__) + return file_name if File.file?(file_name) + + # this will force use of DEFAULT_REDIS_QUEUES_URL when config file is absent + super + end + end + end + end +end diff --git a/lib/gitlab/redis/shared_state.rb b/lib/gitlab/redis/shared_state.rb new file mode 100644 index 00000000000..395dcf082da --- /dev/null +++ b/lib/gitlab/redis/shared_state.rb @@ -0,0 +1,34 @@ +# please require all dependencies below: +require_relative 'wrapper' unless defined?(::Gitlab::Redis::Wrapper) + +module Gitlab + module Redis + class SharedState < ::Gitlab::Redis::Wrapper + SESSION_NAMESPACE = 'session:gitlab'.freeze + DEFAULT_REDIS_SHARED_STATE_URL = 'redis://localhost:6382'.freeze + REDIS_SHARED_STATE_CONFIG_ENV_VAR_NAME = 'GITLAB_REDIS_SHARED_STATE_CONFIG_FILE'.freeze + if defined?(::Rails) && ::Rails.root.present? + DEFAULT_REDIS_SHARED_STATE_CONFIG_FILE_NAME = ::Rails.root.join('config', 'redis.shared_state.yml').freeze + end + + class << self + def default_url + DEFAULT_REDIS_SHARED_STATE_URL + end + + def config_file_name + # if ENV set for this class, use it even if it points to a file does not exist + file_name = ENV[REDIS_SHARED_STATE_CONFIG_ENV_VAR_NAME] + return file_name if file_name + + # otherwise, if config files exists for this class, use it + file_name = File.expand_path(DEFAULT_REDIS_SHARED_STATE_CONFIG_FILE_NAME, __dir__) + return file_name if File.file?(file_name) + + # this will force use of DEFAULT_REDIS_SHARED_STATE_URL when config file is absent + super + end + end + end + end +end diff --git a/lib/gitlab/redis/wrapper.rb b/lib/gitlab/redis/wrapper.rb new file mode 100644 index 00000000000..c43b37dde74 --- /dev/null +++ b/lib/gitlab/redis/wrapper.rb @@ -0,0 +1,135 @@ +# This file should only be used by sub-classes, not directly by any clients of the sub-classes +# please require all dependencies below: +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/module/delegation' + +module Gitlab + module Redis + class Wrapper + DEFAULT_REDIS_URL = 'redis://localhost:6379'.freeze + REDIS_CONFIG_ENV_VAR_NAME = 'GITLAB_REDIS_CONFIG_FILE'.freeze + if defined?(::Rails) && ::Rails.root.present? + DEFAULT_REDIS_CONFIG_FILE_NAME = ::Rails.root.join('config', 'resque.yml').freeze + end + + class << self + delegate :params, :url, to: :new + + def with + @pool ||= ConnectionPool.new(size: pool_size) { ::Redis.new(params) } + @pool.with { |redis| yield redis } + end + + def pool_size + # heuristic constant 5 should be a config setting somewhere -- related to CPU count? + size = 5 + if Sidekiq.server? + # the pool will be used in a multi-threaded context + size += Sidekiq.options[:concurrency] + end + size + end + + def _raw_config + return @_raw_config if defined?(@_raw_config) + + @_raw_config = + begin + if filename = config_file_name + ERB.new(File.read(filename)).result.freeze + else + false + end + rescue Errno::ENOENT + false + end + end + + def default_url + DEFAULT_REDIS_URL + end + + def config_file_name + # if ENV set for wrapper class, use it even if it points to a file does not exist + file_name = ENV[REDIS_CONFIG_ENV_VAR_NAME] + return file_name unless file_name.nil? + + # otherwise, if config files exists for wrapper class, use it + file_name = File.expand_path(DEFAULT_REDIS_CONFIG_FILE_NAME, __dir__) + return file_name if File.file?(file_name) + + # nil will force use of DEFAULT_REDIS_URL when config file is absent + nil + end + end + + def initialize(rails_env = nil) + @rails_env = rails_env || ::Rails.env + end + + def params + redis_store_options + end + + def url + raw_config_hash[:url] + end + + def sentinels + raw_config_hash[:sentinels] + end + + def sentinels? + sentinels && !sentinels.empty? + end + + private + + def redis_store_options + config = raw_config_hash + redis_url = config.delete(:url) + redis_uri = URI.parse(redis_url) + + if redis_uri.scheme == 'unix' + # Redis::Store does not handle Unix sockets well, so let's do it for them + config[:path] = redis_uri.path + query = redis_uri.query + unless query.nil? + queries = CGI.parse(redis_uri.query) + db_numbers = queries["db"] if queries.key?("db") + config[:db] = db_numbers[0].to_i if db_numbers.any? + end + config + else + redis_hash = ::Redis::Store::Factory.extract_host_options_from_uri(redis_url) + # order is important here, sentinels must be after the connection keys. + # {url: ..., port: ..., sentinels: [...]} + redis_hash.merge(config) + end + end + + def raw_config_hash + config_data = fetch_config + + if config_data + config_data.is_a?(String) ? { url: config_data } : config_data.deep_symbolize_keys + else + { url: self.class.default_url } + end + end + + def fetch_config + return false unless self.class._raw_config + + yaml = YAML.load(self.class._raw_config) + + # If the file has content but it's invalid YAML, `load` returns false + if yaml + yaml.fetch(@rails_env, false) + else + false + end + end + end + end +end diff --git a/lib/gitlab/url_builder.rb b/lib/gitlab/url_builder.rb index 35792d2d67f..824e2d7251f 100644 --- a/lib/gitlab/url_builder.rb +++ b/lib/gitlab/url_builder.rb @@ -52,15 +52,13 @@ module Gitlab commit_url(id: object.commit_id, anchor: dom_id(object)) elsif object.for_issue? - issue = Issue.find(object.noteable_id) - issue_url(issue, anchor: dom_id(object)) + issue_url(object.noteable, anchor: dom_id(object)) elsif object.for_merge_request? - merge_request = MergeRequest.find(object.noteable_id) - merge_request_url(merge_request, anchor: dom_id(object)) + merge_request_url(object.noteable, anchor: dom_id(object)) elsif object.for_snippet? - snippet = Snippet.find(object.noteable_id) + snippet = object.noteable if snippet.is_a?(PersonalSnippet) snippet_url(snippet, anchor: dom_id(object)) diff --git a/lib/gitlab/user_activities.rb b/lib/gitlab/user_activities.rb index eb36ab9fded..125488536e1 100644 --- a/lib/gitlab/user_activities.rb +++ b/lib/gitlab/user_activities.rb @@ -6,13 +6,13 @@ module Gitlab BATCH_SIZE = 500 def self.record(key, time = Time.now) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.hset(KEY, key, time.to_i) end end def delete(*keys) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.hdel(KEY, keys) end end @@ -21,7 +21,7 @@ module Gitlab cursor = 0 loop do cursor, pairs = - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.hscan(KEY, cursor, count: BATCH_SIZE) end diff --git a/lib/gitlab/workhorse.rb b/lib/gitlab/workhorse.rb index 4aef23b6aee..ee4f2b773ea 100644 --- a/lib/gitlab/workhorse.rb +++ b/lib/gitlab/workhorse.rb @@ -176,7 +176,7 @@ module Gitlab end def set_key_and_notify(key, value, expire: nil, overwrite: true) - Gitlab::Redis.with do |redis| + Gitlab::Redis::Queues.with do |redis| result = redis.set(key, value, ex: expire, nx: !overwrite) if result redis.publish(NOTIFICATION_CHANNEL, "#{key}=#{value}") diff --git a/lib/tasks/cache.rake b/lib/tasks/cache.rake index 125a3d560d6..564aa141952 100644 --- a/lib/tasks/cache.rake +++ b/lib/tasks/cache.rake @@ -5,12 +5,12 @@ namespace :cache do desc "GitLab | Clear redis cache" task redis: :environment do - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| cursor = REDIS_SCAN_START_STOP loop do cursor, keys = redis.scan( cursor, - match: "#{Gitlab::Redis::CACHE_NAMESPACE}*", + match: "#{Gitlab::Redis::Cache::CACHE_NAMESPACE}*", count: REDIS_CLEAR_BATCH_SIZE ) diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po index db4dc9a02da..7406629ef9d 100644 --- a/locale/bg/gitlab.po +++ b/locale/bg/gitlab.po @@ -4,11 +4,11 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-19 15:50-0500\n" +"POT-Creation-Date: 2017-06-28 13:32+0200\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-23 04:07-0400\n" +"PO-Revision-Date: 2017-07-05 08:18-0400\n" "Last-Translator: Lyubomir Vasilev <lyubomirv@abv.bg>\n" "Language-Team: Bulgarian (https://translate.zanata.org/project/view/GitLab)\n" "Language: bg\n" @@ -29,6 +29,14 @@ msgstr[1] "%d подавания" msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "%{commit_author_link} подаде %{commit_timeago}" +msgid "1 pipeline" +msgid_plural "%d pipelines" +msgstr[0] "1 схема" +msgstr[1] "%d схеми" + +msgid "A collection of graphs regarding Continuous Integration" +msgstr "Набор от графики относно непрекъснатата интеграция" + msgid "About auto deploy" msgstr "Относно автоматичното внедряване" @@ -191,6 +199,9 @@ msgid_plural "Commits" msgstr[0] "Подаване" msgstr[1] "Подавания" +msgid "Commit duration in minutes for last 30 commits" +msgstr "Времетраене на подаванията в минути за последните 30 подавания" + msgid "Commit message" msgstr "Съобщение за подаването" @@ -230,6 +241,13 @@ msgstr "Копиране на идентификатора на подаване msgid "Create New Directory" msgstr "Създаване на нова папка" +msgid "" +"Create a personal access token on your account to pull or push via " +"%{protocol}." +msgstr "" +"Създайте си личен жетон за достъп в профила си, за да можете да изтегляте и " +"изпращате промени чрез %{protocol}." + msgid "Create directory" msgstr "Създаване на папка" @@ -248,6 +266,9 @@ msgstr "Разклоняване" msgid "CreateTag|Tag" msgstr "Етикет" +msgid "CreateTokenToCloneLink|create a personal access token" +msgstr "си създадете личен жетон за достъп" + msgid "Cron Timezone" msgstr "Часова зона за „Cron“" @@ -419,6 +440,15 @@ msgstr "Шаблон за интервала" msgid "Introducing Cycle Analytics" msgstr "Представяме Ви анализа на циклите" +msgid "Jobs for last month" +msgstr "Задачи за последния месец" + +msgid "Jobs for last week" +msgstr "Задачи за последната седмица" + +msgid "Jobs for last year" +msgstr "Задачи за последната година" + msgid "LFSStatus|Disabled" msgstr "Изключено" @@ -584,6 +614,21 @@ msgstr "План за схема" msgid "Pipeline Schedules" msgstr "Планове за схема" +msgid "PipelineCharts|Failed:" +msgstr "Неуспешни:" + +msgid "PipelineCharts|Overall statistics" +msgstr "Обща статистика" + +msgid "PipelineCharts|Success ratio:" +msgstr "Коефициент на успех:" + +msgid "PipelineCharts|Successful:" +msgstr "Успешни:" + +msgid "PipelineCharts|Total:" +msgstr "Общо:" + msgid "PipelineSchedules|Activated" msgstr "Включено" @@ -614,6 +659,18 @@ msgstr "Цел" msgid "PipelineSheduleIntervalPattern|Custom" msgstr "собствен" +msgid "Pipelines" +msgstr "Схеми" + +msgid "Pipelines charts" +msgstr "Графики за схемите" + +msgid "Pipeline|all" +msgstr "всички" + +msgid "Pipeline|success" +msgstr "успешни" + msgid "Pipeline|with stage" msgstr "с етап" diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po index 0ca8dfca266..015d96d6e53 100644 --- a/locale/eo/gitlab.po +++ b/locale/eo/gitlab.po @@ -4,11 +4,11 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-19 15:50-0500\n" +"POT-Creation-Date: 2017-06-28 13:32+0200\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-07-05 02:56-0400\n" +"PO-Revision-Date: 2017-07-05 08:18-0400\n" "Last-Translator: Lyubomir Vasilev <lyubomirv@abv.bg>\n" "Language-Team: Esperanto (https://translate.zanata.org/project/view/GitLab)\n" "Language: eo\n" @@ -29,6 +29,14 @@ msgstr[1] "%d enmetadoj" msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "%{commit_author_link} enmetis %{commit_timeago}" +msgid "1 pipeline" +msgid_plural "%d pipelines" +msgstr[0] "1 ĉenstablo" +msgstr[1] "%d ĉenstabloj" + +msgid "A collection of graphs regarding Continuous Integration" +msgstr "Aro da diagramoj pri la seninterrompa integrado" + msgid "About auto deploy" msgstr "Pri la aŭtomata disponigado" @@ -191,6 +199,9 @@ msgid_plural "Commits" msgstr[0] "Enmetado" msgstr[1] "Enmetadoj" +msgid "Commit duration in minutes for last 30 commits" +msgstr "Daŭro de la enmetadoj por la lastaj 30 enmetadoj" + msgid "Commit message" msgstr "Mesaĝo pri la enmetado" @@ -230,6 +241,13 @@ msgstr "Kopii la identigilon de la enmetado" msgid "Create New Directory" msgstr "Krei novan dosierujon" +msgid "" +"Create a personal access token on your account to pull or push via " +"%{protocol}." +msgstr "" +"Kreu propran atingoĵetonon en via konto por ebligi al vi eltiri kaj alpuŝi " +"per %{protocol}." + msgid "Create directory" msgstr "Krei dosierujon" @@ -248,6 +266,9 @@ msgstr "Disbranĉigi" msgid "CreateTag|Tag" msgstr "Etikedo" +msgid "CreateTokenToCloneLink|create a personal access token" +msgstr "kreos propran atingoĵetonon" + msgid "Cron Timezone" msgstr "Horzono por Cron" @@ -420,6 +441,15 @@ msgstr "Intervala ŝablono" msgid "Introducing Cycle Analytics" msgstr "Ni prezentas al vi la ciklan analizon" +msgid "Jobs for last month" +msgstr "Taskoj po la lasta monato" + +msgid "Jobs for last week" +msgstr "Taskoj po la lasta semajno" + +msgid "Jobs for last year" +msgstr "Taskoj po la lasta jaro" + msgid "LFSStatus|Disabled" msgstr "Malŝaltita" @@ -585,6 +615,21 @@ msgstr "Ĉenstabla plano" msgid "Pipeline Schedules" msgstr "Ĉenstablaj planoj" +msgid "PipelineCharts|Failed:" +msgstr "Malsukcesaj:" + +msgid "PipelineCharts|Overall statistics" +msgstr "Ĝenerala statistiko" + +msgid "PipelineCharts|Success ratio:" +msgstr "Proporcio de sukceso:" + +msgid "PipelineCharts|Successful:" +msgstr "Sukcesaj:" + +msgid "PipelineCharts|Total:" +msgstr "Totalo:" + msgid "PipelineSchedules|Activated" msgstr "Ŝaltita" @@ -615,6 +660,18 @@ msgstr "Celo" msgid "PipelineSheduleIntervalPattern|Custom" msgstr "Propra" +msgid "Pipelines" +msgstr "Ĉenstabloj" + +msgid "Pipelines charts" +msgstr "Ĉenstablaj diagramoj" + +msgid "Pipeline|all" +msgstr "ĉiuj" + +msgid "Pipeline|success" +msgstr "sukcesaj" + msgid "Pipeline|with stage" msgstr "kun etapo" diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po index 2f21aae2899..8a76121e0c1 100644 --- a/locale/zh_CN/gitlab.po +++ b/locale/zh_CN/gitlab.po @@ -4,11 +4,11 @@ msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-19 15:50-0500\n" +"POT-Creation-Date: 2017-06-28 13:32+0200\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-27 03:18-0400\n" +"PO-Revision-Date: 2017-07-10 09:58-0400\n" "Last-Translator: Huang Tao <htve@outlook.com>\n" "Language-Team: Chinese (China) (https://translate.zanata.org/project/view/GitLab)\n" "Language: zh-CN\n" @@ -27,6 +27,13 @@ msgstr[0] "%d 次提交" msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "由 %{commit_author_link} 提交于 %{commit_timeago}" +msgid "1 pipeline" +msgid_plural "%d pipelines" +msgstr[0] "%d 条流水线" + +msgid "A collection of graphs regarding Continuous Integration" +msgstr "持续集成数据图" + msgid "About auto deploy" msgstr "关于自动部署" @@ -184,6 +191,9 @@ msgid "Commit" msgid_plural "Commits" msgstr[0] "提交" +msgid "Commit duration in minutes for last 30 commits" +msgstr "最近30次提交相应持续集成花费的时间(分钟)" + msgid "Commit message" msgstr "提交信息" @@ -223,6 +233,11 @@ msgstr "复制提交 SHA 的值到剪贴板" msgid "Create New Directory" msgstr "创建新目录" +msgid "" +"Create a personal access token on your account to pull or push via " +"%{protocol}." +msgstr "在帐户上创建个人访问令牌,以通过%{protocol}来拉取或推送。" + msgid "Create directory" msgstr "创建目录" @@ -241,6 +256,9 @@ msgstr "派生" msgid "CreateTag|Tag" msgstr "标签" +msgid "CreateTokenToCloneLink|create a personal access token" +msgstr "创建个人访问令牌" + msgid "Cron Timezone" msgstr "Cron 时区" @@ -405,6 +423,15 @@ msgstr "循环周期" msgid "Introducing Cycle Analytics" msgstr "周期分析简介" +msgid "Jobs for last month" +msgstr "上个月的作业" + +msgid "Jobs for last week" +msgstr "上个星期的作业" + +msgid "Jobs for last year" +msgstr "去年的作业" + msgid "LFSStatus|Disabled" msgstr "停用" @@ -567,6 +594,21 @@ msgstr "流水线计划" msgid "Pipeline Schedules" msgstr "流水线计划" +msgid "PipelineCharts|Failed:" +msgstr "失败:" + +msgid "PipelineCharts|Overall statistics" +msgstr "总体统计数据" + +msgid "PipelineCharts|Success ratio:" +msgstr "成功率:" + +msgid "PipelineCharts|Successful:" +msgstr "成功:" + +msgid "PipelineCharts|Total:" +msgstr "总计:" + msgid "PipelineSchedules|Activated" msgstr "是否启用" @@ -597,6 +639,18 @@ msgstr "目标" msgid "PipelineSheduleIntervalPattern|Custom" msgstr "自定义" +msgid "Pipelines" +msgstr "流水线" + +msgid "Pipelines charts" +msgstr "流水线统计图" + +msgid "Pipeline|all" +msgstr "所有" + +msgid "Pipeline|success" +msgstr "成功" + msgid "Pipeline|with stage" msgstr "于阶段" diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po index afdbd01b7d7..b679ed3f26b 100644 --- a/locale/zh_HK/gitlab.po +++ b/locale/zh_HK/gitlab.po @@ -1,17 +1,15 @@ # Huang Tao <htve@outlook.com>, 2017. #zanata -# Victor Wu <anonymous@domain.com>, 2017. -# Hazel Yang <anonymous@domain.com>, 2017. msgid "" msgstr "" "Project-Id-Version: gitlab 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-06-15 21:59-0500\n" +"POT-Creation-Date: 2017-06-28 13:32+0200\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"PO-Revision-Date: 2017-06-23 01:23-0400\n" +"PO-Revision-Date: 2017-07-06 11:26-0400\n" "Last-Translator: Huang Tao <htve@outlook.com>\n" -"Language-Team: Chinese (Hong Kong) (https://translate.zanata.org/project/view/GitLab)\n" +"Language-Team: Chinese (Hong Kong SAR China)\n" "Language: zh-HK\n" "X-Generator: Zanata 3.9.6\n" "Plural-Forms: nplurals=1; plural=0\n" @@ -28,6 +26,13 @@ msgstr[0] " %d 次提交" msgid "%{commit_author_link} committed %{commit_timeago}" msgstr "由 %{commit_author_link} 提交於 %{commit_timeago}" +msgid "1 pipeline" +msgid_plural "%d pipelines" +msgstr[0] "%d 條流水線" + +msgid "A collection of graphs regarding Continuous Integration" +msgstr "相關持續集成的圖像集合" + msgid "About auto deploy" msgstr "關於自動部署" @@ -185,6 +190,9 @@ msgid "Commit" msgid_plural "Commits" msgstr[0] "提交" +msgid "Commit duration in minutes for last 30 commits" +msgstr "最近30次提交花費的時間(分鐘)" + msgid "Commit message" msgstr "提交信息" @@ -224,6 +232,11 @@ msgstr "複製提交 SHA 到剪貼板" msgid "Create New Directory" msgstr "創建新目錄" +msgid "" +"Create a personal access token on your account to pull or push via " +"%{protocol}." +msgstr "在帳戶上創建個人訪問令牌,以通過 %{protocol} 來拉取或推送。" + msgid "Create directory" msgstr "創建目錄" @@ -242,6 +255,9 @@ msgstr "派生" msgid "CreateTag|Tag" msgstr "標籤" +msgid "CreateTokenToCloneLink|create a personal access token" +msgstr "創建個人訪問令牌" + msgid "Cron Timezone" msgstr "Cron 時區" @@ -406,6 +422,15 @@ msgstr "循環週期" msgid "Introducing Cycle Analytics" msgstr "週期分析簡介" +msgid "Jobs for last month" +msgstr "上個月的作業" + +msgid "Jobs for last week" +msgstr "上個星期的作業" + +msgid "Jobs for last year" +msgstr "去年的作業" + msgid "LFSStatus|Disabled" msgstr "停用" @@ -568,6 +593,21 @@ msgstr "流水線計劃" msgid "Pipeline Schedules" msgstr "流水線計劃" +msgid "PipelineCharts|Failed:" +msgstr "失敗:" + +msgid "PipelineCharts|Overall statistics" +msgstr "總體統計" + +msgid "PipelineCharts|Success ratio:" +msgstr "成功率:" + +msgid "PipelineCharts|Successful:" +msgstr "成功:" + +msgid "PipelineCharts|Total:" +msgstr "總計:" + msgid "PipelineSchedules|Activated" msgstr "是否啟用" @@ -598,6 +638,18 @@ msgstr "目標" msgid "PipelineSheduleIntervalPattern|Custom" msgstr "自定義" +msgid "Pipelines" +msgstr "流水線" + +msgid "Pipelines charts" +msgstr "流水線圖表" + +msgid "Pipeline|all" +msgstr "所有" + +msgid "Pipeline|success" +msgstr "成功" + msgid "Pipeline|with stage" msgstr "於階段" diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index 03de59f27ad..68114d149c4 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -12,9 +12,6 @@ fi # gems could not be found under some circumstance. No idea why, hours wasted. retry gem install knapsack fog-aws mime-types -cp config/resque.yml.example config/resque.yml -sed -i 's/localhost/redis/g' config/resque.yml - cp config/gitlab.yml.example config/gitlab.yml # Determine the database by looking at the job name. @@ -37,6 +34,18 @@ else # Assume it's mysql sed -i 's/# host:.*/host: mysql/g' config/database.yml fi +cp config/resque.yml.example config/resque.yml +sed -i 's/localhost/redis/g' config/resque.yml + +cp config/redis.cache.yml.example config/redis.cache.yml +sed -i 's/localhost/redis/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 + +cp config/redis.shared_state.yml.example config/redis.shared_state.yml +sed -i 's/localhost/redis/g' config/redis.shared_state.yml + if [ "$SETUP_DB" != "false" ]; then bundle exec rake db:drop db:create db:schema:load db:migrate diff --git a/spec/config/mail_room_spec.rb b/spec/config/mail_room_spec.rb index 092048a6259..a31e44fa928 100644 --- a/spec/config/mail_room_spec.rb +++ b/spec/config/mail_room_spec.rb @@ -5,12 +5,12 @@ describe 'mail_room.yml' do let(:mailroom_config_path) { 'config/mail_room.yml' } let(:gitlab_config_path) { 'config/mail_room.yml' } - let(:redis_config_path) { 'config/resque.yml' } + let(:queues_config_path) { 'config/redis.queues.yml' } let(:configuration) do vars = { 'MAIL_ROOM_GITLAB_CONFIG_FILE' => absolute_path(gitlab_config_path), - 'GITLAB_REDIS_CONFIG_FILE' => absolute_path(redis_config_path) + 'GITLAB_REDIS_QUEUES_CONFIG_FILE' => absolute_path(queues_config_path) } cmd = "puts ERB.new(File.read(#{absolute_path(mailroom_config_path).inspect})).result" @@ -21,12 +21,12 @@ describe 'mail_room.yml' do end before(:each) do - stub_env('GITLAB_REDIS_CONFIG_FILE', absolute_path(redis_config_path)) - clear_redis_raw_config + stub_env('GITLAB_REDIS_QUEUES_CONFIG_FILE', absolute_path(queues_config_path)) + clear_queues_raw_config end after(:each) do - clear_redis_raw_config + clear_queues_raw_config end context 'when incoming email is disabled' do @@ -39,9 +39,9 @@ describe 'mail_room.yml' do context 'when incoming email is enabled' do let(:gitlab_config_path) { 'spec/fixtures/config/mail_room_enabled.yml' } - let(:redis_config_path) { 'spec/fixtures/config/redis_new_format_host.yml' } + let(:queues_config_path) { 'spec/fixtures/config/redis_queues_new_format_host.yml' } - let(:gitlab_redis) { Gitlab::Redis.new(Rails.env) } + let(:gitlab_redis_queues) { Gitlab::Redis::Queues.new(Rails.env) } it 'contains the intended configuration' do expect(configuration[:mailboxes].length).to eq(1) @@ -56,8 +56,8 @@ describe 'mail_room.yml' do expect(mailbox[:name]).to eq('inbox') expect(mailbox[:idle_timeout]).to eq(60) - redis_url = gitlab_redis.url - sentinels = gitlab_redis.sentinels + redis_url = gitlab_redis_queues.url + sentinels = gitlab_redis_queues.sentinels expect(mailbox[:delivery_options][:redis_url]).to be_present expect(mailbox[:delivery_options][:redis_url]).to eq(redis_url) @@ -73,8 +73,8 @@ describe 'mail_room.yml' do end end - def clear_redis_raw_config - Gitlab::Redis.remove_instance_variable(:@_raw_config) + def clear_queues_raw_config + Gitlab::Redis::Queues.remove_instance_variable(:@_raw_config) rescue NameError # raised if @_raw_config was not set; ignore end diff --git a/spec/controllers/health_check_controller_spec.rb b/spec/controllers/health_check_controller_spec.rb index 58c16cc57e6..03da6287774 100644 --- a/spec/controllers/health_check_controller_spec.rb +++ b/spec/controllers/health_check_controller_spec.rb @@ -3,52 +3,79 @@ require 'spec_helper' describe HealthCheckController do include StubENV - let(:token) { current_application_settings.health_check_access_token } let(:json_response) { JSON.parse(response.body) } let(:xml_response) { Hash.from_xml(response.body)['hash'] } + let(:token) { current_application_settings.health_check_access_token } + let(:whitelisted_ip) { '127.0.0.1' } + let(:not_whitelisted_ip) { '127.0.0.2' } before do + allow(Settings.monitoring).to receive(:ip_whitelist).and_return([whitelisted_ip]) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') end describe 'GET #index' do - context 'when services are up but NO access token' do + context 'when services are up but accessed from outside whitelisted ips' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(not_whitelisted_ip) + end + it 'returns a not found page' do get :index + expect(response).to be_not_found end + + context 'when services are accessed with token' do + it 'supports passing the token in the header' do + request.headers['TOKEN'] = token + + get :index + + expect(response).to be_success + expect(response.content_type).to eq 'text/plain' + end + + it 'supports passing the token in query params' do + get :index, token: token + + expect(response).to be_success + expect(response.content_type).to eq 'text/plain' + end + end end - context 'when services are up and an access token is provided' do - it 'supports passing the token in the header' do - request.headers['TOKEN'] = token - get :index - expect(response).to be_success - expect(response.content_type).to eq 'text/plain' + context 'when services are up and accessed from whitelisted ips' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(whitelisted_ip) end - it 'supports successful plaintest response' do - get :index, token: token + it 'supports successful plaintext response' do + get :index + expect(response).to be_success expect(response.content_type).to eq 'text/plain' end it 'supports successful json response' do - get :index, token: token, format: :json + get :index, format: :json + expect(response).to be_success expect(response.content_type).to eq 'application/json' expect(json_response['healthy']).to be true end it 'supports successful xml response' do - get :index, token: token, format: :xml + get :index, format: :xml + expect(response).to be_success expect(response.content_type).to eq 'application/xml' expect(xml_response['healthy']).to be true end it 'supports successful responses for specific checks' do - get :index, token: token, checks: 'email', format: :json + get :index, checks: 'email', format: :json + expect(response).to be_success expect(response.content_type).to eq 'application/json' expect(json_response['healthy']).to be true @@ -58,33 +85,29 @@ describe HealthCheckController do context 'when a service is down but NO access token' do it 'returns a not found page' do get :index + expect(response).to be_not_found end end - context 'when a service is down and an access token is provided' do + context 'when a service is down and an endpoint is accessed from whitelisted ip' do before do allow(HealthCheck::Utils).to receive(:process_checks).with(['standard']).and_return('The server is on fire') allow(HealthCheck::Utils).to receive(:process_checks).with(['email']).and_return('Email is on fire') + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(whitelisted_ip) end - it 'supports passing the token in the header' do - request.headers['TOKEN'] = token + it 'supports failure plaintext response' do get :index - expect(response).to have_http_status(500) - expect(response.content_type).to eq 'text/plain' - expect(response.body).to include('The server is on fire') - end - it 'supports failure plaintest response' do - get :index, token: token expect(response).to have_http_status(500) expect(response.content_type).to eq 'text/plain' expect(response.body).to include('The server is on fire') end it 'supports failure json response' do - get :index, token: token, format: :json + get :index, format: :json + expect(response).to have_http_status(500) expect(response.content_type).to eq 'application/json' expect(json_response['healthy']).to be false @@ -92,7 +115,8 @@ describe HealthCheckController do end it 'supports failure xml response' do - get :index, token: token, format: :xml + get :index, format: :xml + expect(response).to have_http_status(500) expect(response.content_type).to eq 'application/xml' expect(xml_response['healthy']).to be false @@ -100,7 +124,8 @@ describe HealthCheckController do end it 'supports failure responses for specific checks' do - get :index, token: token, checks: 'email', format: :json + get :index, checks: 'email', format: :json + expect(response).to have_http_status(500) expect(response.content_type).to eq 'application/json' expect(json_response['healthy']).to be false diff --git a/spec/controllers/health_controller_spec.rb b/spec/controllers/health_controller_spec.rb index e7c19b47a6a..cc389e554ad 100644 --- a/spec/controllers/health_controller_spec.rb +++ b/spec/controllers/health_controller_spec.rb @@ -3,55 +3,120 @@ require 'spec_helper' describe HealthController do include StubENV - let(:token) { current_application_settings.health_check_access_token } let(:json_response) { JSON.parse(response.body) } + let(:token) { current_application_settings.health_check_access_token } + let(:whitelisted_ip) { '127.0.0.1' } + let(:not_whitelisted_ip) { '127.0.0.2' } before do + allow(Settings.monitoring).to receive(:ip_whitelist).and_return([whitelisted_ip]) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') end describe '#readiness' do - context 'authorization token provided' do - before do - request.headers['TOKEN'] = token - end + shared_context 'endpoint responding with readiness data' do + let(:request_params) { {} } + + subject { get :readiness, request_params } + + it 'responds with readiness checks data' do + subject - it 'returns proper response' do - get :readiness expect(json_response['db_check']['status']).to eq('ok') - expect(json_response['redis_check']['status']).to eq('ok') + expect(json_response['cache_check']['status']).to eq('ok') + expect(json_response['queues_check']['status']).to eq('ok') + expect(json_response['shared_state_check']['status']).to eq('ok') expect(json_response['fs_shards_check']['status']).to eq('ok') expect(json_response['fs_shards_check']['labels']['shard']).to eq('default') end end - context 'without authorization token' do - it 'returns proper response' do + context 'accessed from whitelisted ip' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(whitelisted_ip) + end + + it_behaves_like 'endpoint responding with readiness data' + end + + context 'accessed from not whitelisted ip' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(not_whitelisted_ip) + end + + it 'responds with resource not found' do get :readiness + expect(response.status).to eq(404) end + + context 'accessed with valid token' do + context 'token passed in request header' do + before do + request.headers['TOKEN'] = token + end + + it_behaves_like 'endpoint responding with readiness data' + end + end + + context 'token passed as URL param' do + it_behaves_like 'endpoint responding with readiness data' do + let(:request_params) { { token: token } } + end + end end end describe '#liveness' do - context 'authorization token provided' do - before do - request.headers['TOKEN'] = token - end + shared_context 'endpoint responding with liveness data' do + subject { get :liveness } + + it 'responds with liveness checks data' do + subject - it 'returns proper response' do - get :liveness expect(json_response['db_check']['status']).to eq('ok') - expect(json_response['redis_check']['status']).to eq('ok') + expect(json_response['cache_check']['status']).to eq('ok') + expect(json_response['queues_check']['status']).to eq('ok') + expect(json_response['shared_state_check']['status']).to eq('ok') expect(json_response['fs_shards_check']['status']).to eq('ok') end end - context 'without authorization token' do - it 'returns proper response' do + context 'accessed from whitelisted ip' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(whitelisted_ip) + end + + it_behaves_like 'endpoint responding with liveness data' + end + + context 'accessed from not whitelisted ip' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(not_whitelisted_ip) + end + + it 'responds with resource not found' do get :liveness + expect(response.status).to eq(404) end + + context 'accessed with valid token' do + context 'token passed in request header' do + before do + request.headers['TOKEN'] = token + end + + it_behaves_like 'endpoint responding with liveness data' + end + + context 'token passed as URL param' do + it_behaves_like 'endpoint responding with liveness data' do + subject { get :liveness, token: token } + end + end + end end end end diff --git a/spec/controllers/metrics_controller_spec.rb b/spec/controllers/metrics_controller_spec.rb index 044c9f179ed..86847c07c09 100644 --- a/spec/controllers/metrics_controller_spec.rb +++ b/spec/controllers/metrics_controller_spec.rb @@ -3,22 +3,22 @@ require 'spec_helper' describe MetricsController do include StubENV - let(:token) { current_application_settings.health_check_access_token } let(:json_response) { JSON.parse(response.body) } let(:metrics_multiproc_dir) { Dir.mktmpdir } + let(:whitelisted_ip) { '127.0.0.1' } + let(:whitelisted_ip_range) { '10.0.0.0/24' } + let(:ip_in_whitelisted_range) { '10.0.0.1' } + let(:not_whitelisted_ip) { '10.0.1.1' } before do stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') stub_env('prometheus_multiproc_dir', metrics_multiproc_dir) allow(Gitlab::Metrics).to receive(:prometheus_metrics_enabled?).and_return(true) + allow(Settings.monitoring).to receive(:ip_whitelist).and_return([whitelisted_ip, whitelisted_ip_range]) end describe '#index' do - context 'authorization token provided' do - before do - request.headers['TOKEN'] = token - end - + shared_examples_for 'endpoint providing metrics' do it 'returns DB ping metrics' do get :index @@ -35,6 +35,30 @@ describe MetricsController do expect(response.body).to match(/^redis_ping_latency [0-9\.]+$/) end + it 'returns Caching ping metrics' do + get :index + + expect(response.body).to match(/^redis_cache_ping_timeout 0$/) + expect(response.body).to match(/^redis_cache_ping_success 1$/) + expect(response.body).to match(/^redis_cache_ping_latency [0-9\.]+$/) + end + + it 'returns Queues ping metrics' do + get :index + + expect(response.body).to match(/^redis_queues_ping_timeout 0$/) + expect(response.body).to match(/^redis_queues_ping_success 1$/) + expect(response.body).to match(/^redis_queues_ping_latency [0-9\.]+$/) + end + + it 'returns SharedState ping metrics' do + get :index + + expect(response.body).to match(/^redis_shared_state_ping_timeout 0$/) + expect(response.body).to match(/^redis_shared_state_ping_success 1$/) + expect(response.body).to match(/^redis_shared_state_ping_latency [0-9\.]+$/) + end + it 'returns file system check metrics' do get :index @@ -59,7 +83,27 @@ describe MetricsController do end end - context 'without authorization token' do + context 'accessed from whitelisted ip' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(whitelisted_ip) + end + + it_behaves_like 'endpoint providing metrics' + end + + context 'accessed from ip in whitelisted range' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(ip_in_whitelisted_range) + end + + it_behaves_like 'endpoint providing metrics' + end + + context 'accessed from not whitelisted ip' do + before do + allow(Gitlab::RequestContext).to receive(:client_ip).and_return(not_whitelisted_ip) + end + it 'returns proper response' do get :index diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index bf922260b2f..2b4e8723b48 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -47,7 +47,7 @@ describe SessionsController do end end - context 'when using valid password', :redis do + context 'when using valid password', :clean_gitlab_redis_shared_state do include UserActivitiesHelpers let(:user) { create(:user) } diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb index 285724f4b48..6b666934563 100644 --- a/spec/features/dashboard/issuables_counter_spec.rb +++ b/spec/features/dashboard/issuables_counter_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'Navigation bar counter', feature: true, caching: true do +describe 'Navigation bar counter', :use_clean_rails_memory_store_caching, feature: true do let(:user) { create(:user) } let(:project) { create(:empty_project, namespace: user.namespace) } let(:issue) { create(:issue, project: project) } diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index 7ca002fc821..bdba22fe9a9 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -61,7 +61,7 @@ feature 'Dashboard Projects' do end end - describe 'with a pipeline', redis: true do + describe "with a pipeline", clean_gitlab_redis_shared_state: true do let(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.sha) } before do diff --git a/spec/features/groups/members/sort_members_spec.rb b/spec/features/groups/members/sort_members_spec.rb index 169827f5d0d..92ff45e0cdc 100644 --- a/spec/features/groups/members/sort_members_spec.rb +++ b/spec/features/groups/members/sort_members_spec.rb @@ -68,7 +68,7 @@ feature 'Groups > Members > Sort members', feature: true do expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, descending') end - scenario 'sorts by recent sign in', :redis do + scenario 'sorts by recent sign in', :clean_gitlab_redis_shared_state do visit_members_list(sort: :recent_sign_in) expect(first_member).to include(owner.name) @@ -76,7 +76,7 @@ feature 'Groups > Members > Sort members', feature: true do expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Recent sign in') end - scenario 'sorts by oldest sign in', :redis do + scenario 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do visit_members_list(sort: :oldest_sign_in) expect(first_member).to include(developer.name) diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb index a8055b21cee..2a2213b67ed 100644 --- a/spec/features/login_spec.rb +++ b/spec/features/login_spec.rb @@ -41,7 +41,7 @@ feature 'Login', feature: true do expect(page).to have_content('Your account has been blocked.') end - it 'does not update Devise trackable attributes', :redis do + it 'does not update Devise trackable attributes', :clean_gitlab_redis_shared_state do user = create(:user, :blocked) expect { gitlab_sign_in(user) }.not_to change { user.reload.sign_in_count } @@ -55,7 +55,7 @@ feature 'Login', feature: true do expect(page).to have_content('Invalid Login or password.') end - it 'does not update Devise trackable attributes', :redis do + it 'does not update Devise trackable attributes', :clean_gitlab_redis_shared_state do expect { gitlab_sign_in(User.ghost) }.not_to change { User.ghost.reload.sign_in_count } end end diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb index afb613f034e..dc7236fa120 100644 --- a/spec/features/projects/members/sorting_spec.rb +++ b/spec/features/projects/members/sorting_spec.rb @@ -67,7 +67,7 @@ feature 'Projects > Members > Sorting', feature: true do expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Name, descending') end - scenario 'sorts by recent sign in', :redis do + scenario 'sorts by recent sign in', :clean_gitlab_redis_shared_state do visit_members_list(sort: :recent_sign_in) expect(first_member).to include(master.name) @@ -75,7 +75,7 @@ feature 'Projects > Members > Sorting', feature: true do expect(page).to have_css('.member-sort-dropdown .dropdown-toggle-text', text: 'Recent sign in') end - scenario 'sorts by oldest sign in', :redis do + scenario 'sorts by oldest sign in', :clean_gitlab_redis_shared_state do visit_members_list(sort: :oldest_sign_in) expect(first_member).to include(developer.name) diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 992a68b25a5..033ccf06124 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -9,188 +9,222 @@ feature 'Pipeline Schedules', :feature, js: true do let(:scope) { nil } let!(:user) { create(:user) } - before do - project.add_master(user) - sign_in(user) - end - - describe 'GET /projects/pipeline_schedules' do + context 'logged in as master' do before do - visit_pipelines_schedules + project.add_master(user) + gitlab_sign_in(user) end - describe 'The view' do - it 'displays the required information description' do - page.within('.pipeline-schedule-table-row') do - expect(page).to have_content('pipeline schedule') - expect(find(".next-run-cell time")['data-original-title']) - .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y')) - expect(page).to have_link('master') - expect(page).to have_link("##{pipeline.id}") - end + describe 'GET /projects/pipeline_schedules' do + before do + visit_pipelines_schedules end - it 'creates a new scheduled pipeline' do - click_link 'New schedule' + describe 'The view' do + it 'displays the required information description' do + page.within('.pipeline-schedule-table-row') do + expect(page).to have_content('pipeline schedule') + expect(find(".next-run-cell time")['data-original-title']) + .to include(pipeline_schedule.real_next_run.strftime('%b %-d, %Y')) + expect(page).to have_link('master') + expect(page).to have_link("##{pipeline.id}") + end + end - expect(page).to have_content('Schedule a new pipeline') - end + it 'creates a new scheduled pipeline' do + click_link 'New schedule' - it 'changes ownership of the pipeline' do - click_link 'Take ownership' - page.within('.pipeline-schedule-table-row') do - expect(page).not_to have_content('No owner') - expect(page).to have_link('John Doe') + expect(page).to have_content('Schedule a new pipeline') end - end - it 'edits the pipeline' do - page.within('.pipeline-schedule-table-row') do - click_link 'Edit' + it 'changes ownership of the pipeline' do + click_link 'Take ownership' + page.within('.pipeline-schedule-table-row') do + expect(page).not_to have_content('No owner') + expect(page).to have_link('John Doe') + end end - expect(page).to have_content('Edit Pipeline Schedule') + it 'edits the pipeline' do + page.within('.pipeline-schedule-table-row') do + click_link 'Edit' + end + + expect(page).to have_content('Edit Pipeline Schedule') + end + + it 'deletes the pipeline' do + click_link 'Delete' + + expect(page).not_to have_css(".pipeline-schedule-table-row") + end end - it 'deletes the pipeline' do - click_link 'Delete' + context 'when ref is nil' do + before do + pipeline_schedule.update_attribute(:ref, nil) + visit_pipelines_schedules + end - expect(page).not_to have_css(".pipeline-schedule-table-row") + it 'shows a list of the pipeline schedules with empty ref column' do + expect(first('.branch-name-cell').text).to eq('') + end end end - context 'when ref is nil' do + describe 'POST /projects/pipeline_schedules/new' do before do - pipeline_schedule.update_attribute(:ref, nil) - visit_pipelines_schedules + visit_new_pipeline_schedule end - it 'shows a list of the pipeline schedules with empty ref column' do - expect(first('.branch-name-cell').text).to eq('') + it 'sets defaults for timezone and target branch' do + expect(page).to have_button('master') + expect(page).to have_button('UTC') end - end - end - describe 'POST /projects/pipeline_schedules/new' do - before do - visit_new_pipeline_schedule - end + it 'it creates a new scheduled pipeline' do + fill_in_schedule_form + save_pipeline_schedule - it 'sets defaults for timezone and target branch' do - expect(page).to have_button('master') - expect(page).to have_button('UTC') - end + expect(page).to have_content('my fancy description') + end - it 'it creates a new scheduled pipeline' do - fill_in_schedule_form - save_pipeline_schedule + it 'it prevents an invalid form from being submitted' do + save_pipeline_schedule - expect(page).to have_content('my fancy description') + expect(page).to have_content('This field is required') + end end - it 'it prevents an invalid form from being submitted' do - save_pipeline_schedule + describe 'PATCH /projects/pipelines_schedules/:id/edit' do + before do + edit_pipeline_schedule + end - expect(page).to have_content('This field is required') - end - end + it 'it displays existing properties' do + description = find_field('schedule_description').value + expect(description).to eq('pipeline schedule') + expect(page).to have_button('master') + expect(page).to have_button('UTC') + end - describe 'PATCH /projects/pipelines_schedules/:id/edit' do - before do - edit_pipeline_schedule - end + it 'edits the scheduled pipeline' do + fill_in 'schedule_description', with: 'my brand new description' - it 'it displays existing properties' do - description = find_field('schedule_description').value - expect(description).to eq('pipeline schedule') - expect(page).to have_button('master') - expect(page).to have_button('UTC') - end + save_pipeline_schedule - it 'edits the scheduled pipeline' do - fill_in 'schedule_description', with: 'my brand new description' + expect(page).to have_content('my brand new description') + end - save_pipeline_schedule + context 'when ref is nil' do + before do + pipeline_schedule.update_attribute(:ref, nil) + edit_pipeline_schedule + end - expect(page).to have_content('my brand new description') + it 'shows the pipeline schedule with default ref' do + page.within('.js-target-branch-dropdown') do + expect(first('.dropdown-toggle-text').text).to eq('master') + end + end + end end - context 'when ref is nil' do - before do - pipeline_schedule.update_attribute(:ref, nil) - edit_pipeline_schedule + context 'when user creates a new pipeline schedule with variables' do + background do + visit_pipelines_schedules + click_link 'New schedule' + fill_in_schedule_form + all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA') + all('[name="schedule[variables_attributes][][value]"]')[0].set('AAA123') + all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB') + all('[name="schedule[variables_attributes][][value]"]')[1].set('BBB123') + save_pipeline_schedule end - it 'shows the pipeline schedule with default ref' do - page.within('.js-target-branch-dropdown') do - expect(first('.dropdown-toggle-text').text).to eq('master') + scenario 'user sees the new variable in edit window' do + find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click + page.within('.pipeline-variable-list') do + expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-key-input").value).to eq('AAA') + expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-value-input").value).to eq('AAA123') + expect(find(".pipeline-variable-row:nth-child(2) .pipeline-variable-key-input").value).to eq('BBB') + expect(find(".pipeline-variable-row:nth-child(2) .pipeline-variable-value-input").value).to eq('BBB123') end end end - end - context 'when user creates a new pipeline schedule with variables' do - background do - visit_pipelines_schedules - click_link 'New schedule' - fill_in_schedule_form - all('[name="schedule[variables_attributes][][key]"]')[0].set('AAA') - all('[name="schedule[variables_attributes][][value]"]')[0].set('AAA123') - all('[name="schedule[variables_attributes][][key]"]')[1].set('BBB') - all('[name="schedule[variables_attributes][][value]"]')[1].set('BBB123') - save_pipeline_schedule - end + context 'when user edits a variable of a pipeline schedule' do + background do + create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| + create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + end - scenario 'user sees the new variable in edit window' do - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - page.within('.pipeline-variable-list') do - expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-key-input").value).to eq('AAA') - expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-value-input").value).to eq('AAA123') - expect(find(".pipeline-variable-row:nth-child(2) .pipeline-variable-key-input").value).to eq('BBB') - expect(find(".pipeline-variable-row:nth-child(2) .pipeline-variable-value-input").value).to eq('BBB123') + visit_pipelines_schedules + find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click + all('[name="schedule[variables_attributes][][key]"]')[0].set('foo') + all('[name="schedule[variables_attributes][][value]"]')[0].set('bar') + click_button 'Save pipeline schedule' end - end - end - context 'when user edits a variable of a pipeline schedule' do - background do - create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| - create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + scenario 'user sees the updated variable in edit window' do + find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click + page.within('.pipeline-variable-list') do + expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-key-input").value).to eq('foo') + expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-value-input").value).to eq('bar') + end end - - visit_pipelines_schedules - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - all('[name="schedule[variables_attributes][][key]"]')[0].set('foo') - all('[name="schedule[variables_attributes][][value]"]')[0].set('bar') - click_button 'Save pipeline schedule' end - scenario 'user sees the updated variable in edit window' do - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - page.within('.pipeline-variable-list') do - expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-key-input").value).to eq('foo') - expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-value-input").value).to eq('bar') + context 'when user removes a variable of a pipeline schedule' do + background do + create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| + create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + end + + visit_pipelines_schedules + find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click + find('.pipeline-variable-list .pipeline-variable-row-remove-button').click + click_button 'Save pipeline schedule' + end + + scenario 'user does not see the removed variable in edit window' do + find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click + page.within('.pipeline-variable-list') do + expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-key-input").value).to eq('') + expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-value-input").value).to eq('') + end end end end - context 'when user removes a variable of a pipeline schedule' do - background do - create(:ci_pipeline_schedule, project: project, owner: user).tap do |pipeline_schedule| - create(:ci_pipeline_schedule_variable, key: 'AAA', value: 'AAA123', pipeline_schedule: pipeline_schedule) + context 'logged in as non-member' do + before do + gitlab_sign_in(user) + end + + describe 'GET /projects/pipeline_schedules' do + before do + visit_pipelines_schedules end - visit_pipelines_schedules - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - find('.pipeline-variable-list .pipeline-variable-row-remove-button').click - click_button 'Save pipeline schedule' + describe 'The view' do + it 'does not show create schedule button' do + expect(page).not_to have_link('New schedule') + end + end end + end + + context 'not logged in' do + describe 'GET /projects/pipeline_schedules' do + before do + visit_pipelines_schedules + end - scenario 'user does not see the removed variable in edit window' do - find(".content-list .pipeline-schedule-table-row:nth-child(1) .btn-group a[title='Edit']").click - page.within('.pipeline-variable-list') do - expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-key-input").value).to eq('') - expect(find(".pipeline-variable-row:nth-child(1) .pipeline-variable-value-input").value).to eq('') + describe 'The view' do + it 'does not show create schedule button' do + expect(page).not_to have_link('New schedule') + end end end end diff --git a/spec/fixtures/config/redis_cache_config_with_env.yml b/spec/fixtures/config/redis_cache_config_with_env.yml new file mode 100644 index 00000000000..52fd5a06460 --- /dev/null +++ b/spec/fixtures/config/redis_cache_config_with_env.yml @@ -0,0 +1,2 @@ +test: + url: <%= ENV['TEST_GITLAB_REDIS_CACHE_URL'] %> diff --git a/spec/fixtures/config/redis_cache_new_format_host.yml b/spec/fixtures/config/redis_cache_new_format_host.yml new file mode 100644 index 00000000000..a24f3716391 --- /dev/null +++ b/spec/fixtures/config/redis_cache_new_format_host.yml @@ -0,0 +1,29 @@ +# redis://[:password@]host[:port][/db-number][?option=value] +# more details: http://www.iana.org/assignments/uri-schemes/prov/redis +development: + url: redis://:mynewpassword@localhost:6380/10 + sentinels: + - + host: localhost + port: 26380 # point to sentinel, not to redis port + - + host: slave2 + port: 26380 # point to sentinel, not to redis port +test: + url: redis://:mynewpassword@localhost:6380/10 + sentinels: + - + host: localhost + port: 26380 # point to sentinel, not to redis port + - + host: slave2 + port: 26380 # point to sentinel, not to redis port +production: + url: redis://:mynewpassword@localhost:6380/10 + sentinels: + - + host: slave1 + port: 26380 # point to sentinel, not to redis port + - + host: slave2 + port: 26380 # point to sentinel, not to redis port diff --git a/spec/fixtures/config/redis_cache_new_format_socket.yml b/spec/fixtures/config/redis_cache_new_format_socket.yml new file mode 100644 index 00000000000..3634c550163 --- /dev/null +++ b/spec/fixtures/config/redis_cache_new_format_socket.yml @@ -0,0 +1,6 @@ +development: + url: unix:/path/to/redis.cache.sock +test: + url: unix:/path/to/redis.cache.sock +production: + url: unix:/path/to/redis.cache.sock diff --git a/spec/fixtures/config/redis_cache_old_format_host.yml b/spec/fixtures/config/redis_cache_old_format_host.yml new file mode 100644 index 00000000000..3609dcd022e --- /dev/null +++ b/spec/fixtures/config/redis_cache_old_format_host.yml @@ -0,0 +1,5 @@ +# redis://[:password@]host[:port][/db-number][?option=value] +# more details: http://www.iana.org/assignments/uri-schemes/prov/redis +development: redis://:mypassword@localhost:6380/10 +test: redis://:mypassword@localhost:6380/10 +production: redis://:mypassword@localhost:6380/10 diff --git a/spec/fixtures/config/redis_cache_old_format_socket.yml b/spec/fixtures/config/redis_cache_old_format_socket.yml new file mode 100644 index 00000000000..26fa0eda245 --- /dev/null +++ b/spec/fixtures/config/redis_cache_old_format_socket.yml @@ -0,0 +1,3 @@ +development: unix:/path/to/old/redis.cache.sock +test: unix:/path/to/old/redis.cache.sock +production: unix:/path/to/old/redis.cache.sock diff --git a/spec/fixtures/config/redis_new_format_host.yml b/spec/fixtures/config/redis_new_format_host.yml index 13772677a45..8d134d467e9 100644 --- a/spec/fixtures/config/redis_new_format_host.yml +++ b/spec/fixtures/config/redis_new_format_host.yml @@ -5,25 +5,25 @@ development: sentinels: - host: localhost - port: 26380 # point to sentinel, not to redis port + port: 26379 # point to sentinel, not to redis port - host: slave2 - port: 26381 # point to sentinel, not to redis port + port: 26379 # point to sentinel, not to redis port test: url: redis://:mynewpassword@localhost:6379/99 sentinels: - host: localhost - port: 26380 # point to sentinel, not to redis port + port: 26379 # point to sentinel, not to redis port - host: slave2 - port: 26381 # point to sentinel, not to redis port + port: 26379 # point to sentinel, not to redis port production: url: redis://:mynewpassword@localhost:6379/99 sentinels: - host: slave1 - port: 26380 # point to sentinel, not to redis port + port: 26379 # point to sentinel, not to redis port - host: slave2 - port: 26381 # point to sentinel, not to redis port + port: 26379 # point to sentinel, not to redis port diff --git a/spec/fixtures/config/redis_queues_config_with_env.yml b/spec/fixtures/config/redis_queues_config_with_env.yml new file mode 100644 index 00000000000..d16a9d8a7f8 --- /dev/null +++ b/spec/fixtures/config/redis_queues_config_with_env.yml @@ -0,0 +1,2 @@ +test: + url: <%= ENV['TEST_GITLAB_REDIS_QUEUES_URL'] %> diff --git a/spec/fixtures/config/redis_queues_new_format_host.yml b/spec/fixtures/config/redis_queues_new_format_host.yml new file mode 100644 index 00000000000..1535584d779 --- /dev/null +++ b/spec/fixtures/config/redis_queues_new_format_host.yml @@ -0,0 +1,29 @@ +# redis://[:password@]host[:port][/db-number][?option=value] +# more details: http://www.iana.org/assignments/uri-schemes/prov/redis +development: + url: redis://:mynewpassword@localhost:6381/11 + sentinels: + - + host: localhost + port: 26381 # point to sentinel, not to redis port + - + host: slave2 + port: 26381 # point to sentinel, not to redis port +test: + url: redis://:mynewpassword@localhost:6381/11 + sentinels: + - + host: localhost + port: 26381 # point to sentinel, not to redis port + - + host: slave2 + port: 26381 # point to sentinel, not to redis port +production: + url: redis://:mynewpassword@localhost:6381/11 + sentinels: + - + host: slave1 + port: 26381 # point to sentinel, not to redis port + - + host: slave2 + port: 26381 # point to sentinel, not to redis port diff --git a/spec/fixtures/config/redis_queues_new_format_socket.yml b/spec/fixtures/config/redis_queues_new_format_socket.yml new file mode 100644 index 00000000000..b488d84d022 --- /dev/null +++ b/spec/fixtures/config/redis_queues_new_format_socket.yml @@ -0,0 +1,6 @@ +development: + url: unix:/path/to/redis.queues.sock +test: + url: unix:/path/to/redis.queues.sock +production: + url: unix:/path/to/redis.queues.sock diff --git a/spec/fixtures/config/redis_queues_old_format_host.yml b/spec/fixtures/config/redis_queues_old_format_host.yml new file mode 100644 index 00000000000..6531748a8d7 --- /dev/null +++ b/spec/fixtures/config/redis_queues_old_format_host.yml @@ -0,0 +1,5 @@ +# redis://[:password@]host[:port][/db-number][?option=value] +# more details: http://www.iana.org/assignments/uri-schemes/prov/redis +development: redis://:mypassword@localhost:6381/11 +test: redis://:mypassword@localhost:6381/11 +production: redis://:mypassword@localhost:6381/11 diff --git a/spec/fixtures/config/redis_queues_old_format_socket.yml b/spec/fixtures/config/redis_queues_old_format_socket.yml new file mode 100644 index 00000000000..53f5db72758 --- /dev/null +++ b/spec/fixtures/config/redis_queues_old_format_socket.yml @@ -0,0 +1,3 @@ +development: unix:/path/to/old/redis.queues.sock +test: unix:/path/to/old/redis.queues.sock +production: unix:/path/to/old/redis.queues.sock diff --git a/spec/fixtures/config/redis_shared_state_config_with_env.yml b/spec/fixtures/config/redis_shared_state_config_with_env.yml new file mode 100644 index 00000000000..eab7203d0de --- /dev/null +++ b/spec/fixtures/config/redis_shared_state_config_with_env.yml @@ -0,0 +1,2 @@ +test: + url: <%= ENV['TEST_GITLAB_REDIS_SHARED_STATE_URL'] %> diff --git a/spec/fixtures/config/redis_shared_state_new_format_host.yml b/spec/fixtures/config/redis_shared_state_new_format_host.yml new file mode 100644 index 00000000000..1180b2b4a82 --- /dev/null +++ b/spec/fixtures/config/redis_shared_state_new_format_host.yml @@ -0,0 +1,29 @@ +# redis://[:password@]host[:port][/db-number][?option=value] +# more details: http://www.iana.org/assignments/uri-schemes/prov/redis +development: + url: redis://:mynewpassword@localhost:6382/12 + sentinels: + - + host: localhost + port: 26382 # point to sentinel, not to redis port + - + host: slave2 + port: 26382 # point to sentinel, not to redis port +test: + url: redis://:mynewpassword@localhost:6382/12 + sentinels: + - + host: localhost + port: 26382 # point to sentinel, not to redis port + - + host: slave2 + port: 26382 # point to sentinel, not to redis port +production: + url: redis://:mynewpassword@localhost:6382/12 + sentinels: + - + host: slave1 + port: 26382 # point to sentinel, not to redis port + - + host: slave2 + port: 26382 # point to sentinel, not to redis port diff --git a/spec/fixtures/config/redis_shared_state_new_format_socket.yml b/spec/fixtures/config/redis_shared_state_new_format_socket.yml new file mode 100644 index 00000000000..1b0e699729e --- /dev/null +++ b/spec/fixtures/config/redis_shared_state_new_format_socket.yml @@ -0,0 +1,6 @@ +development: + url: unix:/path/to/redis.shared_state.sock +test: + url: unix:/path/to/redis.shared_state.sock +production: + url: unix:/path/to/redis.shared_state.sock diff --git a/spec/fixtures/config/redis_shared_state_old_format_host.yml b/spec/fixtures/config/redis_shared_state_old_format_host.yml new file mode 100644 index 00000000000..fef5e768c5d --- /dev/null +++ b/spec/fixtures/config/redis_shared_state_old_format_host.yml @@ -0,0 +1,5 @@ +# redis://[:password@]host[:port][/db-number][?option=value] +# more details: http://www.iana.org/assignments/uri-schemes/prov/redis +development: redis://:mypassword@localhost:6382/12 +test: redis://:mypassword@localhost:6382/12 +production: redis://:mypassword@localhost:6382/12 diff --git a/spec/fixtures/config/redis_shared_state_old_format_socket.yml b/spec/fixtures/config/redis_shared_state_old_format_socket.yml new file mode 100644 index 00000000000..4746afbb5ef --- /dev/null +++ b/spec/fixtures/config/redis_shared_state_old_format_socket.yml @@ -0,0 +1,3 @@ +development: unix:/path/to/old/redis.shared_state.sock +test: unix:/path/to/old/redis.shared_state.sock +production: unix:/path/to/old/redis.shared_state.sock diff --git a/spec/helpers/award_emoji_helper_spec.rb b/spec/helpers/award_emoji_helper_spec.rb index 7dfd6a3f6b4..035960ed96e 100644 --- a/spec/helpers/award_emoji_helper_spec.rb +++ b/spec/helpers/award_emoji_helper_spec.rb @@ -40,7 +40,7 @@ describe AwardEmojiHelper do it 'returns correct url' do @project = merge_request.project - expected_url = "/#{@project.namespace.path}/#{@project.path}/merge_requests/#{merge_request.id}/toggle_award_emoji" + expected_url = "/#{@project.namespace.path}/#{@project.path}/merge_requests/#{merge_request.iid}/toggle_award_emoji" expect(helper.toggle_award_url(merge_request)).to eq(expected_url) end @@ -52,7 +52,7 @@ describe AwardEmojiHelper do it 'returns correct url' do @project = issue.project - expected_url = "/#{@project.namespace.path}/#{@project.path}/issues/#{issue.id}/toggle_award_emoji" + expected_url = "/#{@project.namespace.path}/#{@project.path}/issues/#{issue.iid}/toggle_award_emoji" expect(helper.toggle_award_url(issue)).to eq(expected_url) end diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index d2e918ef014..b423a09873b 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -60,7 +60,7 @@ describe IssuablesHelper do end end - describe 'counter caching based on issuable type and params', :caching do + describe 'counter caching based on issuable type and params', :use_clean_rails_memory_store_caching do let(:params) do { scope: 'created-by-me', diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 487d9800707..c462d9006ea 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -63,7 +63,7 @@ describe ProjectsHelper do end end - describe "#project_list_cache_key", redis: true do + describe "#project_list_cache_key", clean_gitlab_redis_shared_state: true do let(:project) { create(:project) } it "includes the route" do diff --git a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb index fc72df575be..15b3db0ed3d 100644 --- a/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb +++ b/spec/lib/gitlab/auth/unique_ips_limiter_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Auth::UniqueIpsLimiter, :redis, lib: true do +describe Gitlab::Auth::UniqueIpsLimiter, :clean_gitlab_redis_shared_state, lib: true do include_context 'unique ips sign in limit' let(:user) { create(:user) } diff --git a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb index 07db6c3a640..0daf41a7c86 100644 --- a/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb +++ b/spec/lib/gitlab/cache/ci/project_pipeline_status_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do +describe Gitlab::Cache::Ci::ProjectPipelineStatus, :clean_gitlab_redis_cache do let!(:project) { create(:project) } let(:pipeline_status) { described_class.new(project) } let(:cache_key) { "projects/#{project.id}/pipeline_status" } @@ -28,8 +28,8 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do expect(project.instance_variable_get('@pipeline_status')).to be_a(described_class) end - describe 'without a status in redis' do - it 'loads the status from a commit when it was not in redis' do + describe 'without a status in redis_cache' do + it 'loads the status from a commit when it was not in redis_cache' do empty_status = { sha: nil, status: nil, ref: nil } fake_pipeline = described_class.new( project_without_status, @@ -48,9 +48,9 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do described_class.load_in_batch_for_projects([project_without_status]) end - it 'only connects to redis twice' do + it 'only connects to redis_cache twice' do # Once to load, once to store in the cache - expect(Gitlab::Redis).to receive(:with).exactly(2).and_call_original + expect(Gitlab::Redis::Cache).to receive(:with).exactly(2).and_call_original described_class.load_in_batch_for_projects([project_without_status]) @@ -58,9 +58,9 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do end end - describe 'when a status was cached in redis' do + describe 'when a status was cached in redis_cache' do before do - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref }) end @@ -76,8 +76,8 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do expect(pipeline_status.ref).to eq(ref) end - it 'only connects to redis once' do - expect(Gitlab::Redis).to receive(:with).exactly(1).and_call_original + it 'only connects to redis_cache once' do + expect(Gitlab::Redis::Cache).to receive(:with).exactly(1).and_call_original described_class.load_in_batch_for_projects([project]) @@ -94,8 +94,8 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do end describe '.cached_results_for_projects' do - it 'loads a status from redis for all projects' do - Gitlab::Redis.with do |redis| + it 'loads a status from caching for all projects' do + Gitlab::Redis::Cache.with do |redis| redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref }) end @@ -183,7 +183,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do end end - describe "#load_from_project" do + describe "#load_from_project", :clean_gitlab_redis_cache do let!(:pipeline) { create(:ci_pipeline, :success, project: project, sha: project.commit.sha) } it 'reads the status from the pipeline for the commit' do @@ -203,40 +203,40 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do end end - describe "#store_in_cache", :redis do - it "sets the object in redis" do + describe "#store_in_cache", :clean_gitlab_redis_cache do + it "sets the object in caching" do pipeline_status.sha = '123456' pipeline_status.status = 'failed' pipeline_status.store_in_cache - read_sha, read_status = Gitlab::Redis.with { |redis| redis.hmget(cache_key, :sha, :status) } + read_sha, read_status = Gitlab::Redis::Cache.with { |redis| redis.hmget(cache_key, :sha, :status) } expect(read_sha).to eq('123456') expect(read_status).to eq('failed') end end - describe '#store_in_cache_if_needed', :redis do + describe '#store_in_cache_if_needed', :clean_gitlab_redis_cache do it 'stores the state in the cache when the sha is the HEAD of the project' do create(:ci_pipeline, :success, project: project, sha: project.commit.sha) pipeline_status = described_class.load_for_project(project) pipeline_status.store_in_cache_if_needed - sha, status, ref = Gitlab::Redis.with { |redis| redis.hmget(cache_key, :sha, :status, :ref) } + sha, status, ref = Gitlab::Redis::Cache.with { |redis| redis.hmget(cache_key, :sha, :status, :ref) } expect(sha).not_to be_nil expect(status).not_to be_nil expect(ref).not_to be_nil end - it "doesn't store the status in redis when the sha is not the head of the project" do + it "doesn't store the status in redis_cache when the sha is not the head of the project" do other_status = described_class.new( project, pipeline_info: { sha: "123456", status: "failed" } ) other_status.store_in_cache_if_needed - sha, status = Gitlab::Redis.with { |redis| redis.hmget(cache_key, :sha, :status) } + sha, status = Gitlab::Redis::Cache.with { |redis| redis.hmget(cache_key, :sha, :status) } expect(sha).to be_nil expect(status).to be_nil @@ -244,7 +244,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do it "deletes the cache if the repository doesn't have a head commit" do empty_project = create(:empty_project) - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| redis.mapped_hmset(cache_key, { sha: 'sha', status: 'pending', ref: 'master' }) end @@ -255,7 +255,7 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do }) other_status.store_in_cache_if_needed - sha, status, ref = Gitlab::Redis.with { |redis| redis.hmget("projects/#{empty_project.id}/pipeline_status", :sha, :status, :ref) } + sha, status, ref = Gitlab::Redis::Cache.with { |redis| redis.hmget("projects/#{empty_project.id}/pipeline_status", :sha, :status, :ref) } expect(sha).to be_nil expect(status).to be_nil @@ -263,20 +263,20 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do end end - describe "with a status in redis", :redis do + describe "with a status in caching", :clean_gitlab_redis_cache do let(:status) { 'success' } let(:sha) { '424d1b73bc0d3cb726eb7dc4ce17a4d48552f8c6' } let(:ref) { 'master' } before do - Gitlab::Redis.with do |redis| + Gitlab::Redis::Cache.with do |redis| redis.mapped_hmset(cache_key, { sha: sha, status: status, ref: ref }) end end describe '#load_from_cache' do - it 'reads the status from redis' do + it 'reads the status from redis_cache' do pipeline_status.load_from_cache expect(pipeline_status.sha).to eq(sha) @@ -292,10 +292,10 @@ describe Gitlab::Cache::Ci::ProjectPipelineStatus, :redis do end describe '#delete_from_cache' do - it 'deletes values from redis' do + it 'deletes values from redis_cache' do pipeline_status.delete_from_cache - key_exists = Gitlab::Redis.with { |redis| redis.exists(cache_key) } + key_exists = Gitlab::Redis::Cache.with { |redis| redis.exists(cache_key) } expect(key_exists).to be_falsy end diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb index 8813f129ef5..df7d1b5d27a 100644 --- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb +++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_base_spec.rb @@ -236,7 +236,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca subject.track_rename('namespace', 'path/to/namespace', 'path/to/renamed') old_path, new_path = [nil, nil] - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| rename_info = redis.lpop(key) old_path, new_path = JSON.parse(rename_info) end @@ -268,7 +268,7 @@ describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameBase, :trunca key = 'rename:FakeRenameReservedPathMigrationV1:project' stored_renames = nil rename_count = 0 - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| stored_renames = redis.lrange(key, 0, 1) rename_count = redis.llen(key) end diff --git a/spec/lib/gitlab/exclusive_lease_spec.rb b/spec/lib/gitlab/exclusive_lease_spec.rb index 81bbd70ffb8..590d6da4113 100644 --- a/spec/lib/gitlab/exclusive_lease_spec.rb +++ b/spec/lib/gitlab/exclusive_lease_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Gitlab::ExclusiveLease, type: :redis do +describe Gitlab::ExclusiveLease, type: :clean_gitlab_redis_shared_state do let(:unique_key) { SecureRandom.hex(10) } describe '#try_obtain' do diff --git a/spec/lib/gitlab/health_checks/redis/cache_check_spec.rb b/spec/lib/gitlab/health_checks/redis/cache_check_spec.rb new file mode 100644 index 00000000000..3693f52b51b --- /dev/null +++ b/spec/lib/gitlab/health_checks/redis/cache_check_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' +require_relative '../simple_check_shared' + +describe Gitlab::HealthChecks::Redis::CacheCheck do + include_examples 'simple_check', 'redis_cache_ping', 'RedisCache', 'PONG' +end diff --git a/spec/lib/gitlab/health_checks/redis/queues_check_spec.rb b/spec/lib/gitlab/health_checks/redis/queues_check_spec.rb new file mode 100644 index 00000000000..c69443d205d --- /dev/null +++ b/spec/lib/gitlab/health_checks/redis/queues_check_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' +require_relative '../simple_check_shared' + +describe Gitlab::HealthChecks::Redis::QueuesCheck do + include_examples 'simple_check', 'redis_queues_ping', 'RedisQueues', 'PONG' +end diff --git a/spec/lib/gitlab/health_checks/redis/redis_check_spec.rb b/spec/lib/gitlab/health_checks/redis/redis_check_spec.rb new file mode 100644 index 00000000000..03afc1cd761 --- /dev/null +++ b/spec/lib/gitlab/health_checks/redis/redis_check_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' +require_relative '../simple_check_shared' + +describe Gitlab::HealthChecks::Redis::RedisCheck do + include_examples 'simple_check', 'redis_ping', 'Redis', 'PONG' +end diff --git a/spec/lib/gitlab/health_checks/redis/shared_state_check_spec.rb b/spec/lib/gitlab/health_checks/redis/shared_state_check_spec.rb new file mode 100644 index 00000000000..b72e152bbe2 --- /dev/null +++ b/spec/lib/gitlab/health_checks/redis/shared_state_check_spec.rb @@ -0,0 +1,6 @@ +require 'spec_helper' +require_relative '../simple_check_shared' + +describe Gitlab::HealthChecks::Redis::SharedStateCheck do + include_examples 'simple_check', 'redis_shared_state_ping', 'RedisSharedState', 'PONG' +end diff --git a/spec/lib/gitlab/health_checks/redis_check_spec.rb b/spec/lib/gitlab/health_checks/redis_check_spec.rb deleted file mode 100644 index 734cdcb893e..00000000000 --- a/spec/lib/gitlab/health_checks/redis_check_spec.rb +++ /dev/null @@ -1,6 +0,0 @@ -require 'spec_helper' -require_relative './simple_check_shared' - -describe Gitlab::HealthChecks::RedisCheck do - include_examples 'simple_check', 'redis_ping', 'Redis', 'PONG' -end diff --git a/spec/lib/gitlab/health_checks/simple_check_shared.rb b/spec/lib/gitlab/health_checks/simple_check_shared.rb index 3f871d66034..1abebeac4dd 100644 --- a/spec/lib/gitlab/health_checks/simple_check_shared.rb +++ b/spec/lib/gitlab/health_checks/simple_check_shared.rb @@ -47,7 +47,7 @@ shared_context 'simple_check' do |metrics_prefix, check_name, success_result| allow(described_class).to receive(:check).and_return 'error!' end - it { is_expected.to have_attributes(success: false, message: "unexpected #{check_name} check result: error!") } + it { is_expected.to have_attributes(success: false, message: "unexpected #{described_class.human_name} check result: error!") } end context 'Check is timeouting' do @@ -55,7 +55,7 @@ shared_context 'simple_check' do |metrics_prefix, check_name, success_result| allow(described_class).to receive(:check ).and_return Timeout::Error.new end - it { is_expected.to have_attributes(success: false, message: "#{check_name} check timed out") } + it { is_expected.to have_attributes(success: false, message: "#{described_class.human_name} check timed out") } end end diff --git a/spec/lib/gitlab/performance_bar_spec.rb b/spec/lib/gitlab/performance_bar_spec.rb index 8a586bdbf63..b8a2267f1a4 100644 --- a/spec/lib/gitlab/performance_bar_spec.rb +++ b/spec/lib/gitlab/performance_bar_spec.rb @@ -7,7 +7,7 @@ describe Gitlab::PerformanceBar do described_class.enabled?(user) end - it 'caches the allowed user IDs in cache', :caching do + it 'caches the allowed user IDs in cache', :use_clean_rails_memory_store_caching do expect do expect(described_class.enabled?(user)).to be_truthy end.not_to exceed_query_limit(0) diff --git a/spec/lib/gitlab/redis/cache_spec.rb b/spec/lib/gitlab/redis/cache_spec.rb new file mode 100644 index 00000000000..5a4f17cfcf6 --- /dev/null +++ b/spec/lib/gitlab/redis/cache_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Gitlab::Redis::Cache do + let(:config_file_name) { "config/redis.cache.yml" } + let(:environment_config_file_name) { "GITLAB_REDIS_CACHE_CONFIG_FILE" } + let(:config_old_format_socket) { "spec/fixtures/config/redis_cache_old_format_socket.yml" } + let(:config_new_format_socket) { "spec/fixtures/config/redis_cache_new_format_socket.yml" } + let(:old_socket_path) {"/path/to/old/redis.cache.sock" } + let(:new_socket_path) {"/path/to/redis.cache.sock" } + let(:config_old_format_host) { "spec/fixtures/config/redis_cache_old_format_host.yml" } + let(:config_new_format_host) { "spec/fixtures/config/redis_cache_new_format_host.yml" } + let(:redis_port) { 6380 } + let(:redis_database) { 10 } + let(:sentinel_port) { redis_port + 20000 } + let(:config_with_environment_variable_inside) { "spec/fixtures/config/redis_cache_config_with_env.yml"} + let(:config_env_variable_url) {"TEST_GITLAB_REDIS_CACHE_URL"} + let(:class_redis_url) { Gitlab::Redis::Cache::DEFAULT_REDIS_CACHE_URL } + + include_examples "redis_shared_examples" +end diff --git a/spec/lib/gitlab/redis/queues_spec.rb b/spec/lib/gitlab/redis/queues_spec.rb new file mode 100644 index 00000000000..01ca25635a9 --- /dev/null +++ b/spec/lib/gitlab/redis/queues_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Gitlab::Redis::Queues do + let(:config_file_name) { "config/redis.queues.yml" } + let(:environment_config_file_name) { "GITLAB_REDIS_QUEUES_CONFIG_FILE" } + let(:config_old_format_socket) { "spec/fixtures/config/redis_queues_old_format_socket.yml" } + let(:config_new_format_socket) { "spec/fixtures/config/redis_queues_new_format_socket.yml" } + let(:old_socket_path) {"/path/to/old/redis.queues.sock" } + let(:new_socket_path) {"/path/to/redis.queues.sock" } + let(:config_old_format_host) { "spec/fixtures/config/redis_queues_old_format_host.yml" } + let(:config_new_format_host) { "spec/fixtures/config/redis_queues_new_format_host.yml" } + let(:redis_port) { 6381 } + let(:redis_database) { 11 } + let(:sentinel_port) { redis_port + 20000 } + let(:config_with_environment_variable_inside) { "spec/fixtures/config/redis_queues_config_with_env.yml"} + let(:config_env_variable_url) {"TEST_GITLAB_REDIS_QUEUES_URL"} + let(:class_redis_url) { Gitlab::Redis::Queues::DEFAULT_REDIS_QUEUES_URL } + + include_examples "redis_shared_examples" +end diff --git a/spec/lib/gitlab/redis/shared_state_spec.rb b/spec/lib/gitlab/redis/shared_state_spec.rb new file mode 100644 index 00000000000..24b73745dc5 --- /dev/null +++ b/spec/lib/gitlab/redis/shared_state_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Gitlab::Redis::SharedState do + let(:config_file_name) { "config/redis.shared_state.yml" } + let(:environment_config_file_name) { "GITLAB_REDIS_SHARED_STATE_CONFIG_FILE" } + let(:config_old_format_socket) { "spec/fixtures/config/redis_shared_state_old_format_socket.yml" } + let(:config_new_format_socket) { "spec/fixtures/config/redis_shared_state_new_format_socket.yml" } + let(:old_socket_path) {"/path/to/old/redis.shared_state.sock" } + let(:new_socket_path) {"/path/to/redis.shared_state.sock" } + let(:config_old_format_host) { "spec/fixtures/config/redis_shared_state_old_format_host.yml" } + let(:config_new_format_host) { "spec/fixtures/config/redis_shared_state_new_format_host.yml" } + let(:redis_port) { 6382 } + let(:redis_database) { 12 } + let(:sentinel_port) { redis_port + 20000 } + let(:config_with_environment_variable_inside) { "spec/fixtures/config/redis_shared_state_config_with_env.yml"} + let(:config_env_variable_url) {"TEST_GITLAB_REDIS_SHARED_STATE_URL"} + let(:class_redis_url) { Gitlab::Redis::SharedState::DEFAULT_REDIS_SHARED_STATE_URL } + + include_examples "redis_shared_examples" +end diff --git a/spec/lib/gitlab/redis/wrapper_spec.rb b/spec/lib/gitlab/redis/wrapper_spec.rb new file mode 100644 index 00000000000..e1becd0a614 --- /dev/null +++ b/spec/lib/gitlab/redis/wrapper_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Gitlab::Redis::Wrapper do + let(:config_file_name) { "config/resque.yml" } + let(:environment_config_file_name) { "GITLAB_REDIS_CONFIG_FILE" } + let(:config_old_format_socket) { "spec/fixtures/config/redis_old_format_socket.yml" } + let(:config_new_format_socket) { "spec/fixtures/config/redis_new_format_socket.yml" } + let(:old_socket_path) {"/path/to/old/redis.sock" } + let(:new_socket_path) {"/path/to/redis.sock" } + let(:config_old_format_host) { "spec/fixtures/config/redis_old_format_host.yml" } + let(:config_new_format_host) { "spec/fixtures/config/redis_new_format_host.yml" } + let(:redis_port) { 6379 } + let(:redis_database) { 99 } + let(:sentinel_port) { redis_port + 20000 } + let(:config_with_environment_variable_inside) { "spec/fixtures/config/redis_config_with_env.yml"} + let(:config_env_variable_url) {"TEST_GITLAB_REDIS_URL"} + let(:class_redis_url) { Gitlab::Redis::Wrapper::DEFAULT_REDIS_URL } + + include_examples "redis_shared_examples" +end diff --git a/spec/lib/gitlab/sidekiq_status_spec.rb b/spec/lib/gitlab/sidekiq_status_spec.rb index 496e50fbae4..c2e77ef6b6c 100644 --- a/spec/lib/gitlab/sidekiq_status_spec.rb +++ b/spec/lib/gitlab/sidekiq_status_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::SidekiqStatus do - describe '.set', :redis do + describe '.set', :clean_gitlab_redis_shared_state do it 'stores the job ID' do described_class.set('123') @@ -14,7 +14,7 @@ describe Gitlab::SidekiqStatus do end end - describe '.unset', :redis do + describe '.unset', :clean_gitlab_redis_shared_state do it 'removes the job ID' do described_class.set('123') described_class.unset('123') @@ -27,7 +27,7 @@ describe Gitlab::SidekiqStatus do end end - describe '.all_completed?', :redis do + describe '.all_completed?', :clean_gitlab_redis_shared_state do it 'returns true if all jobs have been completed' do expect(described_class.all_completed?(%w(123))).to eq(true) end @@ -39,7 +39,7 @@ describe Gitlab::SidekiqStatus do end end - describe '.num_running', :redis do + describe '.num_running', :clean_gitlab_redis_shared_state do it 'returns 0 if all jobs have been completed' do expect(described_class.num_running(%w(123))).to eq(0) end @@ -52,7 +52,7 @@ describe Gitlab::SidekiqStatus do end end - describe '.num_completed', :redis do + describe '.num_completed', :clean_gitlab_redis_shared_state do it 'returns 1 if all jobs have been completed' do expect(described_class.num_completed(%w(123))).to eq(1) end @@ -74,7 +74,7 @@ describe Gitlab::SidekiqStatus do end end - describe 'completed', :redis do + describe 'completed', :clean_gitlab_redis_shared_state do it 'returns the completed job' do expect(described_class.completed_jids(%w(123))).to eq(['123']) end diff --git a/spec/lib/gitlab/user_activities_spec.rb b/spec/lib/gitlab/user_activities_spec.rb index 187d88c8c58..a4ea0ac59e9 100644 --- a/spec/lib/gitlab/user_activities_spec.rb +++ b/spec/lib/gitlab/user_activities_spec.rb @@ -1,27 +1,27 @@ require 'spec_helper' -describe Gitlab::UserActivities, :redis, lib: true do +describe Gitlab::UserActivities, :clean_gitlab_redis_shared_state, lib: true do let(:now) { Time.now } describe '.record' do context 'with no time given' do - it 'uses Time.now and records an activity in Redis' do + it 'uses Time.now and records an activity in SharedState' do Timecop.freeze do now # eager-load now described_class.record(42) end - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]]) end end end context 'with a time given' do - it 'uses the given time and records an activity in Redis' do + it 'uses the given time and records an activity in SharedState' do described_class.record(42, now) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]]) end end @@ -31,30 +31,30 @@ describe Gitlab::UserActivities, :redis, lib: true do describe '.delete' do context 'with a single key' do context 'and key exists' do - it 'removes the pair from Redis' do + it 'removes the pair from SharedState' do described_class.record(42, now) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]]) end subject.delete(42) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []]) end end end context 'and key does not exist' do - it 'removes the pair from Redis' do - Gitlab::Redis.with do |redis| + it 'removes the pair from SharedState' do + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []]) end subject.delete(42) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []]) end end @@ -63,33 +63,33 @@ describe Gitlab::UserActivities, :redis, lib: true do context 'with multiple keys' do context 'and all keys exist' do - it 'removes the pair from Redis' do + it 'removes the pair from SharedState' do described_class.record(41, now) described_class.record(42, now) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['41', now.to_i.to_s], ['42', now.to_i.to_s]]]) end subject.delete(41, 42) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []]) end end end context 'and some keys does not exist' do - it 'removes the existing pair from Redis' do + it 'removes the existing pair from SharedState' do described_class.record(42, now) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', [['42', now.to_i.to_s]]]) end subject.delete(41, 42) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| expect(redis.hscan(described_class::KEY, 0)).to eq(['0', []]) end end diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb index 493ff3bb5fb..efff0a152a8 100644 --- a/spec/lib/gitlab/workhorse_spec.rb +++ b/spec/lib/gitlab/workhorse_spec.rb @@ -276,7 +276,7 @@ describe Gitlab::Workhorse, lib: true do end it 'set and notify' do - expect_any_instance_of(Redis).to receive(:publish) + expect_any_instance_of(::Redis).to receive(:publish) .with(described_class::NOTIFICATION_CHANNEL, "test-key=test-value") subject @@ -310,7 +310,7 @@ describe Gitlab::Workhorse, lib: true do end it 'does not notify' do - expect_any_instance_of(Redis).not_to receive(:publish) + expect_any_instance_of(::Redis).not_to receive(:publish) subject end diff --git a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb index 4223d2337a8..5b633dd349b 100644 --- a/spec/migrations/migrate_process_commit_worker_jobs_spec.rb +++ b/spec/migrations/migrate_process_commit_worker_jobs_spec.rb @@ -54,7 +54,7 @@ describe MigrateProcessCommitWorkerJobs do end end - describe '#up', :redis do + describe '#up', :clean_gitlab_redis_shared_state do let(:migration) { described_class.new } def job_count @@ -172,7 +172,7 @@ describe MigrateProcessCommitWorkerJobs do end end - describe '#down', :redis do + describe '#down', :clean_gitlab_redis_shared_state do let(:migration) { described_class.new } def job_count diff --git a/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb b/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb index e3b42b5eac8..063829be546 100644 --- a/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb +++ b/spec/migrations/migrate_user_activities_to_users_last_activity_on_spec.rb @@ -3,13 +3,13 @@ require 'spec_helper' require Rails.root.join('db', 'post_migrate', '20170324160416_migrate_user_activities_to_users_last_activity_on.rb') -describe MigrateUserActivitiesToUsersLastActivityOn, :redis, :truncate do +describe MigrateUserActivitiesToUsersLastActivityOn, :clean_gitlab_redis_shared_state, :truncate do let(:migration) { described_class.new } let!(:user_active_1) { create(:user) } let!(:user_active_2) { create(:user) } def record_activity(user, time) - Gitlab::Redis.with do |redis| + Gitlab::Redis::SharedState.with do |redis| redis.zadd(described_class::USER_ACTIVITY_SET_KEY, time.to_i, user.username) end end diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb index 76ce558eea0..4b9cce28e0e 100644 --- a/spec/models/ci/runner_spec.rb +++ b/spec/models/ci/runner_spec.rb @@ -276,14 +276,14 @@ describe Ci::Runner, models: true do it 'sets a new last_update value when it is called the first time' do last_update = runner.ensure_runner_queue_value - expect_value_in_redis.to eq(last_update) + expect_value_in_queues.to eq(last_update) end it 'does not change if it is not expired and called again' do last_update = runner.ensure_runner_queue_value expect(runner.ensure_runner_queue_value).to eq(last_update) - expect_value_in_redis.to eq(last_update) + expect_value_in_queues.to eq(last_update) end context 'updates runner queue after changing editable value' do @@ -294,7 +294,7 @@ describe Ci::Runner, models: true do end it 'sets a new last_update value' do - expect_value_in_redis.not_to eq(last_update) + expect_value_in_queues.not_to eq(last_update) end end @@ -306,12 +306,12 @@ describe Ci::Runner, models: true do end it 'has an old last_update value' do - expect_value_in_redis.to eq(last_update) + expect_value_in_queues.to eq(last_update) end end - def expect_value_in_redis - Gitlab::Redis.with do |redis| + def expect_value_in_queues + Gitlab::Redis::Queues.with do |redis| runner_queue_key = runner.send(:runner_queue_key) expect(redis.get(runner_queue_key)) end @@ -330,7 +330,7 @@ describe Ci::Runner, models: true do end it 'cleans up the queue' do - Gitlab::Redis.with do |redis| + Gitlab::Redis::Queues.with do |redis| expect(redis.get(queue_key)).to be_nil end end diff --git a/spec/models/concerns/reactive_caching_spec.rb b/spec/models/concerns/reactive_caching_spec.rb index 808247ebfd5..5f9b7e0a367 100644 --- a/spec/models/concerns/reactive_caching_spec.rb +++ b/spec/models/concerns/reactive_caching_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe ReactiveCaching, caching: true do +describe ReactiveCaching, :use_clean_rails_memory_store_caching do include ReactiveCachingHelpers class CacheTest diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/project_services/bamboo_service_spec.rb index 7b1a554d1fb..99190d763f2 100644 --- a/spec/models/project_services/bamboo_service_spec.rb +++ b/spec/models/project_services/bamboo_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe BambooService, models: true, caching: true do +describe BambooService, :use_clean_rails_memory_store_caching, models: true do include ReactiveCachingHelpers let(:bamboo_url) { 'http://gitlab.com/bamboo' } diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb index dd529597067..b4ee6691e67 100644 --- a/spec/models/project_services/buildkite_service_spec.rb +++ b/spec/models/project_services/buildkite_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe BuildkiteService, models: true, caching: true do +describe BuildkiteService, :use_clean_rails_memory_store_caching, models: true do include ReactiveCachingHelpers let(:project) { create(:empty_project) } diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb index 1400175427f..c9ac256ff38 100644 --- a/spec/models/project_services/drone_ci_service_spec.rb +++ b/spec/models/project_services/drone_ci_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe DroneCiService, models: true, caching: true do +describe DroneCiService, :use_clean_rails_memory_store_caching, models: true do include ReactiveCachingHelpers describe 'associations' do diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index 5ba523a478a..b66bb5321ab 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe KubernetesService, models: true, caching: true do +describe KubernetesService, :use_clean_rails_memory_store_caching, models: true do include KubernetesHelpers include ReactiveCachingHelpers diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb index 37f23b1243c..3fb134ec3b7 100644 --- a/spec/models/project_services/prometheus_service_spec.rb +++ b/spec/models/project_services/prometheus_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe PrometheusService, models: true, caching: true do +describe PrometheusService, :use_clean_rails_memory_store_caching, models: true do include PrometheusHelpers include ReactiveCachingHelpers diff --git a/spec/models/project_services/teamcity_service_spec.rb b/spec/models/project_services/teamcity_service_spec.rb index 6b004098510..3f3a74d0f96 100644 --- a/spec/models/project_services/teamcity_service_spec.rb +++ b/spec/models/project_services/teamcity_service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe TeamcityService, models: true, caching: true do +describe TeamcityService, :use_clean_rails_memory_store_caching, models: true do include ReactiveCachingHelpers let(:teamcity_url) { 'http://gitlab.com/teamcity' } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 99bfab70088..c4bc129dd37 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -899,7 +899,7 @@ describe Project, models: true do end end - describe '.cached_count', caching: true do + describe '.cached_count', :use_clean_rails_memory_store_caching do let(:group) { create(:group, :public) } let!(:project1) { create(:empty_project, :public, group: group) } let!(:project2) { create(:empty_project, :public, group: group) } diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index af305e9b234..7635b0868e7 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -561,7 +561,7 @@ describe Repository, models: true do end end - describe "#changelog", caching: true do + describe "#changelog", :use_clean_rails_memory_store_caching do it 'accepts changelog' do expect(repository.tree).to receive(:blobs).and_return([TestBlob.new('changelog')]) @@ -593,7 +593,7 @@ describe Repository, models: true do end end - describe "#license_blob", caching: true do + describe "#license_blob", :use_clean_rails_memory_store_caching do before do repository.delete_file( user, 'LICENSE', message: 'Remove LICENSE', branch_name: 'master') @@ -638,7 +638,7 @@ describe Repository, models: true do end end - describe '#license_key', caching: true do + describe '#license_key', :use_clean_rails_memory_store_caching do before do repository.delete_file(user, 'LICENSE', message: 'Remove LICENSE', branch_name: 'master') @@ -703,7 +703,7 @@ describe Repository, models: true do end end - describe "#gitlab_ci_yml", caching: true do + describe "#gitlab_ci_yml", :use_clean_rails_memory_store_caching do it 'returns valid file' do files = [TestBlob.new('file'), TestBlob.new('.gitlab-ci.yml'), TestBlob.new('copying')] expect(repository.tree).to receive(:blobs).and_return(files) @@ -1611,7 +1611,7 @@ describe Repository, models: true do end end - describe '#contribution_guide', caching: true do + describe '#contribution_guide', :use_clean_rails_memory_store_caching do it 'returns and caches the output' do expect(repository).to receive(:file_on_head) .with(:contributing) @@ -1625,7 +1625,7 @@ describe Repository, models: true do end end - describe '#gitignore', caching: true do + describe '#gitignore', :use_clean_rails_memory_store_caching do it 'returns and caches the output' do expect(repository).to receive(:file_on_head) .with(:gitignore) @@ -1638,7 +1638,7 @@ describe Repository, models: true do end end - describe '#koding_yml', caching: true do + describe '#koding_yml', :use_clean_rails_memory_store_caching do it 'returns and caches the output' do expect(repository).to receive(:file_on_head) .with(:koding) @@ -1651,7 +1651,7 @@ describe Repository, models: true do end end - describe '#readme', caching: true do + describe '#readme', :use_clean_rails_memory_store_caching do context 'with a non-existing repository' do it 'returns nil' do allow(repository).to receive(:tree).with(:head).and_return(nil) @@ -1822,7 +1822,7 @@ describe Repository, models: true do end end - describe '#cache_method_output', caching: true do + describe '#cache_method_output', :use_clean_rails_memory_store_caching do context 'with a non-existing repository' do let(:value) do repository.cache_method_output(:cats, fallback: 10) do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 448555d2190..d04162a527f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -348,7 +348,7 @@ describe User, models: true do end end - describe '#update_tracked_fields!', :redis do + describe '#update_tracked_fields!', :clean_gitlab_redis_shared_state do let(:request) { OpenStruct.new(remote_ip: "127.0.0.1") } let(:user) { create(:user) } @@ -1684,7 +1684,7 @@ describe User, models: true do end end - describe '#refresh_authorized_projects', redis: true do + describe '#refresh_authorized_projects', clean_gitlab_redis_shared_state: true do let(:project1) { create(:empty_project) } let(:project2) { create(:empty_project) } let(:user) { create(:user) } diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index cde4fa888a0..453eb4683a0 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -168,7 +168,7 @@ describe API::Internal do end end - describe "POST /internal/allowed", :redis do + describe "POST /internal/allowed", :clean_gitlab_redis_shared_state do context "access granted" do before do project.team << [user, :developer] diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 360a82196a8..9098ae6bcda 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -69,6 +69,22 @@ describe API::MergeRequests do expect(json_response.first['merge_commit_sha']).to eq(merge_request_merged.merge_commit_sha) end + it "returns an array of all merge_requests using simple mode" do + get api("/projects/#{project.id}/merge_requests?view=simple", user) + + expect(response).to have_http_status(200) + expect(response).to include_pagination_headers + expect(json_response.last.keys).to match_array(%w(id iid title web_url created_at description project_id state updated_at)) + expect(json_response).to be_an Array + expect(json_response.length).to eq(3) + expect(json_response.last['iid']).to eq(merge_request.iid) + expect(json_response.last['title']).to eq(merge_request.title) + expect(json_response.last).to have_key('web_url') + expect(json_response.first['iid']).to eq(merge_request_merged.iid) + expect(json_response.first['title']).to eq(merge_request_merged.title) + expect(json_response.first).to have_key('web_url') + end + it "returns an array of all merge_requests" do get api("/projects/#{project.id}/merge_requests?state", user) diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index c34b88f0741..a2368c9d996 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -1313,7 +1313,7 @@ describe API::Users do end end - context "user activities", :redis do + context "user activities", :clean_gitlab_redis_shared_state do let!(:old_active_user) { create(:user, last_activity_on: Time.utc(2000, 1, 1)) } let!(:newly_active_user) { create(:user, last_activity_on: 2.days.ago.midday) } diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index 185679e1a0f..d0443a450a2 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -406,7 +406,7 @@ describe 'Git HTTP requests', lib: true do end end - it 'updates the user last activity', :redis do + it 'updates the user last activity', :clean_gitlab_redis_shared_state do expect(user_activity(user)).to be_nil download(path, env) do |response| diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb index 6d1f0b24196..ebba28ba8ce 100644 --- a/spec/requests/openid_connect_spec.rb +++ b/spec/requests/openid_connect_spec.rb @@ -98,7 +98,7 @@ describe 'OpenID Connect requests' do expect(@payload['sub']).to eq hashed_subject end - it 'includes the time of the last authentication', :redis do + it 'includes the time of the last authentication', :clean_gitlab_redis_shared_state do expect(@payload['auth_time']).to eq user.current_sign_in_at.to_i end diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb index b06cefe071d..8d067c194cc 100644 --- a/spec/services/event_create_service_spec.rb +++ b/spec/services/event_create_service_spec.rb @@ -113,7 +113,7 @@ describe EventCreateService, services: true do end end - describe '#push', :redis do + describe '#push', :clean_gitlab_redis_shared_state do let(:project) { create(:empty_project) } let(:user) { create(:user) } diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index 8e8816870e1..3f77ed10069 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -527,14 +527,18 @@ describe GitPushService, services: true do let(:housekeeping) { Projects::HousekeepingService.new(project) } before do - # Flush any raw Redis data stored by the housekeeping code. - Gitlab::Redis.with { |conn| conn.flushall } + # Flush any raw key-value data stored by the housekeeping code. + Gitlab::Redis::Cache.with { |conn| conn.flushall } + Gitlab::Redis::Queues.with { |conn| conn.flushall } + Gitlab::Redis::SharedState.with { |conn| conn.flushall } allow(Projects::HousekeepingService).to receive(:new).and_return(housekeeping) end after do - Gitlab::Redis.with { |conn| conn.flushall } + Gitlab::Redis::Cache.with { |conn| conn.flushall } + Gitlab::Redis::Queues.with { |conn| conn.flushall } + Gitlab::Redis::SharedState.with { |conn| conn.flushall } end it 'does not perform housekeeping when not needed' do diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb index 697dc18feb0..b399d3402fd 100644 --- a/spec/services/projects/destroy_service_spec.rb +++ b/spec/services/projects/destroy_service_spec.rb @@ -60,14 +60,14 @@ describe Projects::DestroyService, services: true do before do new_user = create(:user) project.team.add_user(new_user, Gitlab::Access::DEVELOPER) - allow_any_instance_of(Projects::DestroyService).to receive(:flush_caches).and_raise(Redis::CannotConnectError) + allow_any_instance_of(Projects::DestroyService).to receive(:flush_caches).and_raise(::Redis::CannotConnectError) end it 'keeps project team intact upon an error' do Sidekiq::Testing.inline! do begin destroy_project(project, user, {}) - rescue Redis::CannotConnectError + rescue ::Redis::CannotConnectError end end diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 175a42a32d9..de41cbab14c 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -908,7 +908,7 @@ describe TodoService, services: true do end end - it 'caches the number of todos of a user', :caching do + it 'caches the number of todos of a user', :use_clean_rails_memory_store_caching do create(:todo, :mentioned, user: john_doe, target: issue, project: project) todo = create(:todo, :mentioned, user: john_doe, target: issue, project: project) TodoService.new.mark_todos_as_done([todo], john_doe) diff --git a/spec/services/users/activity_service_spec.rb b/spec/services/users/activity_service_spec.rb index 2e009d4ce1c..e5330d1d3e4 100644 --- a/spec/services/users/activity_service_spec.rb +++ b/spec/services/users/activity_service_spec.rb @@ -7,7 +7,7 @@ describe Users::ActivityService, services: true do subject(:service) { described_class.new(user, 'type') } - describe '#execute', :redis do + describe '#execute', :clean_gitlab_redis_shared_state do context 'when last activity is nil' do before do service.execute diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb index b65cadbb2f5..1c0f55d2965 100644 --- a/spec/services/users/refresh_authorized_projects_service_spec.rb +++ b/spec/services/users/refresh_authorized_projects_service_spec.rb @@ -8,7 +8,7 @@ describe Users::RefreshAuthorizedProjectsService do let(:user) { project.namespace.owner } let(:service) { described_class.new(user) } - describe '#execute', :redis do + describe '#execute', :clean_gitlab_redis_shared_state do it 'refreshes the authorizations using a lease' do expect_any_instance_of(Gitlab::ExclusiveLease).to receive(:try_obtain) .and_return('foo') diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a497b8613bb..dc0bdd9f4c7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -91,20 +91,30 @@ RSpec.configure do |config| end end - config.around(:each, :caching) do |example| + config.around(:each, :use_clean_rails_memory_store_caching) do |example| caching_store = Rails.cache - Rails.cache = ActiveSupport::Cache::MemoryStore.new if example.metadata[:caching] + Rails.cache = ActiveSupport::Cache::MemoryStore.new + example.run + Rails.cache = caching_store end - config.around(:each, :redis) do |example| - Gitlab::Redis.with(&:flushall) + config.around(:each, :clean_gitlab_redis_cache) do |example| + Gitlab::Redis::Cache.with(&:flushall) + + example.run + + Gitlab::Redis::Cache.with(&:flushall) + end + + config.around(:each, :clean_gitlab_redis_shared_state) do |example| + Gitlab::Redis::SharedState.with(&:flushall) Sidekiq.redis(&:flushall) example.run - Gitlab::Redis.with(&:flushall) + Gitlab::Redis::SharedState.with(&:flushall) Sidekiq.redis(&:flushall) end diff --git a/spec/lib/gitlab/redis_spec.rb b/spec/support/redis/redis_shared_examples.rb index 593aa5038ad..f9552e41894 100644 --- a/spec/lib/gitlab/redis_spec.rb +++ b/spec/support/redis/redis_shared_examples.rb @@ -1,12 +1,10 @@ -require 'spec_helper' - -describe Gitlab::Redis do +RSpec.shared_examples "redis_shared_examples" do include StubENV - let(:config) { 'config/resque.yml' } + let(:test_redis_url) { "redis://redishost:#{redis_port}"} before(:each) do - stub_env('GITLAB_REDIS_CONFIG_FILE', Rails.root.join(config).to_s) + stub_env(environment_config_file_name, Rails.root.join(config_file_name)) clear_raw_config end @@ -26,46 +24,40 @@ describe Gitlab::Redis do end context 'when url contains unix socket reference' do - let(:config_old) { 'spec/fixtures/config/redis_old_format_socket.yml' } - let(:config_new) { 'spec/fixtures/config/redis_new_format_socket.yml' } - context 'with old format' do - let(:config) { config_old } + let(:config_file_name) { config_old_format_socket } it 'returns path key instead' do - is_expected.to include(path: '/path/to/old/redis.sock') + is_expected.to include(path: old_socket_path) is_expected.not_to have_key(:url) end end context 'with new format' do - let(:config) { config_new } + let(:config_file_name) { config_new_format_socket } it 'returns path key instead' do - is_expected.to include(path: '/path/to/redis.sock') + is_expected.to include(path: new_socket_path) is_expected.not_to have_key(:url) end end end context 'when url is host based' do - let(:config_old) { 'spec/fixtures/config/redis_old_format_host.yml' } - let(:config_new) { 'spec/fixtures/config/redis_new_format_host.yml' } - context 'with old format' do - let(:config) { config_old } + let(:config_file_name) { config_old_format_host } it 'returns hash with host, port, db, and password' do - is_expected.to include(host: 'localhost', password: 'mypassword', port: 6379, db: 99) + is_expected.to include(host: 'localhost', password: 'mypassword', port: redis_port, db: redis_database) is_expected.not_to have_key(:url) end end context 'with new format' do - let(:config) { config_new } + let(:config_file_name) { config_new_format_host } it 'returns hash with host, port, db, and password' do - is_expected.to include(host: 'localhost', password: 'mynewpassword', port: 6379, db: 99) + is_expected.to include(host: 'localhost', password: 'mynewpassword', port: redis_port, db: redis_database) is_expected.not_to have_key(:url) end end @@ -73,30 +65,22 @@ describe Gitlab::Redis do end describe '.url' do - it 'withstands mutation' do - url1 = described_class.url - url2 = described_class.url - url1 << 'foobar' - - expect(url2).not_to end_with('foobar') - end - context 'when yml file with env variable' do - let(:config) { 'spec/fixtures/config/redis_config_with_env.yml' } + let(:config_file_name) { config_with_environment_variable_inside } before do - stub_env('TEST_GITLAB_REDIS_URL', 'redis://redishost:6379') + stub_env(config_env_variable_url, test_redis_url) end it 'reads redis url from env variable' do - expect(described_class.url).to eq 'redis://redishost:6379' + expect(described_class.url).to eq test_redis_url end end end describe '._raw_config' do subject { described_class._raw_config } - let(:config) { '/var/empty/doesnotexist' } + let(:config_file_name) { '/var/empty/doesnotexist' } it 'should be frozen' do expect(subject).to be_frozen @@ -105,6 +89,12 @@ describe Gitlab::Redis do it 'returns false when the file does not exist' do expect(subject).to eq(false) end + + it "returns false when the filename can't be determined" do + expect(described_class).to receive(:config_file_name).and_return(nil) + + expect(subject).to eq(false) + end end describe '.with' do @@ -124,7 +114,7 @@ describe Gitlab::Redis do it 'instantiates a connection pool with size 5' do expect(ConnectionPool).to receive(:new).with(size: 5).and_call_original - described_class.with { |_redis| true } + described_class.with { |_redis_shared_example| true } end end @@ -137,7 +127,7 @@ describe Gitlab::Redis do it 'instantiates a connection pool with a size based on the concurrency of the worker' do expect(ConnectionPool).to receive(:new).with(size: 18 + 5).and_call_original - described_class.with { |_redis| true } + described_class.with { |_redis_shared_example| true } end end end @@ -146,16 +136,16 @@ describe Gitlab::Redis do subject { described_class.new(Rails.env).sentinels } context 'when sentinels are defined' do - let(:config) { 'spec/fixtures/config/redis_new_format_host.yml' } + let(:config_file_name) { config_new_format_host } it 'returns an array of hashes with host and port keys' do - is_expected.to include(host: 'localhost', port: 26380) - is_expected.to include(host: 'slave2', port: 26381) + is_expected.to include(host: 'localhost', port: sentinel_port) + is_expected.to include(host: 'slave2', port: sentinel_port) end end context 'when sentinels are not defined' do - let(:config) { 'spec/fixtures/config/redis_old_format_host.yml' } + let(:config_file_name) { config_old_format_host } it 'returns nil' do is_expected.to be_nil @@ -167,7 +157,7 @@ describe Gitlab::Redis do subject { described_class.new(Rails.env).sentinels? } context 'when sentinels are defined' do - let(:config) { 'spec/fixtures/config/redis_new_format_host.yml' } + let(:config_file_name) { config_new_format_host } it 'returns true' do is_expected.to be_truthy @@ -175,7 +165,7 @@ describe Gitlab::Redis do end context 'when sentinels are not defined' do - let(:config) { 'spec/fixtures/config/redis_old_format_host.yml' } + let(:config_file_name) { config_old_format_host } it 'returns false' do is_expected.to be_falsey @@ -187,12 +177,12 @@ describe Gitlab::Redis do it 'returns default redis url when no config file is present' do expect(subject).to receive(:fetch_config) { false } - expect(subject.send(:raw_config_hash)).to eq(url: Gitlab::Redis::DEFAULT_REDIS_URL) + expect(subject.send(:raw_config_hash)).to eq(url: class_redis_url ) end it 'returns old-style single url config in a hash' do - expect(subject).to receive(:fetch_config) { 'redis://myredis:6379' } - expect(subject.send(:raw_config_hash)).to eq(url: 'redis://myredis:6379') + expect(subject).to receive(:fetch_config) { test_redis_url } + expect(subject.send(:raw_config_hash)).to eq(url: test_redis_url) end end @@ -200,7 +190,13 @@ describe Gitlab::Redis do it 'returns false when no config file is present' do allow(described_class).to receive(:_raw_config) { false } - expect(subject.send(:fetch_config)).to be_falsey + expect(subject.send(:fetch_config)).to eq false + end + + it 'returns false when config file is present but has invalid YAML' do + allow(described_class).to receive(:_raw_config) { "# development: true" } + + expect(subject.send(:fetch_config)).to eq false end end diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index 0cae5620920..0a194ca4c90 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -206,6 +206,7 @@ module TestEnv # Otherwise they'd be created by the first test, often timing out and # causing a transient test failure def eager_load_driver_server + return unless ENV['CI'] return unless defined?(Capybara) puts "Starting the Capybara driver server..." diff --git a/spec/support/unique_ip_check_shared_examples.rb b/spec/support/unique_ip_check_shared_examples.rb index 1986d202c4a..ff0b47899f5 100644 --- a/spec/support/unique_ip_check_shared_examples.rb +++ b/spec/support/unique_ip_check_shared_examples.rb @@ -1,7 +1,9 @@ shared_context 'unique ips sign in limit' do include StubENV before(:each) do - Gitlab::Redis.with(&:flushall) + Gitlab::Redis::Cache.with(&:flushall) + Gitlab::Redis::Queues.with(&:flushall) + Gitlab::Redis::SharedState.with(&:flushall) end before do diff --git a/spec/workers/schedule_update_user_activity_worker_spec.rb b/spec/workers/schedule_update_user_activity_worker_spec.rb index e583c3203aa..32c59381b01 100644 --- a/spec/workers/schedule_update_user_activity_worker_spec.rb +++ b/spec/workers/schedule_update_user_activity_worker_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe ScheduleUpdateUserActivityWorker, :redis do +describe ScheduleUpdateUserActivityWorker, :clean_gitlab_redis_shared_state do let(:now) { Time.now } before do diff --git a/spec/workers/update_user_activity_worker_spec.rb b/spec/workers/update_user_activity_worker_spec.rb index 43e9511f116..268ca1d81f2 100644 --- a/spec/workers/update_user_activity_worker_spec.rb +++ b/spec/workers/update_user_activity_worker_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe UpdateUserActivityWorker, :redis do +describe UpdateUserActivityWorker, :clean_gitlab_redis_shared_state do let(:user_active_2_days_ago) { create(:user, current_sign_in_at: 10.months.ago) } let(:user_active_yesterday_1) { create(:user) } let(:user_active_yesterday_2) { create(:user) } @@ -25,7 +25,7 @@ describe UpdateUserActivityWorker, :redis do end end - it 'deletes the pairs from Redis' do + it 'deletes the pairs from SharedState' do data.each { |id, time| Gitlab::UserActivities.record(id, time) } subject.perform(data) diff --git a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml b/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml index 5b6af7be8c4..eeefadaa019 100644 --- a/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/Docker.gitlab-ci.yml @@ -4,10 +4,21 @@ image: docker:latest services: - docker:dind +before_script: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + +build-master: + stage: build + script: + - docker build --pull -t "$CI_REGISTRY_IMAGE" . + - docker push "$CI_REGISTRY_IMAGE" + only: + - master + build: stage: build - before_script: - - docker login -u "$CI_REGISTRY_USER" -p "CI_REGISTRY_PASSWORD" $CI_REGISTRY script: - - docker build --pull -t "$CI_REGISTRY_IMAGE:CI_COMMIT_REF_SLUG" . - - docker push "$CI_REGISTRY_IMAGE:CI_COMMIT_REF_SLUG" + - docker build --pull -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" . + - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" + except: + - master diff --git a/vendor/gitlab-ci-yml/autodeploy/Kubernetes-with-canary.gitlab-ci.yml b/vendor/gitlab-ci-yml/autodeploy/Kubernetes-with-canary.gitlab-ci.yml index 555a51d35b9..06b0c84e516 100644 --- a/vendor/gitlab-ci-yml/autodeploy/Kubernetes-with-canary.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/autodeploy/Kubernetes-with-canary.gitlab-ci.yml @@ -28,7 +28,7 @@ canary: - command canary environment: name: production - url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG.$KUBE_DOMAIN when: manual only: - master @@ -39,7 +39,7 @@ production: - command deploy environment: name: production - url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG.$KUBE_DOMAIN when: manual only: - master @@ -50,7 +50,7 @@ staging: - command deploy environment: name: staging - url: http://$CI_PROJECT_NAME-staging.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG-staging.$KUBE_DOMAIN only: - master @@ -60,7 +60,7 @@ review: - command deploy environment: name: review/$CI_COMMIT_REF_NAME - url: http://$CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN on_stop: stop_review only: - branches diff --git a/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml b/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml index ee830ec2eb0..722934b7981 100644 --- a/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/autodeploy/Kubernetes.gitlab-ci.yml @@ -27,7 +27,7 @@ production: - command deploy environment: name: production - url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG.$KUBE_DOMAIN when: manual only: - master @@ -38,7 +38,7 @@ staging: - command deploy environment: name: staging - url: http://$CI_PROJECT_NAME-staging.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG-staging.$KUBE_DOMAIN only: - master @@ -48,7 +48,7 @@ review: - command deploy environment: name: review/$CI_COMMIT_REF_NAME - url: http://$CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN on_stop: stop_review only: - branches diff --git a/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml b/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml index 27c9107e0d7..acba718ebe4 100644 --- a/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml +++ b/vendor/gitlab-ci-yml/autodeploy/OpenShift.gitlab-ci.yml @@ -23,38 +23,32 @@ build: production: stage: production - variables: - CI_ENVIRONMENT_URL: http://$CI_PROJECT_NAME.$KUBE_DOMAIN script: - command deploy environment: name: production - url: http://$CI_PROJECT_NAME.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG.$KUBE_DOMAIN when: manual only: - master staging: stage: staging - variables: - CI_ENVIRONMENT_URL: http://$CI_PROJECT_NAME-staging.$KUBE_DOMAIN script: - command deploy environment: name: staging - url: http://$CI_PROJECT_NAME-staging.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG-staging.$KUBE_DOMAIN only: - master review: stage: review - variables: - CI_ENVIRONMENT_URL: http://$CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN script: - command deploy environment: name: review/$CI_COMMIT_REF_NAME - url: http://$CI_PROJECT_NAME-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN + url: http://$CI_PROJECT_PATH_SLUG-$CI_ENVIRONMENT_SLUG.$KUBE_DOMAIN on_stop: stop_review only: - branches diff --git a/vendor/licenses.csv b/vendor/licenses.csv index 5dcac5947a1..5beb3e5e9bf 100644 --- a/vendor/licenses.csv +++ b/vendor/licenses.csv @@ -1,9 +1,9 @@ RedCloth,4.3.2,MIT -abbrev,1.0.9,ISC +abbrev,1.1.0,ISC accepts,1.3.3,MIT ace-rails-ap,4.1.2,MIT -acorn,5.0.3,MIT -acorn-dynamic-import,2.0.1,MIT +acorn,5.1.1,MIT +acorn-dynamic-import,2.0.2,MIT acorn-jsx,3.0.1,MIT actionmailer,4.2.8,MIT actionpack,4.2.8,MIT @@ -16,7 +16,7 @@ acts-as-taggable-on,4.0.0,MIT addressable,2.3.8,Apache 2.0 after,0.8.2,MIT after_commit_queue,1.3.0,MIT -ajv,4.11.2,MIT +ajv,4.11.8,MIT ajv-keywords,1.5.1,MIT akismet,2.0.0,MIT align-text,0.1.4,MIT @@ -26,16 +26,17 @@ amdefine,1.0.1,BSD-3-Clause OR MIT ansi-escapes,1.4.0,MIT ansi-html,0.0.5,"Apache, Version 2.0" ansi-regex,2.1.1,MIT -ansi-styles,2.2.1,MIT +ansi-styles,3.1.0,MIT anymatch,1.3.0,ISC append-transform,0.4.0,MIT -aproba,1.1.0,ISC -are-we-there-yet,1.1.2,ISC +aproba,1.1.2,ISC +are-we-there-yet,1.1.4,ISC arel,6.0.4,MIT argparse,1.0.9,MIT arr-diff,2.0.0,MIT -arr-flatten,1.0.1,MIT +arr-flatten,1.1.0,MIT array-find,1.0.0,MIT +array-find-index,1.0.2,MIT array-flatten,1.1.1,MIT array-slice,0.2.3,MIT array-union,1.0.2,MIT @@ -63,26 +64,27 @@ aws-sign2,0.6.0,Apache 2.0 aws4,1.6.0,MIT axiom-types,0.1.1,MIT babel-code-frame,6.22.0,MIT -babel-core,6.23.1,MIT -babel-generator,6.23.0,MIT -babel-helper-bindify-decorators,6.22.0,MIT -babel-helper-builder-binary-assignment-operator-visitor,6.22.0,MIT -babel-helper-call-delegate,6.22.0,MIT -babel-helper-define-map,6.23.0,MIT -babel-helper-explode-assignable-expression,6.22.0,MIT -babel-helper-explode-class,6.22.0,MIT -babel-helper-function-name,6.23.0,MIT -babel-helper-get-function-arity,6.22.0,MIT -babel-helper-hoist-variables,6.22.0,MIT -babel-helper-optimise-call-expression,6.23.0,MIT -babel-helper-regex,6.22.0,MIT -babel-helper-remap-async-to-generator,6.22.0,MIT -babel-helper-replace-supers,6.23.0,MIT -babel-helpers,6.23.0,MIT -babel-loader,6.2.10,MIT +babel-core,6.25.0,MIT +babel-eslint,7.2.3,MIT +babel-generator,6.25.0,MIT +babel-helper-bindify-decorators,6.24.1,MIT +babel-helper-builder-binary-assignment-operator-visitor,6.24.1,MIT +babel-helper-call-delegate,6.24.1,MIT +babel-helper-define-map,6.24.1,MIT +babel-helper-explode-assignable-expression,6.24.1,MIT +babel-helper-explode-class,6.24.1,MIT +babel-helper-function-name,6.24.1,MIT +babel-helper-get-function-arity,6.24.1,MIT +babel-helper-hoist-variables,6.24.1,MIT +babel-helper-optimise-call-expression,6.24.1,MIT +babel-helper-regex,6.24.1,MIT +babel-helper-remap-async-to-generator,6.24.1,MIT +babel-helper-replace-supers,6.24.1,MIT +babel-helpers,6.24.1,MIT +babel-loader,6.4.1,MIT babel-messages,6.23.0,MIT babel-plugin-check-es2015-constants,6.22.0,MIT -babel-plugin-istanbul,4.0.0,New BSD +babel-plugin-istanbul,4.1.4,New BSD babel-plugin-syntax-async-functions,6.13.0,MIT babel-plugin-syntax-async-generators,6.13.0,MIT babel-plugin-syntax-class-properties,6.13.0,MIT @@ -91,57 +93,57 @@ babel-plugin-syntax-dynamic-import,6.18.0,MIT babel-plugin-syntax-exponentiation-operator,6.13.0,MIT babel-plugin-syntax-object-rest-spread,6.13.0,MIT babel-plugin-syntax-trailing-function-commas,6.22.0,MIT -babel-plugin-transform-async-generator-functions,6.22.0,MIT -babel-plugin-transform-async-to-generator,6.22.0,MIT -babel-plugin-transform-class-properties,6.23.0,MIT -babel-plugin-transform-decorators,6.22.0,MIT -babel-plugin-transform-define,1.2.0,MIT +babel-plugin-transform-async-generator-functions,6.24.1,MIT +babel-plugin-transform-async-to-generator,6.24.1,MIT +babel-plugin-transform-class-properties,6.24.1,MIT +babel-plugin-transform-decorators,6.24.1,MIT +babel-plugin-transform-define,1.3.0,MIT babel-plugin-transform-es2015-arrow-functions,6.22.0,MIT babel-plugin-transform-es2015-block-scoped-functions,6.22.0,MIT -babel-plugin-transform-es2015-block-scoping,6.23.0,MIT -babel-plugin-transform-es2015-classes,6.23.0,MIT -babel-plugin-transform-es2015-computed-properties,6.22.0,MIT +babel-plugin-transform-es2015-block-scoping,6.24.1,MIT +babel-plugin-transform-es2015-classes,6.24.1,MIT +babel-plugin-transform-es2015-computed-properties,6.24.1,MIT babel-plugin-transform-es2015-destructuring,6.23.0,MIT -babel-plugin-transform-es2015-duplicate-keys,6.22.0,MIT +babel-plugin-transform-es2015-duplicate-keys,6.24.1,MIT babel-plugin-transform-es2015-for-of,6.23.0,MIT -babel-plugin-transform-es2015-function-name,6.22.0,MIT +babel-plugin-transform-es2015-function-name,6.24.1,MIT babel-plugin-transform-es2015-literals,6.22.0,MIT -babel-plugin-transform-es2015-modules-amd,6.24.0,MIT -babel-plugin-transform-es2015-modules-commonjs,6.24.0,MIT -babel-plugin-transform-es2015-modules-systemjs,6.23.0,MIT -babel-plugin-transform-es2015-modules-umd,6.24.0,MIT -babel-plugin-transform-es2015-object-super,6.22.0,MIT -babel-plugin-transform-es2015-parameters,6.23.0,MIT -babel-plugin-transform-es2015-shorthand-properties,6.22.0,MIT +babel-plugin-transform-es2015-modules-amd,6.24.1,MIT +babel-plugin-transform-es2015-modules-commonjs,6.24.1,MIT +babel-plugin-transform-es2015-modules-systemjs,6.24.1,MIT +babel-plugin-transform-es2015-modules-umd,6.24.1,MIT +babel-plugin-transform-es2015-object-super,6.24.1,MIT +babel-plugin-transform-es2015-parameters,6.24.1,MIT +babel-plugin-transform-es2015-shorthand-properties,6.24.1,MIT babel-plugin-transform-es2015-spread,6.22.0,MIT -babel-plugin-transform-es2015-sticky-regex,6.22.0,MIT +babel-plugin-transform-es2015-sticky-regex,6.24.1,MIT babel-plugin-transform-es2015-template-literals,6.22.0,MIT babel-plugin-transform-es2015-typeof-symbol,6.23.0,MIT -babel-plugin-transform-es2015-unicode-regex,6.22.0,MIT -babel-plugin-transform-exponentiation-operator,6.22.0,MIT +babel-plugin-transform-es2015-unicode-regex,6.24.1,MIT +babel-plugin-transform-exponentiation-operator,6.24.1,MIT babel-plugin-transform-object-rest-spread,6.23.0,MIT -babel-plugin-transform-regenerator,6.22.0,MIT -babel-plugin-transform-strict-mode,6.22.0,MIT -babel-preset-es2015,6.24.0,MIT -babel-preset-es2016,6.22.0,MIT -babel-preset-es2017,6.22.0,MIT -babel-preset-latest,6.24.0,MIT -babel-preset-stage-2,6.22.0,MIT -babel-preset-stage-3,6.22.0,MIT -babel-register,6.23.0,MIT -babel-runtime,6.22.0,MIT -babel-template,6.23.0,MIT -babel-traverse,6.23.1,MIT -babel-types,6.23.0,MIT +babel-plugin-transform-regenerator,6.24.1,MIT +babel-plugin-transform-strict-mode,6.24.1,MIT +babel-preset-es2015,6.24.1,MIT +babel-preset-es2016,6.24.1,MIT +babel-preset-es2017,6.24.1,MIT +babel-preset-latest,6.24.1,MIT +babel-preset-stage-2,6.24.1,MIT +babel-preset-stage-3,6.24.1,MIT +babel-register,6.24.1,MIT +babel-runtime,6.23.0,MIT +babel-template,6.25.0,MIT +babel-traverse,6.25.0,MIT +babel-types,6.25.0,MIT babosa,1.0.2,MIT -babylon,6.15.0,MIT +babylon,6.17.4,MIT backo2,1.0.2,MIT -balanced-match,0.4.2,MIT +balanced-match,1.0.0,MIT base32,0.3.2,MIT base64-arraybuffer,0.1.5,MIT -base64-js,1.2.0,MIT +base64-js,1.2.1,MIT base64id,1.0.0,MIT -batch,0.5.3,MIT +batch,0.6.1,MIT bcrypt,3.1.11,MIT bcrypt-pbkdf,1.0.1,New BSD better-assert,1.0.2,MIT @@ -150,24 +152,28 @@ binary-extensions,1.8.0,MIT bindata,2.3.5,ruby blob,0.0.4,unknown block-stream,0.0.9,ISC -bluebird,3.4.7,MIT -bn.js,4.11.6,MIT +bluebird,3.5.0,MIT +bn.js,4.11.7,MIT body-parser,1.17.2,MIT +bonjour,3.5.0,MIT boom,2.10.1,New BSD -bootsnap,1.0.0,MIT +bootsnap,1.1.1,MIT bootstrap-sass,3.3.6,MIT -brace-expansion,1.1.6,MIT +bootstrap-sass,3.3.7,MIT +bootstrap_form,2.7.0,MIT +brace-expansion,1.1.8,MIT braces,1.8.5,MIT -brorand,1.0.7,MIT +brorand,1.1.0,MIT browser,2.2.0,MIT browserify-aes,1.0.6,MIT browserify-cipher,1.0.0,MIT browserify-des,1.0.0,MIT browserify-rsa,4.0.1,MIT -browserify-sign,4.0.0,ISC +browserify-sign,4.0.4,ISC browserify-zlib,0.1.4,MIT browserslist,1.7.7,MIT buffer,4.9.1,MIT +buffer-indexof,1.1.0,MIT buffer-shims,1.0.0,MIT buffer-xor,1.0.3,MIT builder,3.2.3,MIT @@ -178,29 +184,30 @@ caller-path,0.1.0,MIT callsite,1.0.0,unknown callsites,0.2.0,MIT camelcase,1.2.1,MIT +camelcase-keys,2.1.0,MIT caniuse-api,1.6.1,MIT -caniuse-db,1.0.30000649,CC-BY-4.0 -carrierwave,1.0.0,MIT -caseless,0.11.0,Apache 2.0 +caniuse-db,1.0.30000699,CC-BY-4.0 +carrierwave,1.1.0,MIT +caseless,0.12.0,Apache 2.0 cause,0.1,MIT center-align,0.1.3,MIT chalk,1.1.3,MIT charlock_holmes,0.7.3,MIT -chokidar,1.6.1,MIT +chokidar,1.7.0,MIT chronic,0.10.2,MIT chronic_duration,0.10.6,MIT chunky_png,1.3.5,MIT -cipher-base,1.0.3,MIT +cipher-base,1.0.4,MIT circular-json,0.3.1,MIT citrus,3.0.2,MIT -clap,1.1.3,MIT +clap,1.2.0,MIT cli-cursor,1.0.2,MIT cli-width,2.1.0,ISC -clipboard,1.6.1,MIT +clipboard,1.7.1,MIT cliui,2.1.0,ISC clone,1.0.2,MIT co,4.6.0,MIT -coa,1.0.1,MIT +coa,1.0.4,MIT code-point-at,1.1.0,MIT coercible,1.0.0,MIT coffee-rails,4.1.1,MIT @@ -214,13 +221,13 @@ colormin,1.1.2,MIT colors,1.1.2,MIT combine-lists,1.0.1,MIT combined-stream,1.0.5,MIT -commander,2.9.0,MIT +commander,2.11.0,MIT commondir,1.0.1,MIT component-bind,1.0.0,unknown component-emitter,1.2.1,MIT component-inherit,0.0.3,unknown -compressible,2.0.9,MIT -compression,1.6.2,MIT +compressible,2.0.10,MIT +compression,1.7.0,MIT compression-webpack-plugin,0.3.2,MIT concat-map,0.0.1,MIT concat-stream,1.6.0,MIT @@ -237,38 +244,40 @@ constants-browserify,1.0.0,MIT contains-path,0.1.0,MIT content-disposition,0.5.2,MIT content-type,1.0.2,MIT -convert-source-map,1.3.0,MIT +convert-source-map,1.5.0,MIT cookie,0.3.1,MIT cookie-signature,1.0.6,MIT core-js,2.4.1,MIT core-util-is,1.0.2,MIT -cosmiconfig,2.1.1,MIT +cosmiconfig,2.1.3,MIT crack,0.4.3,MIT create-ecdh,4.0.0,MIT -create-hash,1.1.2,MIT -create-hmac,1.1.4,MIT +create-hash,1.1.3,MIT +create-hmac,1.1.6,MIT creole,0.5.0,ruby cryptiles,2.0.5,New BSD crypto-browserify,3.11.0,MIT css-color-names,0.0.4,MIT -css-loader,0.28.0,MIT -css-selector-tokenizer,0.7.0,MIT -css_parser,1.4.1,MIT +css-loader,0.28.4,MIT +css-selector-tokenizer,"",unknown +css_parser,1.5.0,MIT cssesc,0.1.0,MIT cssnano,3.10.0,MIT csso,2.3.2,MIT +currently-unhandled,0.4.1,MIT custom-event,1.0.1,MIT -d,0.1.1,MIT -d3,3.5.11,New BSD +d,1.0.0,MIT +d3,3.5.17,New BSD d3_rails,3.5.11,MIT dashdash,1.14.1,MIT date-now,0.1.4,MIT de-indent,1.0.2,MIT -debug,2.6.0,MIT +debug,2.6.8,MIT debugger-ruby_core_source,1.3.8,MIT decamelize,1.2.0,MIT deckar01-task_list,2.0.0,MIT -deep-extend,0.4.1,MIT +deep-equal,1.0.1,MIT +deep-extend,0.4.2,MIT deep-is,0.1.3,MIT default-require-extensions,1.0.0,MIT default_value_for,3.0.2,MIT @@ -276,31 +285,35 @@ defaults,1.0.3,MIT defined,1.0.0,MIT del,2.2.2,MIT delayed-stream,1.0.0,MIT -delegate,3.1.2,MIT +delegate,3.1.3,MIT delegates,1.0.0,MIT depd,1.1.0,MIT des.js,1.0.0,MIT descendants_tracker,0.0.4,MIT destroy,1.0.4,MIT detect-indent,4.0.0,MIT +detect-node,2.0.3,ISC devise,4.2.0,MIT devise-two-factor,3.0.0,MIT di,0.0.1,MIT diff-lcs,1.2.5,"MIT,Perl Artistic v2,GNU GPL v2" diffie-hellman,5.0.2,MIT diffy,3.1.0,MIT -doctrine,1.5.0,BSD -document-register-element,1.3.0,MIT +dns-equal,1.0.0,MIT +dns-packet,1.1.1,MIT +dns-txt,2.0.2,MIT +doctrine,2.0.0,Apache 2.0 +document-register-element,1.5.0,MIT dom-serialize,2.2.1,MIT dom-serializer,0.1.0,MIT domain-browser,1.1.7,MIT domain_name,0.5.20161021,"Simplified BSD,New BSD,Mozilla Public License 2.0" domelementtype,1.3.0,unknown -domhandler,2.3.0,unknown -domutils,1.5.1,unknown +domhandler,2.4.1,Simplified BSD +domutils,1.6.2,Simplified BSD doorkeeper,4.2.0,MIT doorkeeper-openid_connect,1.1.2,MIT -dropzone,4.2.0,MIT +dropzone,4.3.0,MIT dropzonejs-rails,0.7.2,MIT duplexer,0.1.1,MIT duplexify,3.5.0,MIT @@ -308,8 +321,8 @@ ecc-jsbn,0.1.1,MIT editorconfig,0.13.2,MIT ee-first,1.1.1,MIT ejs,2.5.6,Apache 2.0 -electron-to-chromium,1.3.3,ISC -elliptic,6.3.3,MIT +electron-to-chromium,1.3.15,ISC +elliptic,6.4.0,MIT email_reply_trimmer,0.1.6,MIT emoji-unicode-version,0.2.1,MIT emojis-list,2.1.0,MIT @@ -319,44 +332,45 @@ end-of-stream,1.0.0,MIT engine.io,1.8.3,MIT engine.io-client,1.8.3,MIT engine.io-parser,1.3.2,MIT -enhanced-resolve,3.1.0,MIT +enhanced-resolve,3.3.0,MIT ent,2.2.0,MIT entities,1.1.1,BSD-like equalizer,0.0.11,MIT errno,0.1.4,MIT -error-ex,1.3.0,MIT +error-ex,1.3.1,MIT erubis,2.7.0,MIT -es5-ext,0.10.12,MIT -es6-iterator,2.0.0,MIT -es6-map,0.1.4,MIT +es5-ext,0.10.24,MIT +es6-iterator,2.0.1,MIT +es6-map,0.1.5,MIT es6-promise,3.0.2,MIT -es6-set,0.1.4,MIT -es6-symbol,3.1.0,MIT -es6-weak-map,2.0.1,MIT +es6-set,0.1.5,MIT +es6-symbol,3.1.1,MIT +es6-weak-map,2.0.2,MIT escape-html,1.0.3,MIT escape-string-regexp,1.0.5,MIT escape_utils,1.1.1,MIT escodegen,1.8.1,Simplified BSD escope,3.6.0,Simplified BSD -eslint,3.15.0,MIT +eslint,3.19.0,MIT eslint-config-airbnb-base,10.0.1,MIT -eslint-import-resolver-node,0.2.3,MIT -eslint-import-resolver-webpack,0.8.1,MIT -eslint-module-utils,2.0.0,MIT -eslint-plugin-filenames,1.1.0,MIT -eslint-plugin-html,2.0.1,ISC -eslint-plugin-import,2.2.0,MIT -eslint-plugin-jasmine,2.2.0,MIT +eslint-import-resolver-node,0.3.1,MIT +eslint-import-resolver-webpack,0.8.3,MIT +eslint-module-utils,2.1.1,MIT +eslint-plugin-filenames,1.2.0,MIT +eslint-plugin-html,2.0.3,ISC +eslint-plugin-import,2.7.0,MIT +eslint-plugin-jasmine,2.7.1,MIT eslint-plugin-promise,3.5.0,ISC -espree,3.4.0,Simplified BSD -esprima,3.1.3,Simplified BSD -esrecurse,4.1.0,Simplified BSD -estraverse,4.1.1,Simplified BSD +espree,3.4.3,Simplified BSD +esprima,2.7.3,Simplified BSD +esquery,1.0.0,BSD +esrecurse,4.2.0,Simplified BSD +estraverse,4.2.0,Simplified BSD esutils,2.0.2,BSD et-orbi,1.0.3,MIT etag,1.8.0,MIT eve-raphael,0.5.0,Apache 2.0 -event-emitter,0.3.4,MIT +event-emitter,0.3.5,MIT event-stream,3.3.4,MIT eventemitter3,1.2.0,MIT events,1.1.1,MIT @@ -371,13 +385,14 @@ expand-range,1.8.2,MIT exports-loader,0.6.4,MIT express,4.15.3,MIT expression_parser,0.9.0,MIT -extend,3.0.0,MIT +extend,3.0.1,MIT extglob,0.3.2,MIT extlib,0.9.16,MIT extsprintf,1.0.2,MIT -faraday,0.11.0,MIT +faraday,0.12.1,MIT faraday_middleware,0.11.0.1,MIT faraday_middleware-multi_json,0.0.6,MIT +fast-deep-equal,1.0.0,MIT fast-levenshtein,2.0.6,MIT fast_gettext,1.4.0,"MIT,ruby" fastparse,1.1.1,MIT @@ -385,15 +400,15 @@ faye-websocket,0.7.3,MIT ffi,1.9.10,BSD figures,1.7.0,MIT file-entry-cache,2.0.0,MIT -file-loader,0.11.1,MIT -filename-regex,2.0.0,MIT +file-loader,0.11.2,MIT +filename-regex,2.0.1,MIT fileset,2.0.3,MIT filesize,3.3.0,New BSD fill-range,2.2.3,MIT finalhandler,1.0.3,MIT find-cache-dir,0.1.1,MIT find-root,0.1.2,MIT -find-up,2.1.0,MIT +find-up,1.1.2,MIT flat-cache,1.2.2,MIT flatten,1.0.2,MIT flipper,0.10.2,MIT @@ -409,41 +424,43 @@ fog-openstack,0.1.6,MIT fog-rackspace,0.1.1,MIT fog-xml,0.1.3,MIT font-awesome-rails,4.7.0.1,"MIT,SIL Open Font License" -for-in,0.1.6,MIT -for-own,0.1.4,MIT +for-in,1.0.2,MIT +for-own,0.1.5,MIT forever-agent,0.6.1,Apache 2.0 -form-data,2.1.2,MIT +form-data,2.1.4,MIT formatador,0.2.5,MIT forwarded,0.1.0,MIT fresh,0.5.0,MIT from,0.1.7,MIT +fs-access,1.0.1,MIT fs.realpath,1.0.0,ISC -fsevents,,unknown -fstream,1.0.10,ISC +fsevents,1.1.2,MIT +fstream,1.0.11,ISC fstream-ignore,1.0.5,ISC function-bind,1.1.0,MIT -gauge,2.7.2,ISC +gauge,2.7.4,ISC gemnasium-gitlab-service,0.2.6,MIT gemojione,3.0.1,MIT generate-function,2.0.0,MIT generate-object-property,1.2.0,MIT get-caller-file,1.0.2,ISC +get-stdin,4.0.1,MIT get_process_mem,0.2.0,MIT -getpass,0.1.6,MIT +getpass,0.1.7,MIT gettext_i18n_rails,1.8.0,MIT gettext_i18n_rails_js,1.2.0,MIT -gitaly,0.8.0,MIT +gitaly,0.14.0,MIT github-linguist,4.7.6,MIT github-markup,1.4.0,MIT gitlab-flowdock-git-hook,1.0.1,MIT gitlab-grit,2.8.1,MIT gitlab-markup,1.5.1,MIT gitlab_omniauth-ldap,1.2.1,MIT -glob,7.1.1,ISC +glob,7.1.2,ISC glob-base,0.3.0,MIT glob-parent,2.0.0,ISC globalid,0.3.7,MIT -globals,9.14.0,MIT +globals,9.18.0,MIT globby,5.0.0,MIT gollum-grit_adapter,1.0.1,MIT gollum-lib,4.2.1,MIT @@ -455,32 +472,34 @@ google-protobuf,3.2.0.2,New BSD googleauth,0.5.1,Apache 2.0 got,3.3.1,MIT graceful-fs,4.1.11,ISC -graceful-readlink,1.0.1,MIT grape,0.19.1,MIT grape-entity,0.6.0,MIT -grpc,1.2.5,New BSD +grpc,1.4.0,New BSD gzip-size,3.0.0,MIT hamlit,2.6.1,MIT handle-thing,1.2.5,MIT -handlebars,4.0.6,MIT -har-validator,2.0.6,ISC +handlebars,4.0.10,MIT +har-schema,1.0.5,ISC +har-validator,4.2.1,ISC has,1.0.1,MIT has-ansi,2.0.0,MIT has-binary,0.1.7,MIT has-cors,1.1.0,MIT -has-flag,1.0.0,MIT +has-flag,2.0.0,MIT has-unicode,2.0.1,ISC +hash-base,2.0.2,MIT hash-sum,1.0.2,MIT -hash.js,1.0.3,MIT +hash.js,1.1.3,MIT hashie,3.5.5,MIT hashie-forbidden_attributes,0.1.1,MIT hawk,3.1.3,New BSD he,1.1.1,MIT health_check,2.6.0,MIT hipchat,1.5.2,MIT +hmac-drbg,1.0.1,MIT hoek,2.16.3,New BSD home-or-tmp,2.0.0,MIT -hosted-git-info,2.2.0,ISC +hosted-git-info,2.5.0,ISC hpack.js,2.1.6,MIT html-comment-regex,1.1.1,MIT html-entities,1.2.0,MIT @@ -503,12 +522,14 @@ https-browserify,0.0.1,MIT i18n,0.8.1,MIT ice_nine,0.11.2,MIT iconv-lite,0.4.15,MIT -icss-replace-symbols,1.0.2,ISC +icss-replace-symbols,1.1.0,ISC +icss-utils,2.1.0,ISC ieee754,1.1.8,New BSD -ignore,3.2.2,MIT +ignore,3.3.3,MIT ignore-by-default,1.0.1,ISC immediate,3.0.6,MIT imurmurhash,0.1.4,MIT +indent-string,2.1.0,MIT indexes-of,1.0.1,MIT indexof,0.0.1,unknown infinity-agent,2.0.3,MIT @@ -517,25 +538,28 @@ influxdb,0.2.3,MIT inherits,2.0.3,ISC ini,1.3.4,ISC inquirer,0.12.0,MIT -interpret,1.0.1,MIT +internal-ip,1.2.0,MIT +interpret,1.0.3,MIT invariant,2.2.2,New BSD invert-kv,1.0.0,MIT +ip,1.1.5,MIT ipaddr.js,1.3.0,MIT ipaddress,0.8.3,MIT is-absolute,0.2.6,MIT is-absolute-url,2.1.0,MIT is-arrayish,0.2.1,MIT is-binary-path,1.0.1,MIT -is-buffer,1.1.4,MIT +is-buffer,1.1.5,MIT is-builtin-module,1.0.0,MIT -is-dotfile,1.0.2,MIT +is-directory,0.3.1,MIT +is-dotfile,1.0.3,MIT is-equal-shallow,0.1.3,MIT is-extendable,0.1.1,MIT is-extglob,1.0.0,MIT is-finite,1.0.2,MIT is-fullwidth-code-point,1.0.0,MIT is-glob,2.0.1,MIT -is-my-json-valid,2.15.0,MIT +is-my-json-valid,2.16.0,MIT is-npm,1.0.0,MIT is-number,2.1.0,MIT is-path-cwd,1.0.0,MIT @@ -556,56 +580,58 @@ is-utf8,0.2.1,MIT is-windows,0.2.0,MIT isarray,1.0.0,MIT isbinaryfile,3.0.2,MIT -isexe,1.1.2,ISC +isexe,2.0.0,ISC isobject,2.1.0,MIT isstream,0.1.2,MIT istanbul,0.4.5,New BSD -istanbul-api,1.1.1,New BSD -istanbul-lib-coverage,1.0.1,New BSD -istanbul-lib-hook,1.0.0,New BSD -istanbul-lib-instrument,1.4.2,New BSD -istanbul-lib-report,1.0.0-alpha.3,New BSD -istanbul-lib-source-maps,1.1.0,New BSD -istanbul-reports,1.0.1,New BSD -jasmine-core,2.6.3,MIT +istanbul-api,1.1.10,New BSD +istanbul-lib-coverage,1.1.1,New BSD +istanbul-lib-hook,1.0.7,New BSD +istanbul-lib-instrument,1.7.3,New BSD +istanbul-lib-report,1.1.1,New BSD +istanbul-lib-source-maps,1.2.1,New BSD +istanbul-reports,1.1.1,New BSD +jasmine-core,2.6.4,MIT jasmine-jquery,2.1.1,MIT jed,1.1.1,MIT jira-ruby,1.1.2,MIT jodid25519,1.0.2,MIT -jquery,2.2.1,MIT +jquery,2.2.4,MIT jquery-atwho-rails,1.3.2,MIT jquery-rails,4.1.1,MIT -jquery-ujs,1.2.1,MIT +jquery-ujs,1.2.2,MIT js-base64,2.1.9,BSD -js-beautify,1.6.12,MIT -js-cookie,2.1.3,MIT -js-tokens,3.0.1,MIT -js-yaml,3.7.0,MIT -jsbn,0.1.0,BSD +js-beautify,1.6.14,MIT +js-cookie,2.1.4,MIT +js-tokens,3.0.2,MIT +js-yaml,"",unknown +jsbn,0.1.1,MIT jsesc,1.3.0,MIT json,1.8.6,ruby json-jwt,1.7.1,MIT json-loader,0.5.4,MIT json-schema,0.2.3,"AFLv2.1,BSD" +json-schema-traverse,0.3.1,MIT json-stable-stringify,1.0.1,MIT json-stringify-safe,5.0.1,ISC json3,3.3.2,MIT json5,0.5.1,MIT jsonify,0.0.0,Public Domain jsonpointer,4.0.1,MIT -jsprim,1.3.1,MIT +jsprim,1.4.0,MIT jszip,3.1.3,(MIT OR GPL-3.0) jszip-utils,0.0.2,MIT or GPLv3 jwt,1.5.6,MIT kaminari,0.17.0,MIT karma,1.7.0,MIT -karma-coverage-istanbul-reporter,0.2.0,MIT +karma-chrome-launcher,2.2.0,MIT +karma-coverage-istanbul-reporter,0.2.3,MIT karma-jasmine,1.1.0,MIT -karma-mocha-reporter,2.2.2,MIT +karma-mocha-reporter,2.2.3,MIT karma-sourcemap-loader,0.3.7,MIT -karma-webpack,2.0.2,MIT +karma-webpack,2.0.4,MIT kgio,2.10.0,LGPL-2.1+ -kind-of,3.1.0,MIT +kind-of,3.2.2,MIT kubeclient,2.2.0,MIT latest-version,1.0.1,MIT launchy,2.4.3,ISC @@ -617,7 +643,7 @@ lie,3.1.1,MIT little-plugger,1.1.4,MIT load-json-file,1.1.0,MIT loader-runner,2.3.0,MIT -loader-utils,0.2.16,MIT +loader-utils,"",unknown locale,2.1.2,"ruby,LGPLv3+" locate-path,2.0.0,MIT lodash,4.17.4,MIT @@ -631,65 +657,69 @@ lodash._isiterateecall,3.0.9,MIT lodash._topath,3.8.1,MIT lodash.assign,3.2.0,MIT lodash.camelcase,4.3.0,MIT -lodash.capitalize,4.2.1,MIT lodash.cond,4.5.2,MIT -lodash.deburr,4.1.0,MIT lodash.defaults,3.1.2,MIT -lodash.get,4.4.2,MIT +lodash.get,3.7.0,MIT lodash.isarguments,3.1.0,MIT lodash.isarray,3.0.4,MIT -lodash.kebabcase,4.0.1,MIT +lodash.kebabcase,4.1.1,MIT lodash.keys,3.1.2,MIT lodash.memoize,4.1.2,MIT lodash.restparam,3.6.1,MIT -lodash.snakecase,4.0.1,MIT +lodash.snakecase,4.1.1,MIT lodash.uniq,4.5.0,MIT -lodash.words,4.2.0,MIT +lodash.upperfirst,4.3.1,MIT log4js,0.6.38,Apache 2.0 logging,2.2.2,MIT longest,1.0.1,MIT loofah,2.0.3,MIT loose-envify,1.3.1,MIT +loud-rejection,1.6.0,MIT lowercase-keys,1.0.0,MIT lru-cache,3.2.0,ISC macaddress,0.2.8,MIT mail,2.6.5,MIT mail_room,0.9.1,MIT +map-obj,1.0.1,MIT map-stream,0.1.0,unknown marked,0.3.6,MIT -math-expression-evaluator,1.2.16,MIT +math-expression-evaluator,1.2.17,MIT media-typer,0.3.0,MIT memoist,0.15.0,MIT memory-fs,0.4.1,MIT +meow,3.7.0,MIT merge-descriptors,1.0.1,MIT method_source,0.8.2,MIT methods,1.1.2,MIT micromatch,2.3.11,MIT miller-rabin,4.0.0,MIT -mime,1.3.4,MIT +mime,1.3.6,MIT mime-db,1.27.0,MIT +mime-types,2.1.15,MIT mime-types,2.99.3,"MIT,Artistic-2.0,GPL-2.0" mimemagic,0.3.0,MIT mini_portile2,2.1.0,MIT minimalistic-assert,1.0.0,ISC -minimatch,3.0.3,ISC +minimalistic-crypto-utils,1.0.1,MIT +minimatch,3.0.4,ISC minimist,0.0.8,MIT mkdirp,0.5.1,MIT -mmap2,2.2.6,ruby -moment,2.17.1,MIT -mousetrap,1.4.6,Apache 2.0 +mmap2,2.2.7,ruby +moment,2.18.1,MIT +mousetrap,1.6.1,Apache 2.0 mousetrap-rails,1.4.6,"MIT,Apache" -ms,0.7.2,MIT +ms,2.0.0,MIT msgpack,1.1.0,Apache 2.0 multi_json,1.12.1,MIT multi_xml,0.6.0,MIT +multicast-dns,6.1.1,MIT +multicast-dns-service-types,1.1.0,MIT multipart-post,2.0.0,MIT mustermann,0.4.0,MIT mustermann-grape,0.4.0,MIT mute-stream,0.0.5,ISC -mysql2,0.3.20,MIT name-all-modules-plugin,1.0.1,MIT -nan,2.5.1,MIT +nan,2.6.2,MIT natural-compare,1.4.0,MIT negotiator,0.6.1,MIT nested-error-stacks,1.0.2,MIT @@ -697,23 +727,25 @@ net-ldap,0.12.1,MIT net-ssh,3.0.1,MIT netrc,0.11.0,MIT node-ensure,0.0.0,MIT +node-forge,0.6.33,BSD node-libs-browser,2.0.0,MIT -node-pre-gyp,0.6.33,New BSD +node-pre-gyp,0.6.36,New BSD node-zopfli,2.0.2,MIT nodemon,1.11.0,MIT nokogiri,1.6.8.1,MIT -nopt,3.0.6,ISC -normalize-package-data,2.3.5,Simplified BSD -normalize-path,2.0.1,MIT +nopt,4.0.1,ISC +normalize-package-data,2.4.0,Simplified BSD +normalize-path,2.1.1,MIT normalize-range,0.1.2,MIT normalize-url,1.9.1,MIT -npmlog,4.0.2,ISC +npmlog,4.1.2,ISC +null-check,1.0.0,MIT num2fraction,1.2.2,MIT number-is-nan,1.0.1,MIT numerizer,0.1.1,MIT oauth,0.5.1,MIT oauth-sign,0.8.2,Apache 2.0 -oauth2,1.3.1,MIT +oauth2,1.4.0,MIT object-assign,4.1.1,MIT object-component,0.0.3,unknown object.omit,2.0.1,MIT @@ -740,7 +772,7 @@ omniauth-twitter,1.2.1,MIT omniauth_crowd,2.2.3,MIT on-finished,2.3.0,MIT on-headers,1.0.1,MIT -once,1.3.3,ISC +once,1.4.0,ISC onetime,1.1.0,MIT opener,1.4.3,(WTFPL OR MIT) opn,4.0.2,MIT @@ -758,10 +790,11 @@ os-tmpdir,1.0.2,MIT osenv,0.1.4,ISC p-limit,1.1.0,MIT p-locate,2.0.0,MIT +p-map,1.1.1,MIT package-json,1.2.0,MIT pako,1.0.5,(MIT AND Zlib) -paranoia,2.2.0,MIT -parse-asn1,5.0.0,ISC +paranoia,2.3.1,MIT +parse-asn1,5.1.0,ISC parse-glob,3.0.4,MIT parse-json,2.2.0,MIT parsejson,0.0.3,MIT @@ -769,36 +802,35 @@ parseqs,0.0.5,MIT parseuri,0.0.5,MIT parseurl,1.3.1,MIT path-browserify,0.0.0,MIT -path-exists,3.0.0,MIT +path-exists,2.1.0,MIT path-is-absolute,1.0.1,MIT path-is-inside,1.0.2,(WTFPL OR MIT) path-parse,1.0.5,MIT path-to-regexp,0.1.7,MIT path-type,1.1.0,MIT pause-stream,0.0.11,"MIT,Apache2" -pbkdf2,3.0.9,MIT -pdfjs-dist,1.8.252,Apache 2.0 +pbkdf2,3.0.12,MIT +pdfjs-dist,1.8.527,Apache 2.0 peek,1.0.1,MIT peek-gc,0.0.2,MIT peek-host,1.0.0,MIT -peek-mysql2,1.1.0,MIT peek-performance_bar,1.2.1,MIT peek-pg,1.3.0,MIT peek-rblineprof,0.2.0,MIT peek-redis,1.2.0,MIT peek-sidekiq,1.0.3,MIT +performance-now,0.2.0,MIT pg,0.18.4,"BSD,ruby,GPL" pify,2.3.0,MIT -pikaday,1.5.1,"BSD,MIT" +pikaday,1.6.1,(0BSD OR MIT) pinkie,2.0.4,MIT pinkie-promise,2.0.1,MIT pkg-dir,1.0.0,MIT -pkg-up,1.0.0,MIT pluralize,1.2.1,MIT po_to_json,1.0.1,MIT portfinder,1.0.13,MIT posix-spawn,0.3.11,"MIT,LGPL" -postcss,5.2.16,MIT +postcss,5.2.17,MIT postcss-calc,5.3.1,MIT postcss-colormin,2.2.2,MIT postcss-convert-values,2.6.1,MIT @@ -819,10 +851,10 @@ postcss-minify-font-values,1.0.5,MIT postcss-minify-gradients,1.0.5,MIT postcss-minify-params,1.2.2,MIT postcss-minify-selectors,2.1.1,MIT -postcss-modules-extract-imports,1.0.1,ISC -postcss-modules-local-by-default,1.1.1,MIT -postcss-modules-scope,1.0.2,ISC -postcss-modules-values,1.2.2,ISC +postcss-modules-extract-imports,1.1.0,ISC +postcss-modules-local-by-default,1.2.0,MIT +postcss-modules-scope,1.1.0,ISC +postcss-modules-values,1.3.0,ISC postcss-normalize-charset,1.1.1,MIT postcss-normalize-url,3.0.8,MIT postcss-ordered-values,2.2.3,MIT @@ -835,16 +867,16 @@ postcss-unique-selectors,2.0.2,MIT postcss-value-parser,3.3.0,MIT postcss-zindex,2.2.0,MIT prelude-ls,1.1.2,MIT -premailer,1.8.6,New BSD -premailer-rails,1.9.2,MIT +premailer,1.10.4,New BSD +premailer-rails,1.9.7,MIT prepend-http,1.0.4,MIT preserve,0.2.0,MIT prismjs,1.6.0,MIT private,0.1.7,MIT -process,0.11.9,MIT +process,0.11.10,MIT process-nextick-args,1.0.7,MIT progress,1.1.8,MIT -prometheus-client-mmap,0.7.0.beta5,Apache 2.0 +prometheus-client-mmap,0.7.0.beta8,Apache 2.0 proto-list,1.2.4,ISC proxy-addr,1.1.4,MIT prr,0.0.0,MIT @@ -855,8 +887,8 @@ punycode,1.4.1,MIT pyu-ruby-sasl,0.0.3.3,MIT q,1.5.0,MIT qjobs,1.1.5,MIT -qs,6.3.0,New BSD -query-string,4.3.2,MIT +qs,6.4.0,New BSD +query-string,4.3.4,MIT querystring,0.2.0,MIT querystring-es3,0.2.1,MIT querystringify,0.0.4,MIT @@ -872,24 +904,25 @@ rails,4.2.8,MIT rails-deprecated_sanitizer,1.0.3,MIT rails-dom-testing,1.0.8,MIT rails-html-sanitizer,1.0.3,MIT +rails-i18n,4.0.9,MIT railties,4.2.8,MIT -rainbow,2.1.0,MIT -raindrops,0.17.0,LGPL-2.1+ +rainbow,2.2.2,MIT +raindrops,0.18.0,LGPL-2.1+ rake,10.5.0,MIT -randomatic,1.1.6,MIT -randombytes,2.0.3,MIT +randomatic,1.1.7,MIT +randombytes,2.0.5,MIT range-parser,1.2.0,MIT raphael,2.2.7,MIT -raven-js,3.14.0,Simplified BSD +raven-js,3.16.1,Simplified BSD raw-body,2.2.0,MIT raw-loader,0.5.1,MIT -rc,1.1.6,(BSD-2-Clause OR MIT OR Apache-2.0) +rc,1.2.1,(BSD-2-Clause OR MIT OR Apache-2.0) rdoc,4.2.2,ruby react-dev-utils,0.5.2,New BSD read-all-stream,3.1.0,MIT read-pkg,1.1.0,MIT read-pkg-up,1.0.1,MIT -readable-stream,2.2.2,MIT +readable-stream,2.3.3,MIT readdirp,2.1.0,MIT readline2,1.0.1,MIT recaptcha,3.0.0,MIT @@ -897,6 +930,7 @@ rechoir,0.6.2,MIT recursive-open-struct,1.0.0,MIT recursive-readdir,2.1.1,MIT redcarpet,3.4.0,MIT +redent,1.0.0,MIT redis,3.3.3,MIT redis-actionpack,5.0.1,MIT redis-activesupport,5.0.1,MIT @@ -907,33 +941,34 @@ redis-store,1.2.0,MIT reduce-css-calc,1.3.0,MIT reduce-function-call,1.0.2,MIT regenerate,1.3.2,MIT -regenerator-runtime,0.10.1,MIT -regenerator-transform,0.9.8,BSD +regenerator-runtime,0.10.5,MIT +regenerator-transform,0.9.11,BSD regex-cache,0.4.3,MIT -regexpu-core,2.0.0,MIT +regexpu-core,"",unknown registry-url,3.1.0,MIT regjsgen,0.2.0,MIT regjsparser,0.1.5,BSD +remove-trailing-separator,1.0.2,ISC repeat-element,1.1.2,MIT repeat-string,1.6.1,MIT repeating,2.0.1,MIT -request,2.79.0,Apache 2.0 +request,2.81.0,Apache 2.0 request_store,1.3.1,MIT require-directory,2.1.1,MIT require-from-string,1.2.1,MIT require-main-filename,1.0.1,ISC require-uncached,1.0.3,MIT requires-port,1.0.0,MIT -resolve,1.2.0,MIT +resolve,1.3.3,MIT resolve-from,1.0.1,MIT responders,2.3.0,MIT rest-client,2.0.0,MIT restore-cursor,1.0.1,MIT retriable,1.4.1,MIT right-align,0.1.3,MIT -rimraf,2.5.4,ISC +rimraf,2.6.1,ISC rinku,2.0.0,ISC -ripemd160,1.0.1,New BSD +ripemd160,2.0.1,MIT rotp,2.1.2,MIT rouge,2.1.0,MIT rqrcode,0.7.0,MIT @@ -941,40 +976,42 @@ rqrcode-rails3,0.1.7,MIT ruby-fogbugz,0.2.1,MIT ruby-prof,0.16.2,Simplified BSD ruby-saml,1.4.1,MIT -ruby_parser,3.8.4,MIT +ruby_parser,3.9.0,MIT rubyntlm,0.5.2,MIT rubypants,0.2.0,BSD rufus-scheduler,3.4.0,MIT rugged,0.25.1.1,MIT run-async,0.1.0,MIT rx-lite,3.1.2,Apache 2.0 -safe-buffer,5.0.1,MIT +safe-buffer,5.1.1,MIT safe_yaml,1.0.4,MIT sanitize,2.1.0,MIT sass,3.4.22,MIT sass-rails,5.0.6,MIT sawyer,0.8.1,MIT -sax,1.2.2,ISC +sax,1.2.4,ISC +schema-utils,0.3.0,MIT securecompare,1.0.0,MIT seed-fu,2.3.6,MIT select,1.1.2,MIT select-hose,2.0.0,MIT select2,3.5.2-browserify,unknown select2-rails,3.5.9.3,MIT +selfsigned,1.9.1,MIT semver,5.3.0,ISC semver-diff,2.1.0,MIT send,0.15.3,MIT -sentry-raven,2.4.0,Apache 2.0 -serve-index,1.8.0,MIT +sentry-raven,2.5.3,Apache 2.0 +serve-index,1.9.0,MIT serve-static,1.12.3,MIT set-blocking,2.0.0,ISC set-immediate-shim,1.0.1,MIT setimmediate,1.0.5,MIT setprototypeof,1.0.3,ISC settingslogic,2.0.9,MIT -sexp_processor,4.8.0,MIT +sexp_processor,4.9.0,MIT sha.js,2.4.8,MIT -shelljs,0.7.6,New BSD +shelljs,0.7.8,New BSD sidekiq,5.0.0,LGPL sidekiq-cron,0.6.0,MIT sidekiq-limit_fetch,3.4.0,MIT @@ -995,18 +1032,18 @@ sockjs-client,1.0.1,MIT sort-keys,1.1.2,MIT source-list-map,0.1.8,MIT source-map,0.5.6,New BSD -source-map-support,0.4.11,MIT +source-map-support,0.4.15,MIT spdx-correct,1.0.2,Apache 2.0 spdx-expression-parse,1.0.4,(MIT AND CC-BY-3.0) spdx-license-ids,1.2.2,Unlicense -spdy,3.4.4,MIT -spdy-transport,2.0.18,MIT +spdy,3.4.7,MIT +spdy-transport,2.0.20,MIT split,0.3.3,MIT sprintf-js,1.0.3,New BSD sprockets,3.7.1,MIT sprockets-rails,3.2.0,MIT sql.js,0.4.0,MIT -sshpk,1.10.2,MIT +sshpk,1.13.1,MIT state_machines,0.4.0,MIT state_machines-activemodel,0.4.0,MIT state_machines-activerecord,0.4.0,MIT @@ -1014,7 +1051,7 @@ stats-webpack-plugin,0.4.3,MIT statuses,1.3.1,MIT stream-browserify,2.0.1,MIT stream-combiner,0.0.4,MIT -stream-http,2.6.3,MIT +stream-http,2.7.2,MIT stream-shift,1.0.0,MIT strict-uri-encode,1.1.0,MIT string-length,1.0.1,MIT @@ -1024,44 +1061,47 @@ stringex,2.5.2,MIT stringstream,0.0.5,MIT strip-ansi,3.0.1,MIT strip-bom,2.0.0,MIT -strip-json-comments,1.0.4,MIT -supports-color,0.2.0,MIT +strip-indent,1.0.1,MIT +strip-json-comments,2.0.1,MIT +supports-color,4.2.0,MIT svgo,0.7.2,MIT sys-filesystem,1.1.6,Artistic 2.0 table,3.8.3,New BSD tapable,0.2.6,MIT tar,2.2.1,ISC -tar-pack,3.3.0,Simplified BSD +tar-pack,3.4.0,Simplified BSD temple,0.7.7,MIT -test-exclude,4.0.0,ISC +test-exclude,4.1.1,ISC text,1.3.1,MIT text-table,0.2.0,MIT thor,0.19.4,MIT thread_safe,0.3.6,Apache 2.0 three,0.84.0,MIT three-orbit-controls,82.1.0,MIT -three-stl-loader,1.0.4,MIT +three-stl-loader,1.0.5,MIT through,2.3.8,MIT +thunky,0.1.0,unknown tilt,2.0.6,MIT timeago.js,2.0.5,MIT timed-out,2.0.0,MIT timers-browserify,2.0.2,MIT timfel-krb5-auth,0.8.3,LGPL -tiny-emitter,1.1.0,MIT +tiny-emitter,2.0.1,MIT tmp,0.0.31,MIT to-array,0.1.4,MIT to-arraybuffer,1.0.1,MIT -to-fast-properties,1.0.2,MIT +to-fast-properties,1.0.3,MIT toml-rb,0.3.15,MIT tool,0.2.3,MIT touch,1.0.0,ISC tough-cookie,2.3.2,New BSD traverse,0.6.6,MIT +trim-newlines,1.0.0,MIT trim-right,1.0.1,MIT truncato,0.7.8,MIT tryit,1.0.3,MIT tty-browserify,0.0.0,MIT -tunnel-agent,0.4.3,Apache 2.0 +tunnel-agent,0.6.0,Apache 2.0 tweetnacl,0.14.5,Unlicense type-check,0.3.2,MIT type-is,1.6.15,MIT @@ -1069,7 +1109,7 @@ typedarray,0.0.6,MIT tzinfo,1.2.2,MIT u2f,0.2.1,MIT uglifier,2.7.2,MIT -uglify-js,2.8.27,Simplified BSD +uglify-js,2.8.29,Simplified BSD uglify-to-browserify,1.0.2,MIT uid-number,0.0.6,ISC ultron,1.1.0,MIT @@ -1087,15 +1127,15 @@ uniqs,2.0.0,MIT unpipe,1.0.0,MIT update-notifier,0.5.0,Simplified BSD url,0.11.0,MIT -url-loader,0.5.8,MIT +url-loader,0.5.9,MIT url-parse,1.0.5,MIT url_safe_base64,0.2.2,MIT user-home,2.0.0,MIT -useragent,2.1.13,MIT +useragent,2.2.0,MIT util,0.10.3,MIT util-deprecate,1.0.2,MIT utils-merge,1.0.0,MIT -uuid,3.0.1,MIT +uuid,3.1.0,MIT validate-npm-package-license,3.0.1,Apache 2.0 validates_hostname,1.0.6,MIT vary,1.1.1,MIT @@ -1107,36 +1147,36 @@ visibilityjs,1.2.4,MIT vm-browserify,0.0.4,MIT vmstat,2.3.0,MIT void-elements,2.0.1,MIT -vue,2.2.6,MIT -vue-hot-reload-api,2.0.11,MIT +vue,2.3.4,MIT +vue-hot-reload-api,2.1.0,MIT vue-loader,11.3.4,MIT vue-resource,0.9.3,MIT vue-style-loader,2.0.5,MIT -vue-template-compiler,2.2.6,MIT -vue-template-es2015-compiler,1.5.1,MIT +vue-template-compiler,2.3.4,MIT +vue-template-es2015-compiler,1.5.3,MIT warden,1.2.6,MIT watchpack,1.3.1,MIT wbuf,1.7.2,MIT webpack,2.6.1,MIT webpack-bundle-analyzer,2.8.2,MIT -webpack-dev-middleware,1.10.0,MIT -webpack-dev-server,2.4.2,MIT +webpack-dev-middleware,1.11.0,MIT +webpack-dev-server,2.5.1,MIT webpack-rails,0.9.10,MIT -webpack-sources,0.1.4,MIT +webpack-sources,0.1.5,MIT websocket-driver,0.6.5,MIT websocket-extensions,0.1.1,MIT whet.extend,0.9.9,MIT -which,1.2.12,ISC +which,1.2.14,ISC which-module,1.0.0,ISC -wide-align,1.1.0,ISC +wide-align,1.1.2,ISC wikicloth,0.8.1,MIT window-size,0.1.0,MIT wordwrap,0.0.2,MIT/X11 -worker-loader,0.8.0,MIT +worker-loader,0.8.1,MIT wrap-ansi,2.1.0,MIT wrappy,1.0.2,ISC write,0.2.1,MIT -write-file-atomic,1.3.1,ISC +write-file-atomic,1.3.4,ISC ws,2.3.1,MIT wtf-8,1.0.0,MIT xdg-basedir,2.0.0,MIT |