Введение
Теперь Fieldlight Studio нужен полный фотокомплект: три уменьшенные фотографии, контактный лист, подписи и галерея, работающая после скачивания. Один агент Jenkins умеет подготавливать фотографии; на другом есть предоставленный инструмент упаковки. Правильный выбор обоих агентов не делает файлы их рабочих каталогов общими.
Вы увидите эту проблему отсутствующих файлов, добавите настоящую временную передачу в рамках одного запуска Pipeline и сохраните полученный ZIP для независимого использования. Эта лабораторная работа начинается с собственных оригиналов, подключённых агентов и ещё не запускавшегося задания; файлы или сборки предыдущей работы она не использует.
Необходимо знать метки агентов, выделение агента этапу, опцию ширины, встроенные артефакты Jenkins, настройку отпечатка и очистку рабочего каталога из работы Выберите агента для обработки фотографий, а также основы навигации в Jenkins. Программирование на Java и установка агентов не нужны. Оба агента — отдельные контейнеры с независимыми файловыми системами на одной учебной виртуальной машине с общим ядром. Fieldlight и его учебные фотографии, созданные ИИ, не изображают реального клиента или событие. Продолжительность — авторская оценка, а не измеренное время для начинающих.
Изучите отдельные рабочие каталоги
На этом шаге вы проследите работу от агента изображений до агента упаковки и увидите, почему успешная подготовка не даёт пригодного для передачи результата. Начните в Photo Desk.
Изучите три оригинала Garden Stories: лаванду, садовую дорожку и лейку. Откройте каждое изображение и вернитесь действием браузера Back. Photo Desk сообщает No completed collection yet. Эти оригиналы должны остаться неизменными. Для нужного результата используются уменьшенные изображения шириной ровно 320 пикселей с сохранением соотношения сторон.
Переключитесь в Jenkins и откройте build-photo-pack. Выберите Configure → Pipeline. Прочитайте подготовленный Script. Верхнеуровневый agent none позволяет каждому этапу выделить собственного подходящего агента. Prepare photos запрашивает photo-imaging и запускает /opt/fieldlight/prepare-photos --width 320; Pack collection запрашивает photo-packing и запускает /opt/fieldlight/pack-photos.
Каждый этап начинается с deleteDir() и имеет собственную очистку post { always { deleteDir() } }. Рабочий каталог принадлежит агенту, выделенному заданию. Хотя оба этапа используют одно имя задания, их каталоги находятся в отдельных файловых системах контейнеров. Это не два имени общего каталога. Оригиналы только для чтения находятся вне рабочего каталога задания, в /opt/fieldlight/originals на агенте изображений.
Программа обработки изображений записывает шесть файлов относительно своего текущего рабочего каталога:
prepared/
images/
garden-01.png
garden-02.png
garden-03.png
contact-sheet.png
captions.csv
preparation.json
Размер трёх уменьшенных изображений — 320 × 213 пикселей. Контактный лист показывает их вместе; CSV связывает каждое имя файла с подписью и размерами; JSON указывает коллекцию, запрошенную ширину и хеши исходных изображений. Предоставленный инструмент упаковки использует эти реальные файлы из собственного рабочего каталога. Он не получает недостающие файлы с другого агента или из Photo Desk.
Вернитесь на страницу задания, не редактируя скрипт, и один раз выберите Build Now. Откройте новую сборку с номером в Build History, затем Console Output. Дождитесь ожидаемого FAILURE. Сначала image-studio сообщает 3 previews at 320 pixels wide. После его очистки pack-studio выполняет команду упаковки и сообщает Missing prepared/preparation.json in this agent's workspace. Заключительная очистка также выполняется.
Это ошибка расположения файлов, а не испорченный оригинал или отсутствующая программа. Этап подготовки завершился, но передачи не было. Ручное копирование файлов, общее монтирование, удаление очистки или размещение обоих этапов на агенте изображений позволили бы обойти учебную задачу, не обеспечив предусмотренный процесс на двух агентах. Оставьте выделение агентов обоим этапам и обе секции очистки на месте.
Если сборка ещё выполняется или находится в очереди, дождитесь окончательного состояния перед проверкой. Если случайная правка вызвала другую ошибку, восстановите исходный скрипт по конфигурации ниже, сохраните и запустите один раз, чтобы увидеть ожидаемый сбой отсутствующего файла:
pipeline {
agent none
stages {
stage('Prepare photos') {
agent { label 'photo-imaging' }
steps {
deleteDir()
sh '/opt/fieldlight/prepare-photos --width 320'
}
post {
always { deleteDir() }
}
}
stage('Pack collection') {
agent { label 'photo-packing' }
steps {
deleteDir()
sh '/opt/fieldlight/pack-photos'
archiveArtifacts artifacts: 'photo-pack.zip', fingerprint: true
}
post {
always { deleteDir() }
}
}
}
}
Сохраните неуспешный запуск и его консольный вывод. Переключитесь в Photo Desk и обновите страницу: она по-прежнему должна сообщать об отсутствии завершённой коллекции. Три полных оригинала остаются доступными. На следующем шаге вы передадите только небольшие подготовленные результаты, затем создадите сохраняемый архив.
Передайте фотографии и сохраните комплект
На этом шаге вы передадите шесть подготовленных файлов в рамках того же запуска Pipeline, сохраните готовый ZIP как артефакт и изучите его независимо. Начните в Jenkins, вернитесь в build-photo-pack, затем выберите Configure → Pipeline.
stash сохраняет небольшой выбранный набор файлов для дальнейшего использования в том же запуске Pipeline. Задайте ему имя и шаблон includes. Здесь prepared/** включает файлы подготовленной папки и вложенные файлы images/. Относительные пути сохраняются, поэтому восстановление stash создаёт prepared/ в принимающем рабочем каталоге. Помещайте в stash только эти небольшие производные файлы, а не оригиналы, среду выполнения Java или каталоги инструментов.
unstash восстанавливает этот именованный набор в рабочий каталог текущего агента. Его имя должно совпадать с предыдущим stash. Разместите его после начального deleteDir() принимающего этапа и до команды упаковки. Разместите stash после обработки и до очистки этапа изображений. Иначе файлы либо ещё не существуют, либо уже удалены, либо удаляются сразу после восстановления.
Stash — временная передача, а не архив для скачивания: обычно Jenkins удаляет его после завершения этого запуска. В отличие от него, archiveArtifacts сохраняет итоговый ZIP вместе со сборкой. Сохранение обеих операций делает передачу временной, а результат — пригодным для использования позднее.
Щёлкните внутри Script, выделите всё через Ctrl+A в Windows/Linux или Command+A в macOS и замените содержимое этой полной версией:
pipeline {
agent none
stages {
stage('Prepare photos') {
agent { label 'photo-imaging' }
steps {
deleteDir()
sh '/opt/fieldlight/prepare-photos --width 320'
stash name: 'prepared-photos', includes: 'prepared/**'
}
post {
always { deleteDir() }
}
}
stage('Pack collection') {
agent { label 'photo-packing' }
steps {
deleteDir()
unstash 'prepared-photos'
sh '/opt/fieldlight/pack-photos'
archiveArtifacts artifacts: 'photo-pack.zip', fingerprint: true
}
post {
always { deleteDir() }
}
}
}
}
Две новые строки — именованный stash и соответствующий unstash. Предоставленные команды обработки изображений и упаковки, правильные агенты, граница исходных файлов и очистка остаются на месте. Настройка archiveArtifacts сохраняет photo-pack.zip и регистрирует встроенный отпечаток файла; отпечаток отслеживает идентичность файла, а не согласование клиента или цифровую подпись.
Выберите Save, затем Build Now. Дождитесь завершения нового запуска с SUCCESS. Откройте его Console Output и прочитайте последовательность: image-studio подготавливает фотографии шириной 320 пикселей, Jenkins сообщает Stashed 6 file(s), рабочий каталог изображений очищается. Затем pack-studio восстанавливает stash, инструмент упаковки сообщает Packed 9 collection files into photo-pack.zip, а Jenkins сохраняет ZIP как артефакт и регистрирует его отпечаток перед очисткой рабочего каталога упаковки.
Если консоль сообщает No such saved stash, сравните оба имени stash и порядок действий, восстановите полный скрипт, сохраните и запустите снова. Если по-прежнему сообщается об отсутствующем подготовленном файле, проверьте, что шаблон includes равен prepared/**, а unstash идёт после принимающей очистки. Каждая новая сборка начинает новую передачу; stash предыдущей сборки не заменяет её. При синтаксической ошибке Groovy восстановите полный скрипт и сохраните его фигурные скобки, кавычки и запятые. Сохраняйте все неуспешные и успешные запуски; обычные ошибки не требуют сброса виртуальной машины.
На странице успешной сборки выберите артефакт photo-pack.zip и сохраните его. Распакуйте весь ZIP в новую папку на своём компьютере. Не открывайте только HTML-файл внутри программы просмотра архива: соседние файлы тоже нужно распаковать. Папка должна содержать:
index.html
styles.css
delivery.txt
captions.csv
preparation.json
contact-sheet.png
images/
garden-01.png
garden-02.png
garden-03.png
Откройте распакованный index.html в браузере. Галерея Fieldlight Studio должна отображать все три правильные фотографии сада и подписи к ним. Откройте каждую фотографию и вернитесь действием браузера Back. Выберите Open contact sheet, чтобы посмотреть настоящий обзор трёх фотографий, затем вернитесь в галерею действием браузера Back. Из распакованной папки откройте captions.csv, preparation.json и delivery.txt в текстовом редакторе; ссылки галереи указывают на эти же файлы, имена файлов в CSV должны указывать на реальные файлы images/, каждое уменьшенное изображение должно иметь размер 320 × 213 пикселей, а JSON — указывать garden с шириной 320. Заметки должны указывать фактические задание Jenkins, сборку и агента упаковки.

Полная галерея содержит три фотографии сада, ссылку на контактный лист и ссылки на реальные файлы подписей, сведений об изображениях и доставки. При открытии распакованной копии держите соседние файлы вместе.
Сохраняйте полную распакованную папку вместе. Откройте её в новом приватном окне браузера, не используя Photo Desk: все изображения, оформление и ссылки на файлы должны по-прежнему работать из локальных файлов. Галерея не использует удалённые шрифты или подстановку онлайн-изображений. Сломанное локальное изображение означает, что реальный файл результата отсутствует или расположен неверно; распакуйте весь исходный ZIP в новую папку вместо копирования недостающих файлов с исходного сайта.
Переключитесь в Photo Desk, обновите страницу и выберите Open prepared collection. Этот вид читает файлы из вашего фактического встроенного архива Jenkins. Изучите фотографии и вложения, затем вернитесь действием браузера Back и выберите Download complete ZIP. Его байты должны совпадать со скачанным артефактом Jenkins. Вернитесь к Photo Desk и подтвердите, что все три полных оригинала остались без изменений.
Наконец, переключитесь в Jenkins. Снова откройте успешную сборку и убедитесь, что её артефакт по-прежнему можно скачать после очистки. Сохраните исходный запуск с отсутствующим файлом, всю историю, оригиналы, инструменты, подключения узлов и метки возможностей. Если вы снова измените скрипт, сохраните его и завершите новую успешную сборку перед проверкой. Теперь у вас настоящая передача между двумя агентами и полный сохранённый результат.
Резюме
Вы наблюдали независимые рабочие каталоги Jenkins, затем передали только необходимые результаты обработки фотографий через именованный stash и соответствующий unstash в одном запуске. Агент упаковки создал полную локальную галерею, а встроенное сохранение артефактов оставило её пригодной для использования после очистки рабочих каталогов обоих этапов. Независимое самостоятельное задание меняет коллекцию и ширину, повторно используя изученные механизмы.



