# Makefile

## Voraussetzungen

> Server-Admin kontaktieren

- Server: Public SSH-Key
- Client: Private SSH-Key
- Client: SSH-Config konfiguriert

<details>
<summary>Details anzeigen</summary>

Dieses Projekt sieht eine Kommunikation zwischen Client und Server mittels _SSH_ vor.
Aufgrund der höheren Sicherheit und einfacheren Bedienbarkeit sind _SSH-Keys_ für den Authentifizierungsprozess zu verwenden.

Das Schlüsselpaar aus _Private-Key_ und _Public-Key_ muss zuvor gemeinsam mit dem Server-Admin eingerichtet werden.
Je nach Server-Konfiguration kann es erforderlich sein, die _SSH-Config_ anzupassen.

</details>

## Empfehlung

Die Verwendung des Terminal-Multiplexers _[Byobu](https://www.byobu.org/)_ wird empfohlen.

```bash
# Debian / Ubuntu
sudo apt install byobu
```

Download & Installation: [https://www.byobu.org/downloads](https://www.byobu.org/downloads)

<details>
<summary>Details anzeigen</summary>

Vorteile von _Byobu_:

- **Sitzungen beibehalten**: Byobu ermöglicht das Starten von Sitzungen, die im Hintergrund weiterlaufen, selbst wenn das Terminal geschlossen oder die Verbindung getrennt wird.
- **Einfache Wiederherstellung**: Es ist jederzeit möglich, zu einer bestehenden Sitzung zurückzukehren, um den Status von Prozessen zu überprüfen oder die Arbeit fortzusetzen.

</details>

## Installation

1. Makefile [herunterladen](./makefile)
2. Makefile in Projektordner speichern
   - Projektstruktur ([Beispiel](#projektstruktur))
3. Makefile [konfigurieren](#konfiguration)
4. `make install`

<details>
<summary>Details anzeigen</summary>

Die _Makefile_ dient in diesem Projekt zur Vereinfachung von Prozessen, die sonst in vielen Einzelschritten manuell über die bash-Konsole durchgeführt werden müssten.

Im Abschnitt [Projektstruktur](#projektstruktur) ist ein beispielhafter Aufbau eines Projekts skizziert.

Hilfen zur Konfiguration der _Makefile_ und Bedeutung der verwendeten Variablen sind im Abschnitt [Konfiguration](#konfiguration) zu finden.

</details>

## Bedienung

> siehe [Befehle](#befehle)

1. `make upload` Projektdateien hochladen
2. `make run` Python-Script ausführen
3. `make log` Fortschritt überprüfen
4. `make download` Output-Dateien herunterladen

<details>
<summary>Details anzeigen</summary>

Die Makefile ist so konfiguriert, dass sie mit Erhalt einfacher Befehlen komplexe oder aufwendige Prozesse ausführt.

Im Abschnitt [Befehle](#befehle) sind diese sogenannten _Targets_ und deren Aufgabe näher beschrieben.

</details>

## Projektstruktur

> Beispiel

```txt
/home/max/akis/my_project/
├── data
│   ├── one.pkl
│   ├── three.pkl
│   └── two.pkl
├── main.py
├── makefile
├── output
│   └── empty
└── scripts
    ├── script-1.py
    ├── script-2.py
    └── script-3.py
```

<details>
<summary>Details anzeigen</summary>

Diese Projektstruktur ist nur ein Beispiel.
Sie soll jedoch verdeutlichen, dass auch verschachtelte Projekte mit der _Makefile_ bedienbar sind.

Wichtig ist jedoch, dass in der _Makefile_ das `MAIN_SCRIPT` konfiguriert ist.
Dieses Python-Script wird durch die _Makefile_ ausgeführt; hier: `main.py`.

Wie das `MAIN_SCRIPT` aufgebaut ist, ist dabei nicht relevant.
Es könnte ein alleinstehendes Script sein, welches ohne andere Python-Scripts auskommt.
Oder es führt andere Python-Scripts aus; wie im obigen Beispiel `scripts/script-1.py`, `scripts/script-2.py` und `scripts/script-3.py`.

Importierte Datasets liegen oft nicht innerhalb des Projektordners, sondern werden von extern importiert.
Es ist darauf zu achten, dass auch der Server Zugriff auf den Pfad der Datasets hat.
Symbolische Links können hier hilfreich sein.

Output-Dateien, die nach Abschluss des Scripts wieder auf den Client heruntergeladen werden sollen, können mit `REMOTE_OUTPUT_FILES` definiert werden.
Sie werden durch den Aufruf von `make download` im zuvor definierten Ordner `LOCAL_OUTPUT_DIR` abgespeichert.

</details>

## Konfiguration

| Variable              | Verwendung                         | Beispiel                             |
| :-------------------- | :--------------------------------- | :----------------------------------- |
| `SERVER_USER`         | Server: User Name                  | `mmustermann`                        |
| `SERVER_HOST`         | Server: Host Name                  | `hyrican-1-extern`                   |
| `CONDA_PATH`          | Server: Conda-Installations-Pfad   | `/home/mmustermann/.local/opt/conda` |
| `CONDA_ENV`           | Server: Conda-Environment-Name     | `ml`                                 |
| `PYTHON_VERSION`      | Python: Gewünschte Version         | `3.10`                               |
| `PYTHON_PACKAGES`     | Python: Benötigte Pakete           | `tensorflow-cpu matplotlib optuna`   |
| `MAIN_SCRIPT`         | Auszuführendes Python-Script [^1]  | `main.py`                            |
| `LOG_FILE`            | Log-Datei (optional) [^1]          | `progress.log`                       |
| `LOCAL_PROJECT_DIR`   | Client: Projektordner [^1]         | `.`                                  |
| `LOCAL_OUTPUT_DIR`    | Client: Output-Ordner [^1]         | `output`                             |
| `REMOTE_PROJECT_DIR`  | Server: Projektordner [^2]         | `/home/mmustermann/akis/my_project`  |
| `REMOTE_OUTPUT_FILES` | Server: Output-Dateien [^1]        | `output/*.svg output/*pkl`           |
| `COPY_LINKS_AS_FILES` | Server: Kopiert Datei des Symlinks | `false`                              |

[^1]: Relativer Pfad zum Projektordner
[^2]: Absoluter Pfad

## Befehle

> `make <target>`

| Target     | Aktion                                    |       Ort       |
| :--------- | :---------------------------------------- | :-------------: |
| `install`  | Installiert Python Environment und Pakete |     Server      |
| `upload`   | Läd veränderte Projektdateien hoch        | Client → Server |
| `run`      | Führt Python Script aus                   |     Server      |
| `kill`     | Bricht Python Script ab                   |     Server      |
| `log`      | Zeigt Log-Datei (optional) an             |     Client      |
| `download` | Läd Outputdateien herunter                | Server → Client |
| `delete`   | Löscht Projektdateien                     |     Server      |

---

## TODOs

- [x] Bedienung über _Byobu_
- [ ] Datasets über NFS
- [ ] Benachrichtigung bei Abbruch/Erfolg
  - [ ] Slack
  - [ ] Matrix
- [ ] parallele Ausführung mehrerer Scripts

---

## Fragen & Anregungen

Fragen, Unklarheiten, Anregungen und Wünsche können gerne über folgende Kommunikationswege an mich herangetragen werden:

- [Slack](https://cvhai.slack.com/team/U084BA4GQ8M)
- [E-Mail](maximilian.melchert@stud.hs-bochum.de)

Es ist durchaus im Sinne des Projekts, auch individualisierte _Makefiles_ für einzelne Projekte anzupassen und umzuschreiben.
Die hier beschriebene _Makefile_ ist nur die Basis, auf der zukünftige Maßanfertigungen aufbauen können.