Compare commits
1 Commits
main
...
melnikov_i
Author | SHA1 | Date | |
---|---|---|---|
205d361924 |
7
melnikov_igor_lab_2/Dockerfile
Normal file
7
melnikov_igor_lab_2/Dockerfile
Normal 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"]
|
47
melnikov_igor_lab_2/README.md
Normal file
47
melnikov_igor_lab_2/README.md
Normal 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
|
27
melnikov_igor_lab_2/app.py
Normal file
27
melnikov_igor_lab_2/app.py
Normal 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')
|
13
melnikov_igor_lab_2/app_1/Dockerfile
Normal file
13
melnikov_igor_lab_2/app_1/Dockerfile
Normal 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"]
|
28
melnikov_igor_lab_2/app_1/app.py
Normal file
28
melnikov_igor_lab_2/app_1/app.py
Normal 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')
|
8
melnikov_igor_lab_2/app_2/Dockerfile
Normal file
8
melnikov_igor_lab_2/app_2/Dockerfile
Normal file
@ -0,0 +1,8 @@
|
||||
# См. описание Dockerfile для первого приложения app_1
|
||||
FROM python:3.9-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY app.py /app/
|
||||
|
||||
CMD ["python", "app.py"]
|
27
melnikov_igor_lab_2/app_2/app.py
Normal file
27
melnikov_igor_lab_2/app_2/app.py
Normal 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')
|
27
melnikov_igor_lab_2/docker-compose.yml
Normal file
27
melnikov_igor_lab_2/docker-compose.yml
Normal 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
|
31
melnikov_igor_lab_2/generate_files.py
Normal file
31
melnikov_igor_lab_2/generate_files.py
Normal 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)
|
7
melnikov_igor_lab_2/generator/Dockerfile
Normal file
7
melnikov_igor_lab_2/generator/Dockerfile
Normal 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"]
|
31
melnikov_igor_lab_2/generator/generate_files.py
Normal file
31
melnikov_igor_lab_2/generator/generate_files.py
Normal 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)
|
Loading…
Reference in New Issue
Block a user