Commit 2711c26b authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖

Add latest changes from gitlab-org/[email protected]

parent 8a7aaf86
Pipeline #129032465 failed with stages
in 99 minutes and 58 seconds
......@@ -45,6 +45,7 @@ logs, and code as it's tough to read otherwise.)
<details>
<summary>Expand for output related to GitLab environment info</summary>
<pre>
(For installations with omnibus-gitlab package run and paste the output of:
......
......@@ -156,7 +156,7 @@ export default {
<gl-loading-icon
v-if="isLoading"
:label="s__('Pipelines|Loading Pipelines')"
:size="3"
size="lg"
class="prepend-top-20"
/>
......
......@@ -46,8 +46,8 @@ const requestLogsUntilData = state => {
if (state.timeRange.current) {
try {
const { start, end } = convertToFixedRange(state.timeRange.current);
params.start = start;
params.end = end;
params.start_time = start;
params.end_time = end;
} catch {
flashTimeRangeWarning();
}
......
......@@ -86,8 +86,8 @@ export const fetchDashboard = ({ state, commit, dispatch }) => {
if (state.timeRange) {
const { start, end } = convertToFixedRange(state.timeRange);
params.start = start;
params.end = end;
params.start_time = start;
params.end_time = end;
}
if (state.currentDashboard) {
......@@ -139,16 +139,16 @@ function fetchPrometheusResult(prometheusEndpoint, params) {
* @param {metric} metric
*/
export const fetchPrometheusMetric = ({ commit }, { metric, params }) => {
const { start, end } = params;
const timeDiff = (new Date(end) - new Date(start)) / 1000;
const { start_time, end_time } = params;
const timeDiff = (new Date(end_time) - new Date(start_time)) / 1000;
const minStep = 60;
const queryDataPoints = 600;
const step = Math.max(minStep, Math.ceil(timeDiff / queryDataPoints));
const queryParams = {
start,
end,
start_time,
end_time,
step,
};
......
......@@ -48,7 +48,7 @@ module Projects
end
def elasticsearch_params
params.permit(:container_name, :pod_name, :search, :start, :end, :cursor)
params.permit(:container_name, :pod_name, :search, :start_time, :end_time, :cursor)
end
def environment
......
......@@ -257,7 +257,7 @@ class ApplicationSetting < ApplicationRecord
validates :snippet_size_limit, numericality: { only_integer: true, greater_than: 0 }
validate :email_restrictions_regex_valid?
validates :email_restrictions, untrusted_regexp: true
SUPPORTED_KEY_TYPES.each do |type|
validates :"#{type}_key_restriction", presence: true, key_restriction: { type: type }
......@@ -411,14 +411,6 @@ class ApplicationSetting < ApplicationRecord
recaptcha_enabled || login_recaptcha_protection_enabled
end
def email_restrictions_regex_valid?
return if email_restrictions.blank?
Gitlab::UntrustedRegexp.new(email_restrictions)
rescue RegexpError
errors.add(:email_restrictions, _('is not a valid regular expression'))
end
private
def parsed_grafana_url
......
......@@ -16,7 +16,7 @@ module PodLogs
private
def valid_params
super + %w(search start end cursor)
super + %w(search start_time end_time cursor)
end
def success_return_keys
......@@ -24,8 +24,8 @@ module PodLogs
end
def check_times(result)
result[:start] = params['start'] if params.key?('start') && Time.iso8601(params['start'])
result[:end] = params['end'] if params.key?('end') && Time.iso8601(params['end'])
result[:start_time] = params['start_time'] if params.key?('start_time') && Time.iso8601(params['start_time'])
result[:end_time] = params['end_time'] if params.key?('end_time') && Time.iso8601(params['end_time'])
success(result)
rescue ArgumentError
......@@ -53,8 +53,8 @@ module PodLogs
pod_name: result[:pod_name],
container_name: result[:container_name],
search: result[:search],
start_time: result[:start],
end_time: result[:end],
start_time: result[:start_time],
end_time: result[:end_time],
cursor: result[:cursor]
)
......
......@@ -114,11 +114,23 @@ module Prometheus
end
def filter_params(params, path)
params = substitute_params(params)
params.slice(*PROXY_SUPPORT.dig(path, :params))
end
def can_proxy?
PROXY_SUPPORT.dig(@path, :method)&.include?(@method)
end
def substitute_params(params)
start_time = params[:start_time]
end_time = params[:end_time]
params['start'] = start_time if start_time
params['end'] = end_time if end_time
params
end
end
end
......@@ -6,6 +6,7 @@ module Prometheus
steps :validate_variables,
:add_params_to_result,
:substitute_params,
:substitute_ruby_variables,
:substitute_liquid_variables
......@@ -35,6 +36,16 @@ module Prometheus
success(result)
end
def substitute_params(result)
start_time = result[:params][:start_time]
end_time = result[:params][:end_time]
result[:params][:start] = start_time if start_time
result[:params][:end] = end_time if end_time
success(result)
end
def substitute_liquid_variables(result)
return success(result) unless query(result)
......
# frozen_string_literal: true
class UntrustedRegexpValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return unless value
Gitlab::UntrustedRegexp.new(value)
rescue RegexpError => e
record.errors.add(attribute, "not valid RE2 syntax: #{e.message}")
end
end
---
title: Fix bug issue template handling of markdown
merge_request: 27808
author: Lee Tickett
type: fixed
......@@ -196,7 +196,7 @@ the tracking database on port 5432.
GEO_DB_PORT="5432"
query_exec () {
gitlab-psql -h $GEO_DB_HOST -d $GEO_DB_NAME -p $GEO_DB_PORT -c "${1}"
gitlab-psql -h $GEO_DB_HOST -U $GEO_DB_USER -d $GEO_DB_NAME -p $GEO_DB_PORT -c "${1}"
}
query_exec "CREATE EXTENSION postgres_fdw;"
......
......@@ -162,6 +162,9 @@ to customize their Value Stream Analytics.
GitLab allows users to hide default stages and create custom stages that align better to their
development workflow.
NOTE: **Note:**
Customizability is [only available for group-level](https://gitlab.com/gitlab-org/gitlab/-/issues/35823#note_272558950) Value Stream Analytics.
### Adding a stage
In the following example we're creating a new stage that measures and tracks issues from creation
......
......@@ -18,11 +18,11 @@ module Gitlab
timeframe_end = (deployment.created_at + 30.minutes).to_f
{
memory_values: client_query_range(memory_query, start: timeframe_start, stop: timeframe_end),
memory_values: client_query_range(memory_query, start_time: timeframe_start, end_time: timeframe_end),
memory_before: client_query(memory_avg_query, time: deployment.created_at.to_f),
memory_after: client_query(memory_avg_query, time: timeframe_end),
cpu_values: client_query_range(cpu_query, start: timeframe_start, stop: timeframe_end),
cpu_values: client_query_range(cpu_query, start_time: timeframe_start, end_time: timeframe_end),
cpu_before: client_query(cpu_avg_query, time: deployment.created_at.to_f),
cpu_after: client_query(cpu_avg_query, time: timeframe_end)
}
......
......@@ -15,9 +15,9 @@ module Gitlab
cpu_query = raw_cpu_usage_query(environment_slug)
{
memory_values: client_query_range(memory_query, start: timeframe_start, stop: timeframe_end),
memory_values: client_query_range(memory_query, start_time: timeframe_start, end_time: timeframe_end),
memory_current: client_query(memory_query, time: timeframe_end),
cpu_values: client_query_range(cpu_query, start: timeframe_start, stop: timeframe_end),
cpu_values: client_query_range(cpu_query, start_time: timeframe_start, end_time: timeframe_end),
cpu_current: client_query(cpu_query, time: timeframe_end)
}
end
......
......@@ -29,7 +29,7 @@ module Gitlab
def run_query(query, context)
query %= context
client_query_range(query, start: 8.hours.ago.to_f, stop: Time.now.to_f)
client_query_range(query, start_time: 8.hours.ago.to_f, end_time: Time.now.to_f)
end
def self.transform_reactive_result(result)
......
......@@ -43,7 +43,7 @@ module Gitlab
series = metric_groups.flat_map(&:metrics).flat_map(&:required_metrics).uniq
lookup = series.each_slice(MAX_QUERY_ITEMS).flat_map do |batched_series|
client_series(*batched_series, start: timeframe_start, stop: timeframe_end)
client_series(*batched_series, start_time: timeframe_start, end_time: timeframe_end)
.select(&method(:has_matching_label?))
.map { |series_info| [series_info['__name__'], true] }
end
......
......@@ -59,7 +59,7 @@ module Gitlab
result =
if query.key?(:query_range)
query[:query_range] %= context
client_query_range(query[:query_range], start: context[:timeframe_start], stop: context[:timeframe_end])
client_query_range(query[:query_range], start_time: context[:timeframe_start], end_time: context[:timeframe_end])
else
query[:query] %= context
client_query(query[:query], time: context[:timeframe_end])
......
......@@ -47,17 +47,17 @@ module Gitlab
end
end
def query_range(query, start: 8.hours.ago, stop: Time.now)
start = start.to_f
stop = stop.to_f
step = self.class.compute_step(start, stop)
def query_range(query, start_time: 8.hours.ago, end_time: Time.now)
start_time = start_time.to_f
end_time = end_time.to_f
step = self.class.compute_step(start_time, end_time)
get_result('matrix') do
json_api_get(
'query_range',
query: query,
start: start,
end: stop,
start: start_time,
end: end_time,
step: step
)
end
......@@ -67,12 +67,12 @@ module Gitlab
json_api_get("label/#{name}/values")
end
def series(*matches, start: 8.hours.ago, stop: Time.now)
json_api_get('series', 'match': matches, start: start.to_f, end: stop.to_f)
def series(*matches, start_time: 8.hours.ago, end_time: Time.now)
json_api_get('series', 'match': matches, start: start_time.to_f, end: end_time.to_f)
end
def self.compute_step(start, stop)
diff = stop - start
def self.compute_step(start_time, end_time)
diff = end_time - start_time
step = (diff / QUERY_RANGE_DATA_POINTS).ceil
......
......@@ -23939,9 +23939,6 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
msgid "is not a valid regular expression"
msgstr ""
msgid "is not allowed for sign-up"
msgstr ""
......
......@@ -8,6 +8,7 @@ module QA
include Events::Project
include Members
attr_accessor :repository_storage # requires admin access
attr_writer :initialize_with_readme
attr_writer :auto_devops_enabled
attr_writer :visibility
......@@ -116,6 +117,8 @@ module QA
post_body[:path] = name
end
post_body[:repository_storage] = repository_storage if repository_storage
post_body
end
......
......@@ -15,7 +15,8 @@ module QA
# supports the given feature
SUPPORTED_FEATURES = {
git_protocol_v2: 'QA_CAN_TEST_GIT_PROTOCOL_V2',
admin: 'QA_CAN_TEST_ADMIN_FEATURES'
admin: 'QA_CAN_TEST_ADMIN_FEATURES',
praefect: 'QA_CAN_TEST_PRAEFECT'
}.freeze
def supported_features
......@@ -26,6 +27,10 @@ module QA
ENV['QA_ADDITIONAL_REPOSITORY_STORAGE']
end
def praefect_repository_storage
ENV['QA_PRAEFECT_REPOSITORY_STORAGE']
end
def admin_password
ENV['GITLAB_ADMIN_PASSWORD']
end
......
......@@ -17,6 +17,28 @@ module QA
expect(project).to have_readme_content('This is a test project')
end
end
it 'pushes to a project using a specific Praefect repository storage', :smoke, :requires_admin, :requires_praefect, quarantine: { issue: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/276', type: :new } do
Flow::Login.sign_in_as_admin
project = Resource::Project.fabricate_via_api! do |storage_project|
storage_project.name = 'specific-repository-storage'
storage_project.repository_storage = QA::Runtime::Env.praefect_repository_storage
end
Resource::Repository::Push.fabricate! do |push|
push.repository_http_uri = project.repository_http_location.uri
push.file_name = 'README.md'
push.file_content = "# This is a test project named #{project.name}"
push.commit_message = 'Add README.md'
push.new_branch = true
end
project.visit!
expect(page).to have_content('README.md')
expect(page).to have_content("This is a test project named #{project.name}")
end
end
end
end
......@@ -271,6 +271,12 @@ describe QA::Runtime::Env do
env_key: 'QA_CAN_TEST_ADMIN_FEATURES',
default: true
it_behaves_like 'boolean method with parameter',
method: :can_test?,
param: :praefect,
env_key: 'QA_CAN_TEST_PRAEFECT',
default: true
it 'raises ArgumentError if feature is unknown' do
expect { described_class.can_test? :foo }.to raise_error(ArgumentError, 'Unknown feature "foo"')
end
......
import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mountComponent from 'helpers/vue_mount_component_helper';
import axios from '~/lib/utils/axios_utils';
import Api from '~/api';
import pipelinesTable from '~/commit/pipelines/pipelines_table.vue';
describe('Pipelines table in Commits and Merge requests', function() {
describe('Pipelines table in Commits and Merge requests', () => {
const jsonFixtureName = 'pipelines/pipelines.json';
let pipeline;
let PipelinesTable;
......@@ -37,19 +37,19 @@ describe('Pipelines table in Commits and Merge requests', function() {
describe('successful request', () => {
describe('without pipelines', () => {
beforeEach(function() {
beforeEach(() => {
mock.onGet('endpoint.json').reply(200, []);
vm = mountComponent(PipelinesTable, props);
});
it('should render the empty state', function(done) {
setTimeout(() => {
it('should render the empty state', done => {
setImmediate(() => {
expect(vm.$el.querySelector('.empty-state')).toBeDefined();
expect(vm.$el.querySelector('.realtime-loading')).toBe(null);
expect(vm.$el.querySelector('.js-pipelines-error-state')).toBe(null);
done();
}, 0);
});
});
});
......@@ -60,19 +60,19 @@ describe('Pipelines table in Commits and Merge requests', function() {
});
it('should render a table with the received pipelines', done => {
setTimeout(() => {
setImmediate(() => {
expect(vm.$el.querySelectorAll('.ci-table .commit').length).toEqual(1);
expect(vm.$el.querySelector('.realtime-loading')).toBe(null);
expect(vm.$el.querySelector('.empty-state')).toBe(null);
expect(vm.$el.querySelector('.js-pipelines-error-state')).toBe(null);
done();
}, 0);
});
});
describe('with pagination', () => {
it('should make an API request when using pagination', done => {
setTimeout(() => {
spyOn(vm, 'updateContent');
setImmediate(() => {
jest.spyOn(vm, 'updateContent').mockImplementation(() => {});
vm.store.state.pageInfo = {
page: 1,
......@@ -135,7 +135,7 @@ describe('Pipelines table in Commits and Merge requests', function() {
}),
);
setTimeout(() => {
setImmediate(() => {
expect(vm.$el.querySelector('.js-run-mr-pipeline')).not.toBeNull();
done();
});
......@@ -156,7 +156,7 @@ describe('Pipelines table in Commits and Merge requests', function() {
}),
);
setTimeout(() => {
setImmediate(() => {
expect(vm.$el.querySelector('.js-run-mr-pipeline')).toBeNull();
done();
});
......@@ -177,7 +177,7 @@ describe('Pipelines table in Commits and Merge requests', function() {
}),
);
setTimeout(() => {
setImmediate(() => {
expect(vm.$el.querySelector('.js-run-mr-pipeline')).toBeNull();
done();
});
......@@ -198,7 +198,7 @@ describe('Pipelines table in Commits and Merge requests', function() {
}),
);
setTimeout(() => {
setImmediate(() => {
expect(vm.$el.querySelector('.js-run-mr-pipeline')).toBeNull();
done();
});
......@@ -222,15 +222,15 @@ describe('Pipelines table in Commits and Merge requests', function() {
});
it('updates the loading state', done => {
spyOn(Api, 'postMergeRequestPipeline').and.returnValue(Promise.resolve());
jest.spyOn(Api, 'postMergeRequestPipeline').mockReturnValue(Promise.resolve());
setTimeout(() => {
setImmediate(() => {
vm.$el.querySelector('.js-run-mr-pipeline').click();
vm.$nextTick(() => {
expect(vm.state.isRunningMergeRequestPipeline).toBe(true);
setTimeout(() => {
setImmediate(() => {
expect(vm.state.isRunningMergeRequestPipeline).toBe(false);
done();
......@@ -248,14 +248,14 @@ describe('Pipelines table in Commits and Merge requests', function() {
vm = mountComponent(PipelinesTable, props);
});
it('should render error state', function(done) {
setTimeout(() => {
it('should render error state', done => {
setImmediate(() => {
expect(vm.$el.querySelector('.js-pipelines-error-state')).toBeDefined();
expect(vm.$el.querySelector('.realtime-loading')).toBe(null);
expect(vm.$el.querySelector('.js-empty-state')).toBe(null);
expect(vm.$el.querySelector('.ci-table')).toBe(null);
done();
}, 0);
});
});
});
});
......@@ -202,8 +202,8 @@ describe('Logs Store actions', () => {
return testAction(fetchLogs, null, state, expectedMutations, expectedActions, () => {
expect(latestGetParams()).toEqual({
pod_name: mockPodName,
start: mockFixedRange.start,
end: mockFixedRange.end,
start_time: mockFixedRange.start,
end_time: mockFixedRange.end,
cursor: mockCursor,
});
});
......@@ -280,8 +280,8 @@ describe('Logs Store actions', () => {
() => {
expect(latestGetParams()).toEqual({
pod_name: mockPodName,
start: mockFixedRange.start,
end: mockFixedRange.end,
start_time: mockFixedRange.start,
end_time: mockFixedRange.end,
cursor: mockCursor,
});
},
......
......@@ -509,8 +509,8 @@ describe('Monitoring store actions', () => {
});
describe('fetchPrometheusMetric', () => {
const params = {
start: '2019-08-06T12:40:02.184Z',
end: '2019-08-06T20:40:02.184Z',
start_time: '2019-08-06T12:40:02.184Z',
end_time: '2019-08-06T20:40:02.184Z',
};
let metric;
let state;
......
......@@ -14,8 +14,8 @@ describe Gitlab::Prometheus::Queries::AdditionalMetricsDeploymentQuery do
it 'queries using specific time' do
expect(client).to receive(:query_range).with(anything,
start: (deployment.created_at - 30.minutes).to_f,
stop: (deployment.created_at + 30.minutes).to_f)
start_time: (deployment.created_at - 30.minutes).to_f,
end_time: (deployment.created_at + 30.minutes).to_f)
expect(query_result).not_to be_nil
end
......
......@@ -12,7 +12,7 @@ describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
it 'queries using specific time' do
expect(client).to receive(:query_range)
.with(anything, start: 8.hours.ago.to_f, stop: Time.now.to_f)
.with(anything, start_time: 8.hours.ago.to_f, end_time: Time.now.to_f)
expect(query_result).not_to be_nil
end
......@@ -25,7 +25,7 @@ describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
it 'queries using the provided times' do
expect(client).to receive(:query_range)
.with(anything, start: start_time, stop: end_time)
.with(anything, start_time: start_time, end_time: end_time)
expect(query_result).not_to be_nil
end
end
......@@ -36,7 +36,7 @@ describe Gitlab::Prometheus::Queries::AdditionalMetricsEnvironmentQuery do
it 'queries using the provided times converted to unix' do
expect(client).to receive(:query_range)
.with(anything, start: start_time.to_f, stop: end_time.to_f)
.with(anything, start_time: start_time.to_f, end_time: end_time.to_f)
expect(query_result).not_to be_nil
end
end
......
......@@ -16,22 +16,22 @@ describe Gitlab::Prometheus::Queries::DeploymentQuery do
it 'sends appropriate queries to prometheus' do
start_time = (deployment.created_at - 30.minutes).to_f
stop_time = (deployment.created_at + 30.minutes).to_f
end_time = (deployment.created_at + 30.minutes).to_f
created_at = deployment.created_at.to_f
expect(client).to receive(:query_range).with('avg(container_memory_usage_bytes{container_name!="POD",environment="environment-slug"}) / 2^20',
start: start_time, stop: stop_time)
start_time: start_time, end_time: end_time)
expect(client).to receive(:query).with('avg(avg_over_time(container_memory_usage_bytes{container_name!="POD",environment="environment-slug"}[30m]))',
time: created_at)
expect(client).to receive(:query).with('avg(avg_over_time(container_memory_usage_bytes{container_name!="POD",environment="environment-slug"}[30m]))',
time: stop_time)
time: end_time)
expect(client).to receive(:query_range).with('avg(rate(container_cpu_usage_seconds_total{container_name!="POD",environment="environment-slug"}[2m])) * 100',
start: start_time, stop: stop_time)
start_time: start_time, end_time: end_time)
expect(client).to receive(:query).with('avg(rate(container_cpu_usage_seconds_total{container_name!="POD",environment="environment-slug"}[30m])) * 100',
time: created_at)
expect(client).to receive(:query).with('avg(rate(container_cpu_usage_seconds_total{container_name!="POD",environment="environment-slug"}[30m])) * 100',
time: stop_time)
time: end_time)
expect(subject.query(deployment.id)).to eq(memory_values: nil, memory_before: nil, memory_after: nil,
cpu_values: nil, cpu_before: nil, cpu_after: nil)
......
......@@ -22,7 +22,7 @@ describe Gitlab::Prometheus::Queries::KnativeInvocationQuery do
it 'has the query, but no data' do
expect(client).to receive(:query_range).with(
'sum(ceil(rate(istio_requests_total{destination_service_namespace="test-ns", destination_service=~"test-name.*"}[1m])*60))',
hash_including(:start, :stop)
hash_including(:start_time, :end_time)
)
subject.query(serverless_func.id)
......
......@@ -193,23 +193,23 @@ describe Gitlab::PrometheusClient do
let(:time_stop) { Time.now.in_time_zone("Warsaw") }
let(:time_start) { time_stop - 8.hours }
let(:query_url) { prometheus_query_range_url(prometheus_query, start: time_start.utc.to_f, stop: time_stop.utc.to_f) }
let(:query_url) { prometheus_query_range_url(prometheus_query, start_time: time_start.utc.to_f, end_time: time_stop.utc.to_f) }
it 'passed dates are properly converted to utc' do
req_stub = stub_prometheus_request(query_url, body: prometheus_values_body('vector'))
subject.query_range(prometheus_query, start: time_start, stop: time_stop)
subject.query_range(prometheus_query, start_time: time_start, end_time: time_stop)
expect(req_stub).to have_been_requested
end
end
context 'when a start time is passed' do
let(:query_url) { prometheus_query_range_url(prometheus_query, start: 2.hours.ago) }
let(:query_url) { prometheus_query_range_url(prometheus_query, start_time: 2.hours.ago) }
it 'passed it in the requested URL' do
<