CS 5113 and 4113 Fall 21

Logo

This is the web page for Fall 2021 Distributed Operation Systems at the University of Oklahoma.

View the Project on GitHub oudalab/cs5113fa21

CS [4|5]113 Fall 2021

Distributed Operating Systems

Assignment 2

In this course, we have discussed how machines communicate with each other. Several issues arise while managing communication between nodes. For this assignment, you will build a system to demonstrate client-server communication.

Description

The primary participants will be three machines. One server machine and two clients, hereinafter called Alice and Bob. The server will generate a secret random positive integer less than fifty (and, less than 100,000 for graduate students) and allow Alice and Bob to make guesses for it. It will announce the winner if either Alice or Bob guess the number correctly. The winner should then stop guessing and let the other client player guess till they figure out the server’s secret number as well. When both Alice and Bob have successfully guessed the server’s secret number, all three machines (server, Alice and Bob) should gracefully exit and power-down.

If either of the client’s guess is smaller than the secret number then the server should communicate back a “low” signal. Inversely, if the guess is greater than the secret then the server should respond with a “high” signal. The client machines will then use this information to make the next guess and so forth.

Libraries and Containers

You will be using an appropriate programming language with the following software tools,

  1. Docker
  2. gRPC
  3. Protocol Buffers

I’ll give you some examples in Python 3.

Examples and Guides

You may install Docker on GNU/Linux by running:

sudo apt install docker.io
sudo systemctl enable --now docker
sudo usermod -aG docker myusername

Exiting the console, log-out and log back in.

The directory tree under your code-directory should look like this,

.
├── docker-compose.yml
├── Dockerfile
├── guessing_game.proto
├── node.py
└── requirements.txt

0 directories, 5 files

Assuming you have a python file called node.py, bellow is an example Dockerfile.

FROM ubuntu:rolling

MAINTAINER harry@hogwarts.edu

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
    && localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8

RUN apt-get update && \
    apt-get upgrade -y \
    && apt-get install -y python3-pip ipython3

RUN apt-get install -y emacs nmap iputils-ping ssh netcat htop slurm net-tools

ENV GRPC_PYTHON_VERSION 1.15.0

RUN apt-get install -y libprotoc-dev protobuf-compiler

RUN python3 -m pip install --upgrade pip && python3 -m pip install click grpcio grpcio-tools

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Build python stuff
COPY requirements.txt /usr/src/app/
RUN pip install --no-cache-dir -r requirements.txt
COPY . /usr/src/app

# Create the protobuf files
# RUN protoc --python_out=. guessing_game.proto
# Code below works similarly
RUN python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. guessing_game.proto

EXPOSE 22
EXPOSE 80
EXPOSE 50050-50100

# Unbuffer to see logs with docker logs <containername>
ENV PYTHONUNBUFFERED=1

# Run the node
CMD ["python3", "node.py"]

You’ll also need a docker-compose.yml,

version: '3.7'

services:
  server:
    build: .
    hostname: server
    container_name: Server
    networks:
      - default
  client1:
    build: .
    hostname: alice
    container_name: Alice
    networks:
      - default
  client2:
    build: .
    hostname: bob
    container_name: Bob
    networks:
      - default

networks:
  default:
    driver: bridge

You may setup the protocol buffer definitions in a file looking like this,

syntax = "proto3";

package guessing_game;


service GuessingGame { // service ran on the server
  rpc reply (Guess) returns (Feedback) {}
  rpc tell_name (Name) returns (Name) {}
}

message Guess {
  // Fill me.
}

message Feedback {
  // Fill me.
}

message Name {
  // Fill me.
}

The requirements.txt maybe empty.

To spin up the server and clients:

docker-compose up --build

To tear down the machines:

docker-compose down

Submission

.
├── code
│   ├── docker-compose.yml
│   ├── Dockerfile
│   ├── guessing_game.proto
│   ├── node.py
│   └── requirements.txt
├── COLLABORATORS
├── media
│   └── demo.gif
└── readme.md

2 directories, 8 files

Given above is a possible project structure. The collaborators file should contain a comma-separated list describing who you worked with and text description describing the nature of the collaboration. This information could be listed in three fields as in the example is below:

Christan Grant, cgrant@ou.edu, Instructor of CS [4|5]113.
https://docs.docker.com/engine/reference/builder/#env, Stuck at tzdata prompt during build.
https://grpc.github.io/grpc/python/, GRPC Documentation.
https://github.com/grpc/grpc/tree/v1.20.0/examples/python/helloworld, hello-world example.

The readme.md file should contain a walk through of your node.py and other source code you may write including a demo.gif at the top demonstrating the running of the three machines playing the guessing game described above. Here is an example gif,

guessing

Submit all source code to a private github repository named cs4113fa21-assignment2 or cs5113fa21-assignment2. Submit a link to the private repository to Canvas. Also, you must add @cegme and @simurgh9 as collaborators to the repository. Code must accessible by the instructor and tashfeen to receive any credit. The video/annotated .gif should also be uploaded.

This is project may not be done in groups. Any code copying is subject to the university’s academic dishonesty policy. Any websites or discussion should be added to a COLLABORATORS file.