From 529b2c87827ec645a9ceed231cff109370f2dc98 Mon Sep 17 00:00:00 2001 From: Kseniy <––ƒ––iputilin201@gmail.com> Date: Sun, 8 Dec 2024 20:55:28 +0400 Subject: [PATCH] kurushina_ksenia_lab_2 --- kurushina_ksenia_lab_2/README.md | 75 +++++++++++++++++++ kurushina_ksenia_lab_2/docker-compose.yml | 32 ++++++++ kurushina_ksenia_lab_2/generate/Dockerfile | 6 ++ .../generate/generate_data.py | 18 +++++ kurushina_ksenia_lab_2/work_one/Dockerfile | 6 ++ kurushina_ksenia_lab_2/work_one/main.py | 24 ++++++ kurushina_ksenia_lab_2/work_two/Dockerfile | 6 ++ kurushina_ksenia_lab_2/work_two/main.py | 18 +++++ 8 files changed, 185 insertions(+) create mode 100644 kurushina_ksenia_lab_2/README.md create mode 100644 kurushina_ksenia_lab_2/docker-compose.yml create mode 100644 kurushina_ksenia_lab_2/generate/Dockerfile create mode 100644 kurushina_ksenia_lab_2/generate/generate_data.py create mode 100644 kurushina_ksenia_lab_2/work_one/Dockerfile create mode 100644 kurushina_ksenia_lab_2/work_one/main.py create mode 100644 kurushina_ksenia_lab_2/work_two/Dockerfile create mode 100644 kurushina_ksenia_lab_2/work_two/main.py diff --git a/kurushina_ksenia_lab_2/README.md b/kurushina_ksenia_lab_2/README.md new file mode 100644 index 0000000..2517d1b --- /dev/null +++ b/kurushina_ksenia_lab_2/README.md @@ -0,0 +1,75 @@ +# Лабораторная работа №2 - Разработка простого распределённого приложения + +## Описание задания + +**Цель**: Создать два приложения, где результаты работы первого используются в качестве входных данных для второго. + +**Основные задачи**: +1. Разработать два приложения: + - **app_one**: Находит файл с максимальным количеством строк в папке `/var/data` и копирует его содержимое в `/var/result/data.txt`. + - **app_two**: Определяет минимальное число в файле `/var/result/data.txt` и записывает его третью степень в `/var/result/result.txt`. +2. Настроить Docker-образ для каждого приложения. +3. Подготовить `docker-compose.yml` для управления обоими приложениями. +4. Организовать монтирование директорий для обмена данными между контейнерами. +5. Настроить `.gitignore` для исключения ненужных файлов при коммитах. + +## Детали задания + +### **Описание приложений** + +1. **work_one**: + - Анализирует содержимое каталога `/var/data`, определяя файл с наибольшим количеством строк. + - Копирует содержимое найденного файла в `/var/result/data.txt`. + +2. **work_two**: + - Читает содержимое файла `/var/result/data.txt`. + - Находит минимальное число в файле и возводит его в третью степень. + - Сохраняет результат в `/var/result/result.txt`. + +### **Требования к реализации**: +- **Docker**: Используется для контейнеризации приложений. +- **Docker Compose**: Позволяет запускать несколько контейнеров через единый файл `docker-compose.yml`. + +### **Сборка и запуск приложения**: +Для сборки и запуска контейнеров выполните команду в директории с `docker-compose.yml`: + +```bash +docker-compose up --build +``` + +Эта команда: +1. Создает Docker-образы для всех сервисов. +2. Запускает контейнеры. +3. Выполняет обработку данных приложениями последовательно. + +### **Результаты работы**: +После завершения работы контейнеров: +- Файл **data.txt** в папке `/var/result` будет содержать данные из файла с максимальным количеством строк из папки `/var/data`. +- Файл **result.txt** в той же папке сохранит третью степень минимального числа из файла **data.txt**. + +## Детали реализации + +### **Программы**: +1. **work_one/main.py**: + - Осуществляет поиск файла с наибольшим количеством строк. + - Сохраняет его содержимое в `/var/result/data.txt`. + +2. **work_two/main.py**: + - Читает содержимое файла `/var/result/data.txt`. + - Находит минимальное число, возводит его в третью степень и сохраняет результат в `/var/result/result.txt`. + +### **Генерация тестовых данных**: +Скрипт **generate.py** используется для создания случайных данных: +- Создает несколько файлов с целыми числами в папке `/var/data`. +- Каждый файл содержит случайные данные, которые обрабатываются первым приложением. + +### **Dockerfile**: +Для каждого приложения разработан отдельный `Dockerfile`, где описаны шаги по сборке образов и запуску соответствующих программ. + +## Итог + +В ходе работы было создано распределённое приложение, использующее Docker и Docker Compose для последовательной обработки данных в двух контейнерах. + +## Видео + +https://cloud.mail.ru/public/H89o/DGmReqSk9 \ No newline at end of file diff --git a/kurushina_ksenia_lab_2/docker-compose.yml b/kurushina_ksenia_lab_2/docker-compose.yml new file mode 100644 index 0000000..7c39692 --- /dev/null +++ b/kurushina_ksenia_lab_2/docker-compose.yml @@ -0,0 +1,32 @@ +version: '3.8' + +services: + generate: + build: + context: ./generate + volumes: + - ./data:/var/data + command: python generate_data.py + + work_one: + build: + context: ./work_one + depends_on: + - generate + volumes: + - ./data:/var/data + - ./result:/var/result + command: python main.py + + work_two: + build: + context: ./work_two + depends_on: + - work_one + volumes: + - ./result:/var/result + command: python main.py + +volumes: + data: + result: diff --git a/kurushina_ksenia_lab_2/generate/Dockerfile b/kurushina_ksenia_lab_2/generate/Dockerfile new file mode 100644 index 0000000..a092849 --- /dev/null +++ b/kurushina_ksenia_lab_2/generate/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.9-slim + +WORKDIR /app +COPY generate_data.py . + +CMD ["python", "generate_data.py"] diff --git a/kurushina_ksenia_lab_2/generate/generate_data.py b/kurushina_ksenia_lab_2/generate/generate_data.py new file mode 100644 index 0000000..1c73dcd --- /dev/null +++ b/kurushina_ksenia_lab_2/generate/generate_data.py @@ -0,0 +1,18 @@ +import os +import random + +OUTPUT_DIR = '/var/data' +NUM_FILES = 5 +MAX_LINES = 100 +MAX_VALUE = 1000 + +os.makedirs(OUTPUT_DIR, exist_ok=True) + +for i in range(NUM_FILES): + file_path = os.path.join(OUTPUT_DIR, f"file_{i}.txt") + with open(file_path, 'w') as f: + num_lines = random.randint(1, MAX_LINES) + for _ in range(num_lines): + f.write(f"{random.randint(1, MAX_VALUE)}\n") + +print(f"Generated {NUM_FILES} files in {OUTPUT_DIR}.") diff --git a/kurushina_ksenia_lab_2/work_one/Dockerfile b/kurushina_ksenia_lab_2/work_one/Dockerfile new file mode 100644 index 0000000..f6a1d3f --- /dev/null +++ b/kurushina_ksenia_lab_2/work_one/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.9-slim + +WORKDIR /app +COPY main.py . + +CMD ["python", "main.py"] diff --git a/kurushina_ksenia_lab_2/work_one/main.py b/kurushina_ksenia_lab_2/work_one/main.py new file mode 100644 index 0000000..185eee3 --- /dev/null +++ b/kurushina_ksenia_lab_2/work_one/main.py @@ -0,0 +1,24 @@ +import os + +INPUT_DIR = '/var/data' +OUTPUT_FILE = '/var/result/data.txt' + +os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True) + +max_lines = -1 +max_file = None + +for file_name in os.listdir(INPUT_DIR): + file_path = os.path.join(INPUT_DIR, file_name) + if os.path.isfile(file_path): + with open(file_path, 'r') as f: + num_lines = sum(1 for _ in f) + if num_lines > max_lines: + max_lines = num_lines + max_file = file_path + +if max_file: + with open(max_file, 'r') as source, open(OUTPUT_FILE, 'w') as destination: + destination.write(source.read()) + +print(f"Copied content from {max_file} to {OUTPUT_FILE}.") diff --git a/kurushina_ksenia_lab_2/work_two/Dockerfile b/kurushina_ksenia_lab_2/work_two/Dockerfile new file mode 100644 index 0000000..f6a1d3f --- /dev/null +++ b/kurushina_ksenia_lab_2/work_two/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.9-slim + +WORKDIR /app +COPY main.py . + +CMD ["python", "main.py"] diff --git a/kurushina_ksenia_lab_2/work_two/main.py b/kurushina_ksenia_lab_2/work_two/main.py new file mode 100644 index 0000000..3fd40cc --- /dev/null +++ b/kurushina_ksenia_lab_2/work_two/main.py @@ -0,0 +1,18 @@ +import os + +INPUT_FILE = '/var/result/data.txt' +OUTPUT_FILE = '/var/result/result.txt' + +os.makedirs(os.path.dirname(OUTPUT_FILE), exist_ok=True) + +with open(INPUT_FILE, 'r') as f: + numbers = [int(line.strip()) for line in f if line.strip().isdigit()] + +if numbers: + min_number = min(numbers) + result = min_number ** 3 + with open(OUTPUT_FILE, 'w') as f: + f.write(str(result)) + print(f"The cube of the smallest number ({min_number}) is {result}. Saved to {OUTPUT_FILE}.") +else: + print("No valid numbers found in the input file.") -- 2.25.1