FF_GIT_URLS_WITHOUT_TOKENS & kubernetes & powershell does not work when the runner manager does not run on windows

Summary

When

  • the runner manager does not run on windows
  • and the kubernetes executor is used
  • and the helper image is registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest-servercore1809 ¹
  • and the shell is set to powershell

then builds fail.

¹ It might work with other helper images, which bring a newer PowerShell version, however that has not been tested, as we need to support 1809 anyway.

Steps to reproduce

.gitlab-ci.yml
variables:
  FF_GIT_URLS_WITHOUT_TOKENS: true
  CI_DEBUG_TRACE: 1

test:
  stage: test
  image: registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest-servercore1809
  script:
    - |
      echo "hello"

Actual behavior

Build fails, because the repo cannot be pulled.

There are some issue in the git credential helper which is used with FF_GIT_URLS_WITHOUT_TOKENS. While the credential helper failure in itself does not cause the build to fail, the fact that it can't provide valid credentials fails the pull of the repo.

Expected behavior

Be able to pull & no errors in the git credential helper.

Relevant logs and/or screenshots

job log
   [...]
DEBUG:  400+  >>>> & "git" '-c' 'http.userAgent=gitlab-runner development 
version linux/amd64' 'fetch' 'origin' '--no-recurse-submodules' 
'+refs/pipelines/1685554197:refs/pipelines/1685554197' 
'+refs/heads/main:refs/remotes/origin/main' '--depth' '20' '--prune' '--quiet'
At line:1 char:43
+ function f([string]$cmd){ if ($cmd.equals(get)) { Write-Host -NoNewli ...
+                                           ~
Missing ')' in method call.
At line:1 char:43
+ function f([string]$cmd){ if ($cmd.equals(get)) { Write-Host -NoNewli ...
+                                           ~~~
Unexpected token 'get' in expression or statement.
At line:1 char:43
+ function f([string]$cmd){ if ($cmd.equals(get)) { Write-Host -NoNewli ...
+                                           ~~~
Missing closing ')' after expression in 'if' statement.
At line:1 char:25
+ function f([string]$cmd){ if ($cmd.equals(get)) { Write-Host -NoNewli ...
+                         ~
Missing closing '}' in statement block or type definition.
At line:1 char:46
+ function f([string]$cmd){ if ($cmd.equals(get)) { Write-Host -NoNewli ...
+                                              ~
Unexpected token ')' in expression or statement.
At line:1 char:47
+ function f([string]$cmd){ if ($cmd.equals(get)) { Write-Host -NoNewli ...
+                                               ~
Unexpected token ')' in expression or statement.
At line:1 char:106
+ ... t)) { Write-Host -NoNewline password=${env:CI_JOB_TOKEN}`n } }; f get
+                                                                  ~
Unexpected token '}' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordEx 
   ception
    + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
 
fatal: could not read Password for 'https://gitlab-ci-token@gitlab.com': terminal prompts disabled
   [...]

Environment description

config.toml contents

Needs a cluster with windows nodes.

listen_address = ":9252"
concurrent = 4
check_interval = 0
connection_max_age = "15m0s"
shutdown_timeout = 0
[session_server]
  session_timeout = 1800
[[runners]]
  name = "gke-win-0"
  url = "https://gitlab.com/"
  id = 0
  token = "glrt-NopeNopeNope"
  token_obtained_at = 0001-01-01T00:00:00Z
  token_expires_at = 0001-01-01T00:00:00Z
  executor = "kubernetes"
  shell = "powershell"
  environment = ["FF_USE_POWERSHELL_PATH_RESOLVER=true"]
  [runners.kubernetes]
    poll_timeout = 1200
    pull_policy = "always"
  [runners.kubernetes.node_selector]
    "kubernetes.io/arch" = "amd64"
    "kubernetes.io/os" = "windows"
    "node.kubernetes.io/windows-build" = "10.0.17763"

Used GitLab Runner version

11989094

Possible fixes

In https://gitlab.com/gitlab-org/gitlab-runner/-/blob/33064acc3ee57ccd6581e367582de8d77146038d/shells/powershell.go#L660 we react to a difference how quoting is handled across pwsh/powershell on different OSs. The intention here is, to change the quoting only on windows & powershell. Generally that works as is.

However, because we use runtime.GOOS here, we actually inspect the OS of the runner manager. In the case of the k8s executor this can however be different to the OS a job actually runs on. So must not check on the OS the runner manager runs on, but actually check on which OS the build will actually land on. Alternatively we could look into making this whole command across all OSs and shells, but I wasn't able to do that previously.

There might be other similar occurrences of the same problem: We expect that the OS a build runs on is the same OS the runner manager runs on -- which is not necessarily true; so we might want to do a quick check on other uses of runtime.GOOS.

Related

Edited by Hannes Hörl