diff --git a/turner_ilya_lab_2/.gitignore b/turner_ilya_lab_2/.gitignore new file mode 100644 index 0000000..645eb4a --- /dev/null +++ b/turner_ilya_lab_2/.gitignore @@ -0,0 +1,5 @@ +data/ +result/ +result_first/ +result_second/ +datagen.py \ No newline at end of file diff --git a/turner_ilya_lab_2/README.md b/turner_ilya_lab_2/README.md new file mode 100644 index 0000000..bcfb21f --- /dev/null +++ b/turner_ilya_lab_2/README.md @@ -0,0 +1,87 @@ +# Лабораторная работа №2 - Разработка простейшего распределенного приложения +## ПИбд-42 || Тюрнер Илья + +## Описание +В рамках данной лабораторной работы было создано два контейнера спростыми программами на python, соблюдающими условие: результат первой программы - это исходные данные второй программы. + +### Цель лабораторной работы +изучение техники создания простого распределённого приложения + +### 1. Варианты +Для обеих программ был выбран вариант 1. + +Вариант первой программы: +**1**. Ищет в каталоге /var/data файл с наибольшим количеством строк и перекладывает его в /var/result/data.txt. + +Вариант второй программы: +**1**. Ищет набольшее число из файла /var/data/data.txt и сохраняет его вторую степень в /var/result/result.txt. + +### 2. Dockerfile +Два Dockerfile имеют сходную структуру: + +```Dockerfile +#Берем базовый образ python +FROM python:3.12 + +#Устанавливаем рабочую директорию +WORKDIR /app + +#Копирум код в рабочую директорию +COPY main.py . + +#Задаем /var/data как монтируемый +VOLUME ["/var/data"] +#Задаем /var/result как монтируемый +VOLUME ["/var/result"] + +#Задаем команду для выполнения программы +CMD ["python", "main.py"] +``` + +### 3. Docker-compose + +`docker-compose.yml`: + +```yaml +services: + #Первая программа + first: + #Директория для сборки первой программы + build: ./WorkFirst/ + #Монтирование 2 каталогов из хост системы + volumes: + - ./data:/var/data + - ./result_first:/var/result + + #Вторая программа + second: + #Директория для сборки второй программы + build: ./WorkSecond/ + #Задание очередности запуска через depends_on + depends_on: + - first + #Монтирование 2 каталогов из хост системы + volumes: + - ./result_first:/var/data + - ./result_second:/var/result +``` + +### 4. Инструкция для работы +1. Клонирование репозитория: +``` +git clone <ссылка-на-репозиторий> +cd <папка репозитория> +cd <папка лабораторной работы> +``` + +2. Запуск контейнеров: +``` +docker compose up --build +``` + +3. Результаты: +Итог работы первой программы будет в папке `result_first`, а второй - в `result_second`. + +### Видео с демонстрацией работы: +Размещено на платформе VK видео +https://vk.com/video/@tyurner02?z=video303312410_456239076%2Fpl_303312410_-2 \ No newline at end of file diff --git a/turner_ilya_lab_2/WorkFirst/Dockerfile b/turner_ilya_lab_2/WorkFirst/Dockerfile new file mode 100644 index 0000000..798cfab --- /dev/null +++ b/turner_ilya_lab_2/WorkFirst/Dockerfile @@ -0,0 +1,16 @@ + #Берем базовый образ python + FROM python:3.12 + + #Устанавливаем рабочую директорию + WORKDIR /app + + #Копирум код в рабочую директорию + COPY main.py . + + #Задаем /var/data как монтируемый + VOLUME ["/var/data"] + #Задаем /var/result как монтируемый + VOLUME ["/var/result"] + + #Задаем команду для выполнения программы + CMD ["python", "main.py"] \ No newline at end of file diff --git a/turner_ilya_lab_2/WorkFirst/main.py b/turner_ilya_lab_2/WorkFirst/main.py new file mode 100644 index 0000000..ee3211b --- /dev/null +++ b/turner_ilya_lab_2/WorkFirst/main.py @@ -0,0 +1,81 @@ +import os +import random + +# Путь к каталогу для поиска файла с наибольшим кол-вом строк +CATALOG_PATH = "/var/data" + +# Путь до файла с результатом +RESULT_FILE = "/var/result/data.txt" + + +def find_file_with_most_lines(directory): + """Ищет файл с наибольшим количеством строк в заданном каталоге и его подкаталогах.""" + + file_with_most_lines = None + max_lines = 0 + + for root, _, files in os.walk(directory): + for file in files: + filepath = os.path.join(root, file) + + try: + with open(filepath, 'r', encoding='utf-8') as f: + line_count = sum(1 for _ in f) + + if line_count > max_lines: + max_lines = line_count + file_with_most_lines = (filepath, line_count) + + except (OSError, UnicodeDecodeError) as e: + print(f"Ошибка при обработке файла '{filepath}': {e}") + + return file_with_most_lines + + +def copy_file(first, second): + """Копирует содержимое файла first в файл second.""" + + try: + with open(second, "wb") as f_second, open(first, "rb") as f_first: + while chunk := f_first.read(4096): + f_second.write(chunk) + + print(f"Файл '{first}' успешно скопирован в '{second}'.") + + except Exception as e: + print(f"Ошибка при копировании файла '{first}': {e}") + + +def main(): + file_with_most_lines = find_file_with_most_lines(CATALOG_PATH) + + if file_with_most_lines: + first_path, _ = file_with_most_lines + second_path = RESULT_FILE + + copy_file(first_path, second_path) + + else: + print("Не найдены файлы") + + +def generate_random_numbers(filename, count): + """Функция генерирует случайные числа и записывает их в файл""" + + with open(filename, "w") as f: + for _ in range(count): + num = random.randint(0, 1000) + f.write(str(num) + "\n") + + print(f"Случайные числа успешно записаны в '{filename}'.") + + +if __name__ == "__main__": + generate_random_numbers("/var/data/data1.txt", 25) + generate_random_numbers("/var/data/data2.txt", 30) + generate_random_numbers("/var/data/data3.txt", 27) + generate_random_numbers("/var/data/data4.txt", 12) + generate_random_numbers("/var/data/data5.txt", 19) + print("Генерация файлов завершена") + + main() \ No newline at end of file diff --git a/turner_ilya_lab_2/WorkSecond/Dockerfile b/turner_ilya_lab_2/WorkSecond/Dockerfile new file mode 100644 index 0000000..798cfab --- /dev/null +++ b/turner_ilya_lab_2/WorkSecond/Dockerfile @@ -0,0 +1,16 @@ + #Берем базовый образ python + FROM python:3.12 + + #Устанавливаем рабочую директорию + WORKDIR /app + + #Копирум код в рабочую директорию + COPY main.py . + + #Задаем /var/data как монтируемый + VOLUME ["/var/data"] + #Задаем /var/result как монтируемый + VOLUME ["/var/result"] + + #Задаем команду для выполнения программы + CMD ["python", "main.py"] \ No newline at end of file diff --git a/turner_ilya_lab_2/WorkSecond/main.py b/turner_ilya_lab_2/WorkSecond/main.py new file mode 100644 index 0000000..dc65c59 --- /dev/null +++ b/turner_ilya_lab_2/WorkSecond/main.py @@ -0,0 +1,60 @@ +# Путь к файлу для чтения +DATA_FILE = "/var/data/data.txt" + +# Путь к файлу для записи +RESULT_FILE = "/var/result/result.txt" + + +def find_biggest_number(data_file): + """Поиск наибольшего числа в файле""" + + try: + with open(data_file, "r") as f: + numbers = [int(line.strip()) for line in f.readlines()] + + biggest_num = max(numbers) + return biggest_num + + except ValueError as e: + print(f"Ошибка преобразования строки: {e}") + + except Exception as e: + print(f"Ошибка чтения файла '{data_file}': {e}") + + return None + + +def square_number(num): + """Возвращает квадрат числа""" + + return num**2 + + +def write_result(result_file, result): + """Фиксирует результат в файл.""" + + try: + with open(result_file, "w") as f: + f.write(str(result)) + + print(f"Результат '{result}' успешно передан в '{result_file}'.") + + except Exception as e: + print(f"Ошибка фиксации результата в файл '{result_file}': {e}") + + +def main(): + biggest_num = find_biggest_number(DATA_FILE) + + if biggest_num is not None: + result = square_number(biggest_num) + + write_result(RESULT_FILE, result) + print(result) + + else: + print("Нет чисел в файле.") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/turner_ilya_lab_2/docker-compose.yml b/turner_ilya_lab_2/docker-compose.yml new file mode 100644 index 0000000..f2192d8 --- /dev/null +++ b/turner_ilya_lab_2/docker-compose.yml @@ -0,0 +1,21 @@ +services: + #Первая программа + first: + #Директория для сборки первой программы + build: ./WorkFirst/ + #Монтирование 2 каталогов из хост системы + volumes: + - ./data:/var/data + - ./result_first:/var/result + + #Вторая программа + second: + #Директория для сборки второй программы + build: ./WorkSecond/ + #Задание очередности запуска через depends_on + depends_on: + - first + #Монтирование 2 каталогов из хост системы + volumes: + - ./result_first:/var/data + - ./result_second:/var/result \ No newline at end of file