Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
077a0d707f
commit
9c149f7026
|
|
@ -15,8 +15,8 @@ const createSandbox = () => {
|
|||
return iframeEl;
|
||||
};
|
||||
|
||||
export default async () => {
|
||||
const wrapperEl = document.getElementById('js-openapi-viewer');
|
||||
export default async (el = document.getElementById('js-openapi-viewer')) => {
|
||||
const wrapperEl = el;
|
||||
const sandboxEl = createSandbox();
|
||||
|
||||
const { data } = await axios.get(wrapperEl.dataset.endpoint);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ const viewers = {
|
|||
svg: () => import('./image_viewer.vue'),
|
||||
sketch: () => import('./sketch_viewer.vue'),
|
||||
notebook: () => import('./notebook_viewer.vue'),
|
||||
openapi: () => import('./openapi_viewer.vue'),
|
||||
};
|
||||
|
||||
export const loadViewer = (type, isUsingLfs) => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
<script>
|
||||
import renderOpenApi from '~/blob/openapi';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
blob: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
url: this.blob.rawPath,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
renderOpenApi(this.$refs.viewer);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="viewer" class="file-content" :data-endpoint="url" data-testid="openapi"></div>
|
||||
</template>
|
||||
|
|
@ -171,7 +171,7 @@ the time limit to resolve all files is 30 seconds.
|
|||
|
||||
#### `include:local`
|
||||
|
||||
Use `include:local` to include a file that is in the same repository as the `.gitlab-ci.yml` file.
|
||||
Use `include:local` to include a file that is in the same repository as the project running the pipeline.
|
||||
Use `include:local` instead of symbolic links.
|
||||
|
||||
**Keyword type**: Global keyword.
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ response = ServiceResponse.error(
|
|||
|
||||
if response.success?
|
||||
head :ok
|
||||
if response.reason == :job_not_retriable
|
||||
elsif response.reason == :job_not_retriable
|
||||
head :unprocessable_entity
|
||||
else
|
||||
head :bad_request
|
||||
|
|
|
|||
|
|
@ -7,8 +7,21 @@ module Gitlab
|
|||
module Database
|
||||
module LoadBalancing
|
||||
class Resolver
|
||||
FAR_FUTURE_TTL = 100.years.from_now
|
||||
|
||||
UnresolvableNameserverError = Class.new(StandardError)
|
||||
|
||||
Response = Class.new do
|
||||
attr_reader :address, :ttl
|
||||
|
||||
def initialize(address:, ttl:)
|
||||
raise ArgumentError unless ttl.present? && address.present?
|
||||
|
||||
@address = address
|
||||
@ttl = ttl
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(nameserver)
|
||||
@nameserver = nameserver
|
||||
end
|
||||
|
|
@ -28,13 +41,14 @@ module Gitlab
|
|||
private
|
||||
|
||||
def ip_address
|
||||
IPAddr.new(@nameserver)
|
||||
# IP addresses are valid forever
|
||||
Response.new(address: IPAddr.new(@nameserver), ttl: FAR_FUTURE_TTL)
|
||||
rescue IPAddr::InvalidAddressError
|
||||
end
|
||||
|
||||
def ip_address_from_hosts_file
|
||||
ip = Resolv::Hosts.new.getaddress(@nameserver)
|
||||
IPAddr.new(ip)
|
||||
Response.new(address: IPAddr.new(ip), ttl: FAR_FUTURE_TTL)
|
||||
rescue Resolv::ResolvError
|
||||
end
|
||||
|
||||
|
|
@ -42,7 +56,12 @@ module Gitlab
|
|||
answer = Net::DNS::Resolver.start(@nameserver, Net::DNS::A).answer
|
||||
return if answer.empty?
|
||||
|
||||
answer.first.address
|
||||
raw_response = answer.first
|
||||
|
||||
# Defaults to 30 seconds if there is no TTL present
|
||||
ttl_in_seconds = raw_response.ttl.presence || 30
|
||||
|
||||
Response.new(address: answer.first.address, ttl: ttl_in_seconds.seconds.from_now)
|
||||
rescue Net::DNS::Resolver::NoResponseError
|
||||
raise UnresolvableNameserverError, "no response from DNS server(s)"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ module Gitlab
|
|||
@use_tcp = use_tcp
|
||||
@load_balancer = load_balancer
|
||||
@max_replica_pools = max_replica_pools
|
||||
@nameserver_ttl = 1.second.ago # Begin with an expired ttl to trigger a nameserver dns lookup
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
|
|
@ -191,8 +192,14 @@ module Gitlab
|
|||
end
|
||||
|
||||
def resolver
|
||||
@resolver ||= Net::DNS::Resolver.new(
|
||||
nameservers: Resolver.new(@nameserver).resolve,
|
||||
return @resolver if defined?(@resolver) && @nameserver_ttl.future?
|
||||
|
||||
response = Resolver.new(@nameserver).resolve
|
||||
|
||||
@nameserver_ttl = response.ttl
|
||||
|
||||
@resolver = Net::DNS::Resolver.new(
|
||||
nameservers: response.address,
|
||||
port: @port,
|
||||
use_tcp: @use_tcp
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import OpenapiViewer from '~/repository/components/blob_viewers/openapi_viewer.vue';
|
||||
import renderOpenApi from '~/blob/openapi';
|
||||
|
||||
jest.mock('~/blob/openapi');
|
||||
|
||||
describe('OpenAPI Viewer', () => {
|
||||
let wrapper;
|
||||
|
||||
const DEFAULT_BLOB_DATA = { rawPath: 'some/openapi.yml' };
|
||||
|
||||
const createOpenApiViewer = () => {
|
||||
wrapper = shallowMountExtended(OpenapiViewer, {
|
||||
propsData: { blob: DEFAULT_BLOB_DATA },
|
||||
});
|
||||
};
|
||||
|
||||
const findOpenApiViewer = () => wrapper.findByTestId('openapi');
|
||||
|
||||
beforeEach(() => createOpenApiViewer());
|
||||
|
||||
it('calls the openapi render', () => {
|
||||
expect(renderOpenApi).toHaveBeenCalledWith(wrapper.vm.$refs.viewer);
|
||||
});
|
||||
|
||||
it('renders an openapi viewer', () => {
|
||||
expect(findOpenApiViewer().exists()).toBe(true);
|
||||
expect(findOpenApiViewer().attributes('data-endpoint')).toBe(DEFAULT_BLOB_DATA.rawPath);
|
||||
});
|
||||
});
|
||||
|
|
@ -2,15 +2,16 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::Resolver do
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::Resolver, :freeze_time, feature_category: :database do
|
||||
describe '#resolve' do
|
||||
let(:ip_addr) { IPAddr.new('127.0.0.2') }
|
||||
|
||||
context 'when nameserver is an IP' do
|
||||
it 'returns an IPAddr object' do
|
||||
service = described_class.new('127.0.0.2')
|
||||
response = service.resolve
|
||||
|
||||
expect(service.resolve).to eq(ip_addr)
|
||||
expect(response.address).to eq(ip_addr)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -22,12 +23,14 @@ RSpec.describe Gitlab::Database::LoadBalancing::Resolver do
|
|||
allow(instance).to receive(:getaddress).with('localhost').and_return('127.0.0.2')
|
||||
end
|
||||
|
||||
expect(subject).to eq(ip_addr)
|
||||
expect(subject.address).to eq(ip_addr)
|
||||
end
|
||||
|
||||
context 'when nameserver is not in the hosts file' do
|
||||
let(:raw_ttl) { 10 }
|
||||
|
||||
it 'looks the nameserver up in DNS' do
|
||||
resource = double(:resource, address: ip_addr)
|
||||
resource = double(:resource, address: ip_addr, ttl: raw_ttl)
|
||||
packet = double(:packet, answer: [resource])
|
||||
|
||||
allow_next_instance_of(Resolv::Hosts) do |instance|
|
||||
|
|
@ -38,7 +41,8 @@ RSpec.describe Gitlab::Database::LoadBalancing::Resolver do
|
|||
.with('localhost', Net::DNS::A)
|
||||
.and_return(packet)
|
||||
|
||||
expect(subject).to eq(ip_addr)
|
||||
expect(subject.address).to eq(ip_addr)
|
||||
expect(subject.ttl).to eq(raw_ttl.seconds.from_now)
|
||||
end
|
||||
|
||||
context 'when nameserver is not in DNS' do
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery, feature_category: :database do
|
||||
let(:load_balancer) do
|
||||
configuration = Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
|
||||
configuration.service_discovery[:record] = 'localhost'
|
||||
|
|
@ -23,6 +23,8 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
resource = double(:resource, address: IPAddr.new('127.0.0.1'))
|
||||
packet = double(:packet, answer: [resource])
|
||||
|
||||
service.instance_variable_set(:@nameserver_ttl, Gitlab::Database::LoadBalancing::Resolver::FAR_FUTURE_TTL)
|
||||
|
||||
allow(Net::DNS::Resolver).to receive(:start)
|
||||
.with('localhost', Net::DNS::A)
|
||||
.and_return(packet)
|
||||
|
|
@ -362,4 +364,52 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
|
|||
expect(service.addresses_from_load_balancer).to eq(addresses)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#resolver', :freeze_time do
|
||||
context 'without predefined resolver' do
|
||||
it 'fetches a new resolver and assigns it to the instance variable' do
|
||||
expect(service.instance_variable_get(:@resolver)).not_to be_present
|
||||
|
||||
service_resolver = service.resolver
|
||||
|
||||
expect(service.instance_variable_get(:@resolver)).to be_present
|
||||
expect(service_resolver).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
context 'with predefined resolver' do
|
||||
let(:resolver) do
|
||||
Net::DNS::Resolver.new(
|
||||
nameservers: 'localhost',
|
||||
port: 8600
|
||||
)
|
||||
end
|
||||
|
||||
before do
|
||||
service.instance_variable_set(:@resolver, resolver)
|
||||
end
|
||||
|
||||
context "when nameserver's TTL is in the future" do
|
||||
it 'returns the existing resolver' do
|
||||
expect(service.resolver).to eq(resolver)
|
||||
end
|
||||
end
|
||||
|
||||
context "when nameserver's TTL is in the past" do
|
||||
before do
|
||||
service.instance_variable_set(
|
||||
:@nameserver_ttl,
|
||||
1.minute.ago
|
||||
)
|
||||
end
|
||||
|
||||
it 'fetches new resolver' do
|
||||
service_resolver = service.resolver
|
||||
|
||||
expect(service_resolver).to be_present
|
||||
expect(service_resolver).not_to eq(resolver)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -760,31 +760,12 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
|
|||
stub_ci_pipeline_yaml_file(config)
|
||||
end
|
||||
|
||||
it 'creates the environment with tags' do
|
||||
it 'creates the environment with tags', :sidekiq_inline do
|
||||
result = execute_service.payload
|
||||
|
||||
expect(result).to be_persisted
|
||||
expect(Environment.find_by(name: "review/master")).to be_present
|
||||
expect(result.builds.first.tag_list).to contain_exactly('hello')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when create deployment step is synchronous' do
|
||||
before do
|
||||
config = YAML.dump(
|
||||
deploy: {
|
||||
environment: { name: "review/$CI_COMMIT_REF_NAME" },
|
||||
script: 'ls',
|
||||
tags: ['hello']
|
||||
})
|
||||
|
||||
stub_feature_flags(move_create_deployments_to_worker: false)
|
||||
stub_ci_pipeline_yaml_file(config)
|
||||
end
|
||||
|
||||
it 'creates the deployments successfully' do
|
||||
result = execute_service.payload
|
||||
|
||||
expect(result.builds.first.deployment).to be_persisted
|
||||
expect(result.builds.first.deployment.deployable).to be_a(Ci::Build)
|
||||
end
|
||||
|
|
@ -882,11 +863,13 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
|
|||
stub_ci_pipeline_yaml_file(YAML.dump(ci_yaml))
|
||||
end
|
||||
|
||||
it 'creates a pipeline with the environment' do
|
||||
it 'creates a pipeline with the environment', :sidekiq_inline do
|
||||
result = execute_service.payload
|
||||
|
||||
expect(result).to be_persisted
|
||||
expect(Environment.find_by(name: 'production')).to be_present
|
||||
expect(result.builds.first.deployment).to be_persisted
|
||||
expect(result.builds.first.deployment.deployable).to be_a(Ci::Build)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1329,9 +1312,11 @@ RSpec.describe Ci::CreatePipelineService, :yaml_processor_feature_flag_corectnes
|
|||
}
|
||||
end
|
||||
|
||||
it 'has a job with environment' do
|
||||
it 'has a job with environment', :sidekiq_inline do
|
||||
expect(pipeline.builds.count).to eq(1)
|
||||
expect(pipeline.builds.first.persisted_environment.name).to eq('review/master')
|
||||
expect(pipeline.builds.first.persisted_environment.name).to eq('review/master')
|
||||
expect(pipeline.builds.first.deployment).to be_created
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue