Я использую Packer + Ansible для создания агента Linux TeamCity с использованием управляемого образа Windows Azure. Вот проблема, с которой я сталкиваюсь, описанная в серии шагов:
Мой сценарий Ansible создает пользователя teamcity
, которому необходимо будет прочитать файл из каталога /var/lib/waagent
, когда код агента TeamCity будет помещен на виртуальную машину агента самим сервером сборки через Агент Push . Я назначаю 0755
разрешения для каталога /var/lib/waagent
для teamcity
внутри моего скрипта Ansible.
Когда я создаю свой образ Linux через Packer + Ansible, на последнем этапе используется процесс waagent
, отвечающий за управление лазурью, для удаления машины из эксплуатации. Методом проб и ошибок я обнаружил, что этот процесс удаляет каталог /var/lib/waagent
как часть процедуры очистки.
Когда TeamCity / Azure Portal / etc использует этот управляемый образ, который мы создали на первых двух шагах для создания новой виртуальной машины, создается новая папка /var/lib/waagent
, но она принадлежит пользователю root
.
Когда код агента TeamCity выполняется под учетной записью teamcity
, он выполняет следующую команду (изнутри своей среды выполнения Kotlin): /bin/sh -c "sudo cat /var/lib/waagent/ovf-env.xml"
Сбой с ошибкой permission denied
, и, следовательно, агент TeamCity невозможно использовать данные в файле ovf-env.xml
для автоматической авторизации на сервере сборки - эту проблему я сейчас пытаюсь исправить.
У других пользователей были похожие проблемы с плагином TeamCity Azure, и им удалось исправить их, отредактировав файл /etc/sudoers
: https://github.com/JetBrains/teamcity-azure-agent/issues/86#issuecomment-365042798
Я немного не в себе, когда дело доходит до системного администрирования Ansible и Linux, но вот что я попытался сделать в своем скрипте Ansible, чтобы помочь воспроизвести это решение в моей собственной среде:
- name: "Define dir list from dict"
set_fact:
dotnetcore_dirs: "\
{{ dotnetcore_dirs | default([]) }} + \
[ '/opt/{{ item.key }}' ]"
with_dict: "{{ dotnetcore }}"
- set_fact:
dotnetcore_dirs: "{{ dotnetcore_dirs }} + [ '{{ teamcity_agent_install_dir }}', '/var/lib/waagent' ]"
- name: Add TeamCity group
group: "name={{ teamcity_agent_group }}"
state: present
become: true
- name: Add TeamCity user
user:
name: "{{ teamcity_agent_user }}"
password: "{{ teamcity_agent_password | password_hash('sha512') }}"
- name: "Create Agent Build dirs"
file:
path: "{{ item }}"
state: directory
owner: "{{ teamcity_agent_user }}"
group: "{{ teamcity_agent_group }}"
mode: 0755
with_items: "{{ dotnetcore_dirs }}"
- name: Modify sudoers file so we can cat /var/lib/waagent files
blockinfile:
path: /etc/sudoers
block: |
%{{ teamcity_agent_group }} ALL=(ALL) NOPASSWD: ALL
validate: 'visudo -cf %s'
- name: Add teamcity user to groups
user:
name: "{{ teamcity_agent_user }}"
groups: "docker, {{ teamcity_agent_group }}"
append: yes
До сих пор я не был успешным с таким подходом. Я могу выполнить следующую команду при подключении SSH к агенту TeamCity непосредственно из bash:
sudo cat /var/lib/waagent/ovf-env.xml
И с этим изображением можно просто прочитать содержимое файла.
Почему команда /bin/sh -c sudo cat /var/lib/waagent/ovf-env.xml
терпит неудачу, когда она запускается здесь с помощью кода Kotlin агента TeamCity Azure? https://github.com/JetBrains/teamcity-azure-agent/blob/9d267ce798f8218fc153d5d73bc954ede52e1250/plugin-azure-agent/src/main/kotlin/jetbrains/buildServer/clouds/azure/FileUtilsImpl.kt#L43-L53
private fun readFileWithSudo(file: File): String {
val commandLine = GeneralCommandLine()
commandLine.exePath = UNIX_SHELL_PATH
commandLine.addParameter("-c")
commandLine.addParameter("sudo cat $file")
val execResult = SimpleCommandLineProcessRunner.runCommand(commandLine, ByteArray(0))
if (execResult.exitCode != 0) {
throw IOException("Failed to read file: ${execResult.stderr}")
}
return execResult.stdout.trim()
}
Этот код выполняется под учетной записью teamcity
- так почему процесс, порожденный здесь Kotlin, не может сделать то, что может делать учетная запись teamcity
с обычного терминала bash? Что я могу сделать, чтобы это исправить?
Редактировать: используется strace
для отслеживания процесса запуска агента TeamCity, и вот соответствующие строки:
13565 stat("/var/lib/waagent", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13565 stat("/var/lib/waagent", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
13565 access("/var/lib/waagent", X_OK) = 0
13565 open("/var/lib/waagent/ovf-env.xml", O_RDONLY) = -1 EACCES (Permission denied)