Add workspace tunnelling grpc service

Issue: Tunnel workspaces traffic to appropriate agentw (#688 - closed)

Description

Add workspace tunnelling grpc service which tunnels incoming HTTP requests on the Workspaces HTTP Server to localhost:port inside the workspace where agentw is running.

Steps to verify

  1. Update GDK to pull latest changes in Add workspaces in gdk.yml (gitlab-org/gitlab-development-kit!5034 - merged) .

  2. Setup dnsmasq for pointing workspaces.gdk.test and its subdomains to the listen_address (172.16.123.1). There is a separate issue to make this part of GDK itself - GDK: Introduce dnsmasq service (gitlab-org/gitlab-development-kit#2694)

    Click to expand for steps to setup dnsmasq
    # Reference - https://allanphilipbarku.medium.com/setup-automatic-local-domains-with-dnsmasq-on-macos-ventura-b4cd460d8cb3
    
    ## Step 1: Install and configure Dnsmasq
    
    brew install dnsmasq
    
    mkdir -pv $(brew --prefix)/etc/
    
    echo 'address=/workspaces.gdk.test/172.16.123.1' >> $(brew --prefix)/etc/dnsmasq.conf
    
    sudo brew services start dnsmasq
    
    dig x.workspaces.gdk.test @127.0.0.1
    
    ## Step 2: Create a dns resolver and test setup
    
    sudo mkdir -v /etc/resolver
    
    sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/workspaces.gdk.test'
    
    sudo killall -HUP mDNSResponder
    
    ## Step 3: Verify
    
    dig x.workspaces.gdk.test
  3. Generate certs for workspaces domain in your GDK directory - mkcert "*.workspaces.gdk.test"

  4. Checkout GitLab on vtak/agentw_integration_test branch.

  5. Checkout GitLab Agent on this branch(vtak/add_reverse_tunnel).

  6. Update gdk.yml

    ---
    gitlab_k8s_agent:
      agent_listen_address: gdk.test:8150
      enabled: true
      k8s_api_listen_address: gdk.test:8154
    hostname: gdk.test
    listen_address: 172.16.123.1
    nginx:
      enabled: true
      http:
        enabled: true
    workspaces:
      enabled: true
  7. gdk reconfigure && gdk restart

  8. Start agentk and create a workspace from it.

  9. Start agentw (in GoLand or CLI). Use the token of the workspace created above by running the following command in the rails console - RemoteDevelopment::Workspace.find_by_name('workspace-4-1-n8dl59').workspace_token.token. Send the following flags to this agentw - --kas-address=grpc://172.16.123.1:8150 --token-file="/location/to-file/containing/agentw/token.txt" --observability-listen-address=":8081"

  10. Get the workspace ID from rails

    [6] pry(main)> RemoteDevelopment::Workspace.find_by_name('workspace-4-1-n8dl59').id
      RemoteDevelopment::Workspace Load (0.4ms)  SELECT "workspaces".* FROM "workspaces" WHERE "workspaces"."name" = 'workspace-4-1-n8dl59' LIMIT 1 /*application:console,db_config_database:gitlabhq_development,db_config_name:main,console_hostname:vtak--20250504-TQGKQ,console_username:vtak,line:(pry):6:in `__pry__'*/
    => 30
  11. Verify logs.

    KAS logs

    ...
    {"time":"2025-08-18T14:18:16.895209+05:30","level":"DEBUG","msg":"Registering agent tunnel","agent_key":"agentw:30","tunnels_by_agent":0}
    {"time":"2025-08-18T14:18:16.895233+05:30","level":"DEBUG","msg":"Registering agent tunnel","agent_key":"agentw:30","tunnels_by_agent":1}

    An agentw represents a workspace. Notice the agent_key has agent_id 30 which is the workspace id retrieved in the above step.

    agentw logs

    {"time":"2025-08-18T14:18:16.854111+05:30","level":"INFO","msg":"Starting","mod_name":"google_profiler"}
    {"time":"2025-08-18T14:18:16.854115+05:30","level":"INFO","msg":"Starting","mod_name":"workspaces"}
    {"time":"2025-08-18T14:18:16.854227+05:30","level":"INFO","msg":"Starting","mod_name":"agent2kas_tunnel"}
    {"time":"2025-08-18T14:18:16.854238+05:30","level":"INFO","msg":"Starting","mod_name":"observability"}
    {"time":"2025-08-18T14:18:16.854244+05:30","level":"INFO","msg":"Starting","mod_name":"agent_registrar"}
    {"time":"2025-08-18T14:18:16.854769+05:30","level":"INFO","msg":"Observability endpoint is up","mod_name":"observability","net_network":"tcp","net_address":"[::]:8081"}
  12. Start a HTTP Server (this is mimicking the VS Code server that is running inside a workspace, or any other service port in the workspace)

    python3 -m http.server 60001
  13. Access this server through reverse tunnelling - https://60001-workspace-4-1-n8dl59.workspaces.gdk.test:3555

Edited by Chad Woolley

Merge request reports

Loading