Compare commits
2 Commits
358ae2153c
...
2e0ffdec18
Author | SHA1 | Date | |
---|---|---|---|
2e0ffdec18 | |||
cb141cc4e7 |
1
morozov_vladimir_lab_2/.gitignore
vendored
Normal file
1
morozov_vladimir_lab_2/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.idea
|
23
morozov_vladimir_lab_2/docker-compose.yml
Normal file
23
morozov_vladimir_lab_2/docker-compose.yml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
version: '3'
|
||||||
|
# Объявляем сервисы
|
||||||
|
services:
|
||||||
|
|
||||||
|
worker_0: # сервис приложения для генерации данных
|
||||||
|
build: ./worker_0/ # путь к его докер файлу
|
||||||
|
volumes: # монтируем том
|
||||||
|
- data:/usr/src/myData
|
||||||
|
worker_1: # сервис 1го приложения
|
||||||
|
build: ./worker_1/ # путь к его докер файлу
|
||||||
|
volumes: # монтируем том
|
||||||
|
- data:/usr/src/myData
|
||||||
|
depends_on: # объявляем, что данный сервис запуститься только после запуска сервиса worker_0
|
||||||
|
worker_0:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
worker_2: # сервис 2го приложения
|
||||||
|
build: ./worker_2/ # путь к его докер файлу
|
||||||
|
volumes: # монтируем том
|
||||||
|
- data:/usr/src/myData
|
||||||
|
depends_on:
|
||||||
|
- worker_1 # объявляем, что данный сервис запуститься только после запуска сервиса worker_1
|
||||||
|
volumes: # объявляем тома
|
||||||
|
data:
|
45
morozov_vladimir_lab_2/readme.md
Normal file
45
morozov_vladimir_lab_2/readme.md
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# Лабораторная работа №2 - разработка простейшего распределенного приложения
|
||||||
|
|
||||||
|
## Разработанные приложения
|
||||||
|
- worker_0 - программа, которая создаст папки /var/data и сгенерирует в них изначальные данные
|
||||||
|
- worker_1 - 1я программа. Вариант 4: Формирует файл /var/result/data.txt так, что каждая строка файла - количество символов в именах файлов из каталога /var/data
|
||||||
|
- worker_2 - 2я программа. Вариант 2: Ищет наименьшее число из файла /var/data/data.txt и сохраняет его третью степень в /var/result/result.txt
|
||||||
|
|
||||||
|
Все программы были разработаны на языке Python.
|
||||||
|
|
||||||
|
## DockerFile
|
||||||
|
Для каждого приложения был создан отдельный dockerfile, который позволяет нам создавать свои образы, на основе которых будут созданы контейнеры. Все файлы лежат в папках программ, описание имеет только dockerfile для `worker_0`, так как по структуре все они одинаковы
|
||||||
|
|
||||||
|
## DockerCompose
|
||||||
|
Для того, чтобы запустить все программы нам нужно создать `docker-compose.yml`, в котором определим как запускать наши сервисы. В отличие от 1й л/р в `docker-compose.yml` были добавлены команды `build`, которая позволяет нам указать путь до dockerfile нашего приложения, а также `depends_on`, которая позволяет установить порядок запусков сервисов. Более подробное описание `docker-compose.yml` находится в нем самом в качестве комментариев
|
||||||
|
|
||||||
|
## Как запустить
|
||||||
|
Для того, чтобы запустить наше распределенное приложение нужно выполнить несколько шагов
|
||||||
|
1) Запустить докер приложение. Я использую doker desktop.
|
||||||
|
2) Открыть терминал
|
||||||
|
3) перейти в папку, в которой лежит `docker-compose.yml`. Сделать это можно с помощью команды `cd`
|
||||||
|
3) Запустить команду:
|
||||||
|
```
|
||||||
|
docker-compose up --build
|
||||||
|
```
|
||||||
|
После этого будут созданые контейнеры, которые построены на основе образов, указанных в `docker-compose.yml`. В терминале будут отабражено следующее:
|
||||||
|
```[+] Running 5/5
|
||||||
|
✔ Network morozov_vladimir_lab_2_default Created
|
||||||
|
✔ Volume "morozov_vladimir_lab_2_data" Created
|
||||||
|
✔ Container morozov_vladimir_lab_2-worker_0-1 Created
|
||||||
|
✔ Container morozov_vladimir_lab_2-worker_1-1 Created
|
||||||
|
✔ Container morozov_vladimir_lab_2-worker_2-1 Created
|
||||||
|
Attaching to worker_0-1, worker_1-1, worker_2-1
|
||||||
|
worker_0-1 | Start generating data
|
||||||
|
worker_0-1 | Create dir and files
|
||||||
|
worker_0-1 exited with code 0
|
||||||
|
worker_1-1 | Start first app
|
||||||
|
worker_1-1 | Create dir
|
||||||
|
worker_1-1 exited with code 0
|
||||||
|
worker_2-1 | Start second app
|
||||||
|
worker_2-1 | 0
|
||||||
|
worker_2-1 exited with code 0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Запись тестирования
|
||||||
|
Работа приложения представлена в [видео](https://disk.yandex.ru/i/0KAySyP5eaBg0g)
|
55
morozov_vladimir_lab_2/worker_0/app.py
Normal file
55
morozov_vladimir_lab_2/worker_0/app.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import os.path
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
# программа для создания первоначальных данных
|
||||||
|
|
||||||
|
# кол-во создаваемых файлов
|
||||||
|
count_files = 10
|
||||||
|
# буквы для создани случайных названий файлов
|
||||||
|
letters = "a b c d e f g h i j k l m n o p q r s t u v w x y z"
|
||||||
|
|
||||||
|
# создание папки /var/data
|
||||||
|
def create_dir(path):
|
||||||
|
os.makedirs(f"{path}/var/data")
|
||||||
|
|
||||||
|
# заполнение файлов случайным кол-вом строк, состоящих из случайных чисел
|
||||||
|
def create_strings(file):
|
||||||
|
count_strings = random.randint(5,10)
|
||||||
|
for i in range(0, count_strings):
|
||||||
|
for _ in range(0,10):
|
||||||
|
file.write(f"{random.randint(0, 100)} ")
|
||||||
|
if i != count_strings-1:
|
||||||
|
file.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
# Создание файлов с данными
|
||||||
|
def create_files(path):
|
||||||
|
arr = letters.split()
|
||||||
|
with open(f"{path}/var/data/data.txt", 'w') as f:
|
||||||
|
create_strings(f)
|
||||||
|
for i in range(1, count_files):
|
||||||
|
name = ""
|
||||||
|
for _ in range(0, random.randint(3, 10)):
|
||||||
|
name += arr[random.randint(0, len(arr)-1)]
|
||||||
|
with open(f"{path}/var/data/{name}{i}.txt",'w') as f:
|
||||||
|
create_strings(f)
|
||||||
|
|
||||||
|
# проверка на наличие папок и файлов
|
||||||
|
def check_dir(path):
|
||||||
|
if os.path.exists(f"{path}/var/data"):
|
||||||
|
if os.path.isfile(f"{path}/var/data/data.txt") and len(os.listdir(f"{path}/var/data")) >= count_files:
|
||||||
|
print("Already create")
|
||||||
|
else:
|
||||||
|
print("Create files")
|
||||||
|
create_files(path)
|
||||||
|
else:
|
||||||
|
print("Create dir and files")
|
||||||
|
create_dir(path)
|
||||||
|
create_files(path)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__' :
|
||||||
|
print("Start generating data")
|
||||||
|
path = sys.argv[1]
|
||||||
|
check_dir(path)
|
||||||
|
|
8
morozov_vladimir_lab_2/worker_0/dockerfile
Normal file
8
morozov_vladimir_lab_2/worker_0/dockerfile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# объявляем базовый образ, на основе которого будет все построено
|
||||||
|
FROM "python:3.9-slim"
|
||||||
|
# назначаем основную рабочую директорию
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
# копируем содержимое текущей папке (скрипт питона) в контейнер, в основную рабочую папку
|
||||||
|
COPY . .
|
||||||
|
# при запуске образа выполняем команду запуска приложения
|
||||||
|
CMD [ "python", "./app.py", "/usr/src/myData"]
|
30
morozov_vladimir_lab_2/worker_1/app.py
Normal file
30
morozov_vladimir_lab_2/worker_1/app.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
# 1я программа.
|
||||||
|
# Вариант 4: Формирует файл /var/result/data.txt так,
|
||||||
|
# что каждая строка файла - количество символов в именах файлов из каталога /var/data
|
||||||
|
|
||||||
|
# Создание папки
|
||||||
|
def create_dir(path):
|
||||||
|
os.makedirs(f"{path}/var/result")
|
||||||
|
|
||||||
|
# Создание файла result и заполнение его
|
||||||
|
def create_file(path):
|
||||||
|
with open(f"{path}/var/result/data.txt", 'w') as f:
|
||||||
|
files = os.listdir(f"{path}/var/data")
|
||||||
|
for i, file in enumerate(files):
|
||||||
|
f.write(f"{file} - {len(file.replace('.txt', ''))}")
|
||||||
|
if i != len(files)-1:
|
||||||
|
f.write('\n')
|
||||||
|
|
||||||
|
# Проверка на наличие файла result
|
||||||
|
def check(path):
|
||||||
|
if not os.path.exists(f"{path}/var/result"):
|
||||||
|
print("Create dir")
|
||||||
|
create_dir(path)
|
||||||
|
create_file(path)
|
||||||
|
|
||||||
|
if __name__ == '__main__' :
|
||||||
|
print("Start first app")
|
||||||
|
path = sys.argv[1]
|
||||||
|
check(path)
|
4
morozov_vladimir_lab_2/worker_1/dockerfile
Normal file
4
morozov_vladimir_lab_2/worker_1/dockerfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
FROM "python:3.9-slim"
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
COPY . .
|
||||||
|
CMD [ "python", "./app.py", "/usr/src/myData"]
|
27
morozov_vladimir_lab_2/worker_2/app.py
Normal file
27
morozov_vladimir_lab_2/worker_2/app.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import sys
|
||||||
|
# 2я Программа
|
||||||
|
# Вариант 2: Ищет наименьшее число из файла /var/data/data.txt
|
||||||
|
# и сохраняет его третью степень в /var/result/result.txt
|
||||||
|
|
||||||
|
|
||||||
|
# Основной метод, в котором открываем файл data.txt, ищем в нем наименьшее число и записываем его степень в result
|
||||||
|
def work(path):
|
||||||
|
result = 0
|
||||||
|
with open(f"{path}/var/data/data.txt", 'r') as f:
|
||||||
|
strings = f.readlines()
|
||||||
|
min = int(strings[0].replace('\n','').split()[0])
|
||||||
|
for string in strings:
|
||||||
|
arr = string.replace('\n','').split()
|
||||||
|
for num in arr:
|
||||||
|
if int(num) <= min:
|
||||||
|
min = int(num)
|
||||||
|
result = int(min)**3
|
||||||
|
with open(f"{path}/var/result/result.txt", 'w') as f:
|
||||||
|
f.write(f"{result}")
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__' :
|
||||||
|
print("Start second app")
|
||||||
|
path = sys.argv[1]
|
||||||
|
work(path)
|
4
morozov_vladimir_lab_2/worker_2/dockerfile
Normal file
4
morozov_vladimir_lab_2/worker_2/dockerfile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
FROM "python:3.9-slim"
|
||||||
|
WORKDIR /usr/src/app
|
||||||
|
COPY . .
|
||||||
|
CMD [ "python", "./app.py", "/usr/src/myData"]
|
Loading…
Reference in New Issue
Block a user