'kubectl patch' работает на Linux Bash, но не на Windows Powershell ISE - PullRequest
1 голос
/ 10 апреля 2019

Следующая команда отлично работает на Ubuntu bash:

kubectl patch deployment wapi-backend-d1 --patch '{"spec": {"template": {"metadata": {"labels": {"date": "test"}}}}}'

Эта же команда не работает в Windows Powershell Console (ISE).

Ошибка:

kubectl : Error from server (BadRequest): invalid character 's' looking for beginning of object key string
At line:1 char:1
+ kubectl patch deployment wapi-backend-d1 --patch '{"spec": {"template ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Error from serv...ject key string:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Версия консоли powershell:

PS > $PSVersionTable

Name                           Value                                                                                                                                                                                                                             
----                           -----                                                                                                                                                                                                                             
PSVersion                      5.1.14409.1005                                                                                                                                                                                                                    
PSEdition                      Desktop                                                                                                                                                                                                                           
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                                                                                                                                           
BuildVersion                   10.0.14409.1005                                                                                                                                                                                                                   
CLRVersion                     4.0.30319.42000                                                                                                                                                                                                                   
WSManStackVersion              3.0                                                                                                                                                                                                                               
PSRemotingProtocolVersion      2.3                                                                                                                                                                                                                               
SerializationVersion           1.1.0.1            

Я пробовал команду с другим значением исправления, так как видел, что кто-то пишет, что исправление может завершиться ошибкой, если оно уже применено.

Путь / спецификация / шаблон / метаданные / метки / дата действительно существует в yaml развертывания, так что это тоже не проблема.

Я предполагаю, что это может быть связано с тем, что kubectl работает по-другому в Powershellв отношении кавычек, но не смог найти способ заставить его работать.

Я пытался

kubectl patch deployment wapi-backend-d1 --patch "{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"test123\"}}}}}"

Но это приводит к

Error from server (NotFound): deployments.extensions "spec\\: {\\template\\: {\\metadata\\: {\\labels\\: {\\date\\: \\test123\\}}}}}" not found

Что должно бытькоманда на Powershell?

Ответы [ 2 ]

2 голосов
/ 10 апреля 2019

Вы нашли правильное решение в своем собственном ответе , но позвольте мне попытаться его разобрать концептуально:

Встраивание " (двойные кавычки) в строковые аргументы, передаваемые внешним программам:

  • (a) Во-первых - разумно и неизбежно - вам необходимо выполнить синтаксические требования PowerShell в отношении встраивания символов ". в кавычках.

  • (b) Тогда - и этот шаг не обязателен - вам нужно \ -сканировать встроенные " символы. что вы хотите внешние программы чтобы увидеть .

    • Это давняя, утомительная ошибка , которая вряд ли будет исправлена, однако, пока должна поддерживаться обратная совместимость; см. этот выпуск GitHub .

Re (a) , у вас есть следующие опции:

  • '...' -цитирование (одинарное цитирование), внутри которого вы можете использовать " как есть:

    • '{ "spec": "none" }'
    • Все внутри '...' взято буквально - расширение (интерполяция) не происходит.
  • "..." -цитирование (двойное цитирование), внутри которого вы можете использовать `" или "" для встраивания " символов:

    • "{ `"spec`": `"none`" }" - ` - общий escape-символ PowerShell.
    • "{ ""spec"": ""none"" }" - " -специфический выход (удвоение)
    • Содержимое "..." подлежит расширению (интерполяция), что означает, что вы можете ссылаться на переменные ($var) или подвыражения ($(1 + 2)) внутри таких строк, которые PowerShell заменяет их значения - см. этот ответ , чтобы узнать больше о расширяемых строках PowerShell .

Если вы передаете такую ​​строку другим PowerShell командам (командлетам, функциям или сценариям), никаких дальнейших действий не требуется ; e.g.:

PS> Write-Output '3" of rain'
3" of rain

Re (b) - т.е. передать такие строки внешним программам - вам дополнительно необходимо \ - оставить встроенный " символов. :

  • Применение в ручном режиме при переходе к приведенным выше примерам:

    • '{ \"spec\": \"none\" }'
    • "{ \`"spec\`": \`"none\`" }"
    • "{ \""spec\"": \""none\"" }"
  • Применение экранирующего программно к существующей строке:

    • $str = '3" of rain'; $escapedStr = $str -replace '"', '\"'
  • То есть, чтобы внешняя программа в конечном итоге увидела буквальное значение 3" of rain, вы должны передать буквенное значение 3\" of rain из PowerShell. Это \ -экранирование - это то, что PowerShell, как оболочка, должна делать автоматически за сценой, но в настоящее время этого не делает.

  • Существует дополнительная ошибка в Windows PowerShell - поскольку исправлено в PowerShell Core - что неправильно обрабатывает строки с несбалансированным встроенных " символов. если " является частью первого слова :

    1161 * *
  • Например, вышеупомянутые методы НЕ работают с литеральными значениями, такими как 3" of rain - вместо этого вы должны использовать следующее чудовище: `"3\`" of rain`", которое технически представляет собой серию отдельных аргументов без кавычек, что означает, что (a) множественные пробелы между словами строк не поддерживаются (они свернуты в один пробел), и (b) метасимволы PowerShell, такие как & < > $ & | @ {, должны быть отдельно ` -экранированы.
  • Обратите внимание, что ошибка появляется, только если " является частью первого слова в значении, и только если этому первому слову не предшествует пробел (хотя аргументы с начальным пробелом редко бывают полезны); например, '3 \" of rain' будет снова работать, потому что несбалансированный " не является частью первого слова.

например:.

# Using choice.exe as a sample external program to pass a string to.
# choice.exe echoes the string it receives via /m as the prompt message.
PS> choice /m '{ \"spec\": \"none\" }' /d Y /t 0
{ "spec": "none" } [Y,N]?Y
2 голосов
/ 10 апреля 2019

Подробную и очень полезную информацию см. В ответе от mklement0

. После большого разочарования я решил перечислить все варианты выхода из цитаты, которые я пробовал, и нашелс еще одним, который неожиданно сработал!Итак, поделитесь им здесь:

kubectl patch deployment wapi-backend-d1 --patch '{\"spec\": {\"template\": {\"metadata\": {\"labels\": {\"date\": \"test123\"}}}}}'

Вот как использовать патч kubectl с Powershell

Кроме того, обратите внимание: на самом деле я пытался патчить его с отметкой времени, чтобы вызвать скользящее обновлениебез изменения тегов изображений-контейнеров (поэтому установка изображения не помогла бы мне).

Когда вы пытаетесь поместить свой JSON в переменную, а затем вызываете kubectl patch с переменной, у вас снова возникают проблемы с экранированием.Вот чем я закончил:

$patchRequest = @{
    spec = @{
        template = @{
            metadata = @{
                labels = @{
                    date = ((((Get-Date -Format o)).replace(':','-').replace('+','_')))
                }
            }
        }
    }
}
$patchJson = ((ConvertTo-Json -InputObject $patchRequest -Compress -Depth 10))
$patchJson = $patchJson.replace('"','\"')
kubectl patch deployment wapi-backend-d1 --patch $patchJson
...