Skip to content

feat: Allow for DNS Zone change in RD Config

Shekhar Patnaik requested to merge spatnaik/425778-allow-update-rd-dnszone into master

Issue: Allow updating dns_zone in remote development a... (#425778 - closed)

What does this MR do and why?

Currently we don't allow for users to update the DNS Zone in the remote development configuration. This will give users the ability to update the DNS Zone. When the DNS Zone is updated, the corresponding workspaces will also be updated.

How to set up and validate locally

  1. Setup remote development and run a local instance of GitLab Agent
  2. Create a workspace
  3. Update the DNS Zone in the agent config to a new value, and commit it
  4. Check the URL of the workspace in the Workspaces List tab, see that it was updated to use the new DNS zone.
  5. Verify that the workspace is automatically restarted on the next reconciliation loop. NOTE: The DNS resolution for the new name may be out of sync during this period, we have decided this is acceptable.
  6. After restart, click the hostname and make sure the workspace is available and working. E.g. open the terminal in the Web IDE, check the local hostname (which will be different than external hostname and not have the DNS zone), etc.

Screen Recording

Screen_Recording_2024-01-05_at_4.31.49_PM

Database Change Notes

Context

For context, there are currently (as of 2024-01-05) there are only 11 records in the production SaaS database which will be impacted by the migration in this MR:

gitlabhq_production=> SELECT actual_state, COUNT(id) FROM workspaces GROUP BY actual_state;
   actual_state    | count
-------------------+-------
 Running           |     4
 CreationRequested |     7
 Terminated        |   423
(3 rows)

And given that we have had very little feedback from on-prem/enterprise users so far in the Beta period, I think it is not likely that any current on-prem users have many more records than this.

Migrate UP Queries

Query to move data to new columns:

        UPDATE workspaces
        SET url_prefix = CONCAT('https://#{DEFAULT_PORT}-', name),
            dns_zone = remote_development_agent_configs.dns_zone,
            url_query_string = CASE
                                    WHEN POSITION('?' IN url) > 0
                                    THEN SUBSTRING(url FROM POSITION('?' IN url) + 1)
                                    ELSE ''
                                END
        FROM
            remote_development_agent_configs
        WHERE
            workspaces.cluster_agent_id = remote_development_agent_configs.cluster_agent_id
        AND url IS NOT NULL
        AND workspaces.id BETWEEN 1 AND 500

Query to null out old column:

        UPDATE workspaces
        SET url = NULL
        WHERE workspaces.id BETWEEN 1 AND 500
        AND url_prefix IS NOT NULL
        AND dns_zone IS NOT NULL
        AND url_query_string IS NOT NULL

Migrate DOWN queries

Query to move data back to old column:

        UPDATE workspaces
        SET url = CONCAT(url_prefix, '.', dns_zone, '?', url_query_string)
        WHERE workspaces.id BETWEEN 1 AND 500

Query to clear out new columns:

        UPDATE workspaces
        SET url_prefix = NULL,
            dns_zone = NULL,
            url_query_string = NULL
        WHERE workspaces.id BETWEEN 1 AND 500

Update All query

Info for new update_all query in ee/lib/remote_development/agent_config/updater.rb

UPDATE "workspaces" SET "force_include_all_resources" = TRUE, "dns_zone" = 'workspaces.localdev.me8' WHERE "workspaces"."id" IN (SELECT "workspaces"."id" FROM "workspaces" INNER JOIN "cluster_agents" ON "workspaces"."cluster_agent_id" = "cluster_agents"."id" WHERE "cluster_agents"."id" = 4 AND NOT ("workspaces"."desired_state" = 'Terminated' AND "workspaces"."actual_state" = 'Terminated'))

The corresponding new touch_all query is equivalent.

Note that in terms of number of records affected, both of these new queries are functionally identical to the existing touch_all production query in ee/lib/remote_development/workspaces/reconcile/persistence/workspaces_to_be_returned_updater.rb in the case of a full reconciliation:

UPDATE "workspaces" SET "updated_at" = '2024-01-06 00:44:42.896864', "responded_to_agent_at" = '2024-01-06 00:44:42.896864' WHERE "workspaces"."cluster_agent_id" = 4 AND "workspaces"."id" IN (89, 90)

In other words, in both cases, all workspace records associated with the agent which are not terminated will have some non-key fields updated.

The only difference is in the WHERE clause to obtain the records. In the new case, it's based off a join to the agent record, and in the existing case it will be an IN (...) clause listing all the agent's workspaces, based off of a list of IDs which were determined earlier in the reconciliation logic, based off the complete list of workspace names sent by the agent.

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Chad Woolley

Merge request reports