Skip to content

Add gitlab_rails['cdn_host'] setting

Jason Young requested to merge 6824-add-cdn-host-setting into master

What does this MR do?

Related issues

Closes #6824 (closed)

Testing

Testing here is functionally equivalent to the testing strategy for the charts MR

Set up a functional CDN:

Tested Worker Script
const CORS_HEADERS = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS',
  'Access-Control-Allow-Headers': 'X-Csrf-Token, X-Requested-With',
}

const ORIGIN_HOSTNAME = 'gitlab.clusterdomain'
const CACHE_PRIVATE_OBJECTS = false

self.addEventListener('fetch', event => event.respondWith(handle(event)))

async function handle(event) {
  try {
    let response = await verifyAndHandle(event);

    // responses returned from cache are immutable, so we recreate them
    // to set CORS headers
    response = new Response(response.body, response)
    response.headers.set('Access-Control-Allow-Origin', '*')

    return response
  } catch (e) {
    return new Response('An error occurred!', {status: e.statusCode || 500})
  }
}

async function verifyAndHandle(event) {
  if (event.request.method === 'OPTIONS') {
    return handleOptions(event.request)
  }

  return handleRequest(event)
}

function handleOptions(request) {
  // Make sure the necessary headers are present
  // for this to be a valid pre-flight request
  if (
    request.headers.get('Origin') !== null &&
    request.headers.get('Access-Control-Request-Method') !== null &&
    request.headers.get('Access-Control-Request-Headers') !== null
  ) {
    // Handle CORS pre-flight request
    return new Response(null, {
      headers: CORS_HEADERS,
    })
  } else {
    // Handle standard OPTIONS request
    return new Response(null, {
      headers: {
        Allow: 'GET, HEAD, OPTIONS',
      },
    })
  }
}

async function handleRequest(event) {
  let cache = caches.default
  let url = new URL(event.request.url)
  let headers = new Headers(event.request.headers)

  url.host = ORIGIN_HOSTNAME
  console.log(url)


  let request = new Request(url, { headers: headers })
  let cached_response = await cache.match(request)
  let is_conditional_header_set = headers.has('If-None-Match')

  if (cached_response) {
    return cached_response
  }

  // We don't want to override If-None-Match that is set on the original request
  if (cached_response && !is_conditional_header_set) {
    headers.set('If-None-Match', cached_response.headers.get('ETag'))
  }

  let response = await fetch(request, {headers: headers  })
  console.log(response)

  if (response.status == 304) {
    if (is_conditional_header_set) {
      return response
    } else {
      return cached_response
    }
  } else if (response.ok) {
    response = new Response(response.body, response)

    // cache.put will never cache any response with a Set-Cookie header
    response.headers.delete('Set-Cookie')

    if (CACHE_PRIVATE_OBJECTS) {
      response.headers.delete('Cache-Control')
    }

    event.waitUntil(cache.put(request, response.clone()))
  }

  return response
}

  • Set up the latest nightly package, with the cookbooks symlinked to this checked out branch ( 6824-add-cdn-host-setting ) per the development docs
  • Set gitlab_rails['cdn_host'] = '//name.account.workers.dev' in /etc/gitlab/gitlab.rb and run reconfigure
  • Observe the cdn_host: //name.account.workers.dev setting written to /var/opt/gitlab/gitlab-rails/etc/gitlab.yml
  • Observe that asset requests are made to name.account.workers.dev after puma restarts and loads the application code
  • Running gitlab-rails console should show your configured cdn_host in Settings.gitlab['cdn_host'] as well as Rails.application.config.action_controller.asset_host

A functioning CDN is not actually required, the application UI will just be in a broken state trying to generate requests for .js files and other assets to http[s]://name.account.workers.dev/assets/[asset] - but it can be used to verify that the asset_host was set appropriately from the configured gitlab_rails['cdn_host']

Checklist

See Definition of done.

For anything in this list which will not be completed, please provide a reason in the MR discussion

Required

  • Merge Request Title, and Description are up to date, accurate, and descriptive
  • MR targeting the appropriate branch
  • MR has a green pipeline on GitLab.com
  • Pipeline is green on dev.gitlab.org if the change is touching anything besides documentation or internal cookbooks
  • trigger-package has a green pipeline running against latest commit

Expected (please provide an explanation if not completing)

  • Test plan indicating conditions for success has been posted and passes
  • Documentation created/updated
  • Tests added
  • Integration tests added to GitLab QA
  • Equivalent MR/issue for the GitLab Chart opened ( Issue / MR )
Edited by Jason Young

Merge request reports