Compare commits

..

1 Commits

Author SHA1 Message Date
205d361924 . 2024-12-15 16:56:11 +04:00
11 changed files with 253 additions and 0 deletions

View File

@ -0,0 +1,7 @@
# См. описание Dockerfile для первого приложения app_1
FROM python:3.9-slim
WORKDIR /app
COPY generate_files.py /app/
CMD ["python", "generate_files.py"]

View File

@ -0,0 +1,47 @@
# Лабораторная работа №2 - Разработка простейшего распределённого приложения
## Задание
* Разработать два приложения такие, что результат первого является исходными данными для второго.
* Изучить файлы сборки образов ```docker``` и разработать их для созданных приложений и правильно закоммитить решение
* Собрать файл ```docker-compose.yml``` для запуска приложений.
### Варианты задания:
 1. Первое приложение берёт из каталога /var/data случайный файл и перекладывает его в /var/result/data.txt
 2. Второе приложение сохраняет произведение первого и последнего числа из файла /var/result/data.txt в /var/result/result.txt
## Запуск работы программы
1. Убедиться, что установлены необходимые технологии:
- Docker: Платформа для контейнеризации приложений.
- Docker Compose: Инструмент для запуска много контейнерных приложений на основе `docker-compose.yaml`. Обычно поставляется вместе с Docker. Чтобы проверить, установлена ли утилита, нужно запустить команду:
```bash
docker-compose --version
```
2. В директории, где находится файл `docker-compose.yaml`, выполнить следующую команду для запуска всех сервисов:
```bash
docker-compose up --build
```
Эта команда сначала выполнит сборку, а затем запустит контейнеры.
3. После успешного запуска можно перейти в каталог проекта и увидеть папку data со сгенерированными файлами и папку result, в которой два текстовых файла:
- data.txt - файл, полученный после выполнения первой программы.
- result.txt -файл, полученный после выполнения второй программы.
## Описание работы:
1. **Генератор файлов**
generate_files.py, генерирует случайные файлы с числами и сохраняет их в папке data.
2. **Первое приложение**
app.py, случайным образом получает один файл из папки data и копирует его содержимое в result/data.txt.
3. **Второе приложение**
app.py, находит произведение первого и последнего чисел из result/data.txt и записывает в result/result.txt.
4. **Файла docker-compose.yml**
docker-compose.yml построчно описан в комментариях в коде.
Файл Docker построчно описан в коде на примере Docker первого сервиса app_1.
## Видео работы программы
https://disk.yandex.ru/i/CRj-ZMrHrZKvcA

View File

@ -0,0 +1,27 @@
import os
def multiply_first_and_last(input_file, output_file):
# Проверяем, существует файл data.txt
if not os.path.exists(input_file):
print(f"File {input_file} does not exist.")
return
# Считываем содержимое файла
with open(input_file, 'r') as f:
numbers = [int(line.strip()) for line in f.readlines()]
if numbers:
first_number = numbers[0]
last_number = numbers.pop()
result = first_number * last_number
# Записываем полученный результата в result.txt
with open(output_file, 'w') as f_out:
f_out.write(str(result))
print(f"Saved {first_number}х{last_number} to {output_file}")
else:
print(f"No numbers found in {input_file}")
if __name__ == "__main__":
multiply_first_and_last('/var/result/data.txt', '/var/result/result.txt')

View File

@ -0,0 +1,13 @@
# Указываем базовый образ для Docker
#slim означает, что это более компактный, содержащий только основные компоненты Python, что уменьшает размер образа
FROM python:3.9-slim
# Устанавливаем рабочую директорию внутри контейнера Docker в /app.
# Все последующие команды в Dockerfile будут выполняться в этой директории.
WORKDIR /app
# Перемещаем файл в контейнер
COPY app.py /app/
# Указываем команду, которая будет выполняться при запуске контейнера
CMD ["python", "app.py"]

View File

@ -0,0 +1,28 @@
import os
import random
def find_shortest_filename(source_dir, result_file):
# Проверяем есть ли папка result, если нет - создаем
result_dir = os.path.dirname(result_file)
if not os.path.exists(result_dir):
os.makedirs(result_dir)
print(f"Created directory {result_dir}")
files = [f for f in os.listdir(source_dir) if os.path.isfile(os.path.join(source_dir, f))]
if not files:
print(f"No files found in {source_dir}")
return
# Выбор случайного файла
random_file = random.choice(files)
random_file_path = os.path.join(source_dir, random_file)
# Копируем файл в result/data.txt., если файл уже есть перезаписываем
with open(random_file_path, 'r') as f_in, open(result_file, 'w') as f_out:
f_out.write(f_in.read())
print(f"Moved {random_file} to {result_file}")
if __name__ == "__main__":
find_shortest_filename('/var/data', '/var/result/data.txt')

View File

@ -0,0 +1,8 @@
# См. описание Dockerfile для первого приложения app_1
FROM python:3.9-slim
WORKDIR /app
COPY app.py /app/
CMD ["python", "app.py"]

View File

@ -0,0 +1,27 @@
import os
def multiply_first_and_last(input_file, output_file):
# Проверяем, существует файл data.txt
if not os.path.exists(input_file):
print(f"File {input_file} does not exist.")
return
# Считываем содержимое файла
with open(input_file, 'r') as f:
numbers = [int(line.strip()) for line in f.readlines()]
if numbers:
first_number = numbers[0]
last_number = numbers.pop()
result = first_number * last_number
# Записываем полученный результата в result.txt
with open(output_file, 'w') as f_out:
f_out.write(str(result))
print(f"Saved {first_number}х{last_number} to {output_file}")
else:
print(f"No numbers found in {input_file}")
if __name__ == "__main__":
multiply_first_and_last('/var/result/data.txt', '/var/result/result.txt')

View File

@ -0,0 +1,27 @@
services:
# сервис, отвечающий за генерацию файлов
generator:
build:
context: ./generator # путь к директории с Dockerfile для генерации
volumes:
- ./data:/var/data # монтирование локальной директории ./data в директорию /var/data внутри контейнера
entrypoint: python generate_files.py # запуск скрипта генерации
# Первый сервис, получающий случайный файл
app_1:
build:
context: ./app_1 # путь к директории с Dockerfile для первого сервиса
volumes:
- ./data:/var/data # Монтирование локальной директории data в /var/data
- ./result:/var/result # Монтирование локальной директории data в /var/result
depends_on: # Указывает, что первый сервис зависит от генератора
- generator
# Второй сервис, считающий произведение первого и последнего чисел из файла
app_2:
build:
context: ./app_2 # путь к директории с Dockerfile для второго сервиса
volumes:
- ./result:/var/result # Монтирование локальной директории data в /var/result
depends_on: # Указывает, что второй сервис зависит от первого
- app_1

View File

@ -0,0 +1,31 @@
import os
import random
import string
def generate_random_filename(length):
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length)) + '.txt'
def generate_data_files(directory, num_files, min_lines, max_lines):
# Создание директории, если таковой не существует
if not os.path.exists(directory):
os.makedirs(directory)
# Проверка, пустая ли директория
if os.listdir(directory):
print(f"{directory} is not empty, skipping file generation.")
return
# Генерация файлов
for _ in range(num_files):
file_name = generate_random_filename(random.randint(1, 20))
file_path = os.path.join(directory, file_name)
with open(file_path, 'w') as f:
num_lines = random.randint(min_lines, max_lines)
for _ in range(num_lines):
f.write(f"{random.randint(1, 1000)}\n")
print(f"Generated file: {file_path}")
if __name__ == "__main__":
generate_data_files('/var/data', num_files=random.randint(5, 15), min_lines=1, max_lines=50)

View File

@ -0,0 +1,7 @@
# См. описание Dockerfile для первого приложения app_1
FROM python:3.9-slim
WORKDIR /app
COPY generate_files.py /app/
CMD ["python", "generate_files.py"]

View File

@ -0,0 +1,31 @@
import os
import random
import string
def generate_random_filename(length):
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=length)) + '.txt'
def generate_data_files(directory, num_files, min_lines, max_lines):
# Создание директории, если таковой не существует
if not os.path.exists(directory):
os.makedirs(directory)
# Проверка, пустая ли директория
if os.listdir(directory):
print(f"{directory} is not empty, skipping file generation.")
return
# Генерация файлов
for _ in range(num_files):
file_name = generate_random_filename(random.randint(1, 20))
file_path = os.path.join(directory, file_name)
with open(file_path, 'w') as f:
num_lines = random.randint(min_lines, max_lines)
for _ in range(num_lines):
f.write(f"{random.randint(1, 1000)}\n")
print(f"Generated file: {file_path}")
if __name__ == "__main__":
generate_data_files('/var/data', num_files=random.randint(5, 15), min_lines=1, max_lines=50)