feat: Allow for DNS Zone change in RD Config
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
- Setup remote development and run a local instance of GitLab Agent
- Create a workspace
- Update the DNS Zone in the agent config to a new value, and commit it
- Check the URL of the workspace in the Workspaces List tab, see that it was updated to use the new DNS zone.
- 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.
- 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
- Postgres.ai query explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25147/commands/80257
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
- Postgres.ai query explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25147/commands/80258
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
- Postgres.ai query explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25147/commands/80259
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
- Postgres.ai query explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25147/commands/80260
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'))
- Postgres.ai query explain: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/25147/commands/80261
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.
-
I have evaluated the MR acceptance checklist for this MR.