diff --git a/nikolaeva_yana_lab_2/ app_one/Dockerfile b/nikolaeva_yana_lab_2/ app_one/Dockerfile new file mode 100644 index 0000000..5378828 --- /dev/null +++ b/nikolaeva_yana_lab_2/ app_one/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . /app + +CMD ["python", "main.py"] diff --git a/nikolaeva_yana_lab_2/ app_one/main.py b/nikolaeva_yana_lab_2/ app_one/main.py new file mode 100644 index 0000000..1b2d430 --- /dev/null +++ b/nikolaeva_yana_lab_2/ app_one/main.py @@ -0,0 +1,38 @@ +import os + +def get_file_with_most_lines(directory): + max_lines = 0 + target_file = "" + + for filename in os.listdir(directory): + filepath = os.path.join(directory, filename) + if os.path.isfile(filepath): + with open(filepath, 'r') as f: + line_count = sum(1 for _ in f) + if line_count > max_lines: + max_lines = line_count + target_file = filename + + return target_file + +def copy_file(src_directory, dest_directory, filename): + src_filepath = os.path.join(src_directory, filename) + dest_filepath = os.path.join(dest_directory, 'data.txt') + + os.makedirs(dest_directory, exist_ok=True) + + with open(src_filepath, 'r') as src_file: + with open(dest_filepath, 'w') as dest_file: + dest_file.write(src_file.read()) + +def main(): + src_directory = '/var/data' + dest_directory = '/var/result' + + target_file = get_file_with_most_lines(src_directory) + if target_file: + copy_file(src_directory, dest_directory, target_file) + print(f"File {target_file} copied to {dest_directory}/data.txt") + +if __name__ == "__main__": + main() diff --git a/nikolaeva_yana_lab_2/README.md b/nikolaeva_yana_lab_2/README.md new file mode 100644 index 0000000..3863c28 --- /dev/null +++ b/nikolaeva_yana_lab_2/README.md @@ -0,0 +1,77 @@ +# Лабораторная работа №2 — Создание простейшего распределённого приложения + +## Цель работы + +Разработать два приложения, которые взаимодействуют следующим образом: результат работы первого приложения становится входными данными для второго. + +## Поставленные задачи + +1. **Разработка приложений**: + - **app_one**: Определяет файл с максимальным количеством строк в каталоге `/var/data` и копирует его содержимое в `/var/result/data.txt`. + - **app_two**: Анализирует файл `/var/result/data.txt`, находит наименьшее число и записывает его третью степень в `/var/result/result.txt`. +2. Создать Dockerfile для каждого приложения. +3. Настроить `docker-compose.yml` для совместного запуска приложений. +4. Реализовать монтирование директорий для передачи данных между контейнерами. +5. Организовать репозиторий с использованием `.gitignore` для исключения ненужных файлов. + +## Детализация заданий + +### Приложения + +1. **app_one**: + - Находит файл с наибольшим количеством строк в каталоге `/var/data`. + - Копирует содержимое этого файла в `/var/result/data.txt`. + +2. **app_two**: + - Читает файл `/var/result/data.txt`. + - Определяет наименьшее число в файле, возводит его в третью степень и сохраняет результат в `/var/result/result.txt`. + +### Инструменты и требования + +1. **Docker**: Для контейнеризации приложений. +2. **Docker Compose**: Для управления многоконтейнерным приложением через файл `docker-compose.yml`. + +## Процесс сборки и запуска + +Для запуска приложений выполните следующую команду в директории с файлом `docker-compose.yml`: + +```bash +docker-compose up --build +``` + +Эта команда: +- Соберёт образы всех сервисов. +- Запустит контейнеры. +- Автоматически выполнит последовательную обработку данных. + +## Итоговые результаты + +После завершения работы приложений результат можно найти в каталоге `/var/result`: +- **data.txt** — копия файла с максимальным количеством строк из каталога `/var/data`. +- **result.txt** — результат возведения наименьшего числа из `data.txt` в третью степень. + +## Описание реализации + +### Скрипты + +1. **app_one/main.py**: + - Находит файл с максимальным количеством строк. + - Копирует его содержимое в `/var/result/data.txt`. + +2. **app_two/main.py**: + - Анализирует файл `/var/result/data.txt`, определяет минимальное число, возводит его в третью степень и записывает в `/var/result/result.txt`. + +3. **generate_data.py** (скрипт для генерации данных): + - Создаёт несколько файлов с случайными числами в каталоге `/var/data` для тестирования. + +### Dockerfile + +Каждое приложение имеет собственный Dockerfile с инструкциями по сборке образов на основе Python. + +## Заключение + +Реализовано распределённое приложение, использующее Docker для запуска контейнеров и Docker Compose для оркестрации. Решение обеспечивает автоматизированную обработку данных через два взаимосвязанных приложения. + +## Ссылка на видео + +https://cloud.mail.ru/public/qbRv/m3AAUZ2VT \ No newline at end of file diff --git a/nikolaeva_yana_lab_2/app_two/ Dockerfile b/nikolaeva_yana_lab_2/app_two/ Dockerfile new file mode 100644 index 0000000..5378828 --- /dev/null +++ b/nikolaeva_yana_lab_2/app_two/ Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . /app + +CMD ["python", "main.py"] diff --git a/nikolaeva_yana_lab_2/app_two/main.py b/nikolaeva_yana_lab_2/app_two/main.py new file mode 100644 index 0000000..4c2f88e --- /dev/null +++ b/nikolaeva_yana_lab_2/app_two/main.py @@ -0,0 +1,25 @@ +import os + +def get_largest_number_from_file(filepath): + with open(filepath, 'r') as f: + numbers = [int(line.strip()) for line in f.readlines()] + return max(numbers) + +def save_square_of_number(number, output_filepath): + result = number ** 2 + with open(output_filepath, 'w') as f: + f.write(str(result)) + +def main(): + input_filepath = '/var/result/data.txt' + output_filepath = '/var/result/result.txt' + + if os.path.exists(input_filepath): + largest_number = get_largest_number_from_file(input_filepath) + save_square_of_number(largest_number, output_filepath) + print(f"Largest number squared: {largest_number}^2 saved to {output_filepath}") + else: + print(f"Input file {input_filepath} not found!") + +if __name__ == "__main__": + main() diff --git a/nikolaeva_yana_lab_2/data_generator/Dockerfile b/nikolaeva_yana_lab_2/data_generator/Dockerfile new file mode 100644 index 0000000..b98495c --- /dev/null +++ b/nikolaeva_yana_lab_2/data_generator/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.9-slim + +WORKDIR /app + +COPY . /app + +CMD ["python", "generate_data.py"] diff --git a/nikolaeva_yana_lab_2/data_generator/generate_data.py b/nikolaeva_yana_lab_2/data_generator/generate_data.py new file mode 100644 index 0000000..e8f2db5 --- /dev/null +++ b/nikolaeva_yana_lab_2/data_generator/generate_data.py @@ -0,0 +1,29 @@ +import os +import random + + +def generate_random_files(directory, num_files, num_lines_per_file, min_value, max_value): + os.makedirs(directory, exist_ok=True) + + for i in range(num_files): + file_path = os.path.join(directory, f"file_{i + 1}.txt") + with open(file_path, 'w') as f: + for _ in range(num_lines_per_file): + random_number = random.randint(min_value, max_value) + f.write(f"{random_number}\n") + print(f"Generated file: {file_path}") + + +def main(): + data_directory = '/var/data' + num_files = 10 + num_lines_per_file = 12 + min_value = 1 + max_value = 100 + + generate_random_files(data_directory, num_files, num_lines_per_file, min_value, max_value) + print(f"Generated {num_files} files in {data_directory}") + + +if __name__ == "__main__": + main() diff --git a/nikolaeva_yana_lab_2/docker-compose.yml b/nikolaeva_yana_lab_2/docker-compose.yml new file mode 100644 index 0000000..872c5fd --- /dev/null +++ b/nikolaeva_yana_lab_2/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3' +services: + data_generator: + build: + context: ./data_generator + volumes: + - ./data:/var/data + app_one: + build: + context: ./app_one + volumes: + - ./data:/var/data + - ./result:/var/result + depends_on: + - data_generator + app_two: + build: + context: ./app_two + volumes: + - ./result:/var/result + depends_on: + - app_one