Ansible Playbook Documentation
==============================

This document provides an overview of the Ansible playbook `configure_server.yml`.

.. code-block:: yaml

    # ansible/configure_server.yml
    ---
    - hosts: localhost
    gather_facts: yes
    become: yes
    vars:
        ansible_python_interpreter: /usr/bin/python3
    tasks:
        - name: Check if Ubuntu 20.xx is installed
        assert:
            that:
            - ansible_distribution == 'Ubuntu'
            - ansible_distribution_major_version | int >= 20
            msg: "Please use Ubuntu 20.xx version. Current version: {{ ansible_distribution }} {{ ansible_distribution_version }}"

        - name: Add NOPASSWD rule to sudoers
        block:
            - name: Add NOPASSWD rule to sudoers
            lineinfile:
                path: /etc/sudoers
                line: '%sudo  ALL=(ALL) NOPASSWD: ALL'
            become: yes
            register: result
            ignore_errors: yes

            - name: Print success message
            debug:
                msg: "Sudo NOPASSWD rule added successfully."
            when: result is not failed

            - name: Print error message and stop execution
            block:
                - debug:
                    msg: "Error occurred while modifying sudoers file."
                - meta: end_play
            when: result is failed

        - name: Setup Current Directory and Destination Directory
        block:
            - name: Get Current Directory
            command: pwd
            register: current_dir_output
            changed_when: false
            ignore_errors: true

            - name: Debug Current Directory
            debug:
                var: current_dir_output.stdout

            - name: Debug current_dir_output.stdout
            debug:
                var: current_dir_output.stdout

            - name: Set Destination Directory
            set_fact:
                dest_directory: "{{ current_dir_output.stdout | replace('/navidec/ansible', '') }}"
            changed_when: false

            - name: Debug Destination Directory
            debug:
                var: dest_directory

        - name: Copy run.sh from navidec to parent directory
        block:
            - name: Copy run.sh file
            copy:
                src: "{{ dest_directory }}/navidec/run.sh"
                dest: "{{ dest_directory }}/run.sh"
                remote_src: yes
                mode: preserve
    
            - name: Change owner of run.sh
            file:
                path: "{{ dest_directory }}/run.sh"
                owner: "{{ ansible_env.SUDO_USER }}"
                group: "{{ ansible_env.SUDO_USER }}"
            become: yes

        - name: Install Containernet
        block:
            - name: Check if Containernet repository already exists
            stat:
                path: "{{ dest_directory }}/containernet"
            register: containernet_repo

            - name: Remove existing Containernet repository if it exists
            when: containernet_repo.stat.exists
            file:
                path: "{{ dest_directory }}/containernet"
                state: absent
            ignore_errors: yes
            become: yes

            - name: Clone Containernet repository
            git:
                repo: https://github.com/containernet/containernet.git
                dest: "{{ dest_directory }}/containernet"
                clone: yes
                update: yes
            become: yes

            - name: Remove existing 'openflow' directory if it exists
            file:
                path: "{{ dest_directory }}/openflow"
                state: absent
            ignore_errors: yes
            become: yes

            - name: Run Containernet install playbook
            shell: ansible-playbook -i localhost, -c local "{{ dest_directory }}/containernet/ansible/install.yml"
            become: yes
            register: containernet_output

            - name: Display Containernet install playbook output
            debug:
                var: containernet_output.stdout_lines

        - name: Update package list and Install packages
        apt:
            name: sshpass, latexmk, texlive-fonts-recommended, texlive-latex-extra, texlive-fonts-extra
            update_cache: yes
            state: present
        become: yes

        - name: Install Kubectl
        block:
            - name: Download Kubectl
            get_url:
                url: "https://dl.k8s.io/release/{{ lookup('url', 'https://dl.k8s.io/release/stable.txt').split('\n')[0] }}/bin/linux/amd64/kubectl"
                dest: "{{ dest_directory }}/kubectl"
            become: yes

            - name: Install Kubectl
            command: >
                install "{{ dest_directory }}/kubectl" kubectl
            args:
                chdir: /usr/local/bin
            become: yes

            - name: Remove Kubectl setup file
            file:
                path: "{{ dest_directory }}/kubectl"
                state: absent
            become: yes

        - name: Install Sysbox
        block:
            - name: Download Sysbox
            get_url:
                url: "https://downloads.nestybox.com/sysbox/releases/v0.6.2/sysbox-ce_0.6.2-0.linux_amd64.deb"
                dest: "{{ dest_directory }}/sysbox-ce_0.6.2-0.linux_amd64.deb"
            become: yes

            - name: Install jq
            apt:
                name: jq
                state: present
            become: yes

            - name: Install Sysbox
            apt:
                deb: "{{ dest_directory }}/sysbox-ce_0.6.2-0.linux_amd64.deb"
            become: yes

            - name: Remove Sysbox setup file
            file:
                path: "{{ dest_directory }}/sysbox-ce_0.6.2-0.linux_amd64.deb"
                state: absent
            become: yes

        - name: Check Sysbox Service Status
        block:
            - name: Get Sysbox service status
            shell: systemctl is-active sysbox
            register: sysbox_status
            changed_when: false

            - name: Print Sysbox service status
            debug:
                msg: "Sysbox service is {{ sysbox_status.stdout }}"

        - name: Update Docker daemon and restart it
        block:
            - name: Insert line into file
            ansible.builtin.lineinfile:
                path: /etc/docker/daemon.json
                insertafter: '"bip": "172.20.0.1/16",'
                line: '    "default-runtime": "sysbox-runc",'
                state: present
            become: yes

            - name: Restart docker
            ansible.builtin.systemd:
                name: docker
                state: restarted
            become: yes

        - name: Install pip3 and required packages
        command: pip3 install psutil networkx pika fastapi uvicorn requests rich sphinx sphinx-rtd-theme sphinx-sitemap myst-parser linkify-it-py
        become: yes

        - name: Install Node.js
        block:
            - name: Download Node.js setup script
            get_url:
                url: "https://deb.nodesource.com/setup_20.x"
                dest: "{{ dest_directory }}/nodesource_setup.sh"
            become: yes

            - name: Run Node.js setup script
            command: "bash {{ dest_directory }}/nodesource_setup.sh"
            become: yes

            - name: Install Node.js
            apt:
                name: nodejs
                state: present
            become: yes

            - name: Remove Node.js setup script
            file:
                path: "{{ dest_directory }}/nodesource_setup.sh"
                state: absent
            become: yes

            - name: Check Node.js version
            command: "node --version"
            register: node_version
            changed_when: false
            become: yes

            - name: Print Node.js version
            debug:
                msg: "Node.js version is {{ node_version.stdout }}"

        - name: Install nodemon
        block:
            - name: Upgrade npm using sudo
            command: "npm install -g npm"
            become: yes
            ignore_errors: yes

            - name: Print npm upgrade result
            debug:
                msg: "npm upgraded successfully."
            when: node_version.stdout is defined and "npm" not in node_version.stdout

            - name: Install nodemon using sudo
            command: "npm install -g nodemon"
            become: yes
            ignore_errors: yes

            - name: Print nodemon installation result
            debug:
                msg: "nodemon installed successfully."
            when: node_version.stdout is defined and "nodemon" not in node_version.stdout

            - name: Install nodemon using npm
            command: "npm install -g nodemon"
            become: yes
            ignore_errors: yes

            - name: Print nodemon installation result
            debug:
                msg: "nodemon installed successfully."
            when: node_version.stdout is defined and "nodemon" not in node_version.stdout

        - name: export COLORTERM=truecolor to current user
        block:
            - name: Get the current user
            set_fact:
                current_user: "{{ ansible_env.SUDO_USER | default(ansible_env.USER) }}"
            
            - name: Print the username
            ansible.builtin.debug:
                msg: "Current user is: {{ current_user }}"

            - name: Check if '#export COLORTERM=truecolor' is in ~/.bashrc
            command: grep -q "#export COLORTERM=truecolor" "/home/{{ current_user }}/.bashrc"
            register: grep_result
            ignore_errors: yes

            - name: Remove '#' from the line if it exists
            replace:
                path: "/home/{{ current_user }}/.bashrc"
                regexp: '^#export COLORTERM=truecolor'
                replace: 'export COLORTERM=truecolor'
            when: grep_result.rc == 0

            - name: Check if export COLORTERM=truecolor is in ~/.bashrc
            command: grep -q "export COLORTERM=truecolor" "/home/{{ current_user }}/.bashrc"
            register: grep_result
            ignore_errors: yes

            - name: Add export COLORTERM=truecolor to ~/.bashrc if not present
            lineinfile:
                path: "/home/{{ current_user }}/.bashrc"
                line: "export COLORTERM=truecolor"
            when: grep_result.rc != 0


        - name: Create docker group & add current user to it
        block:
            - name: Get the current non root remote user
            set_fact:
                remote_regular_user: "{{ ansible_env.SUDO_USER }}"

            - name: Print the username
            ansible.builtin.debug:
                msg: "Current user is: {{ remote_regular_user }}"
    
            - name: Add docker group
            ansible.builtin.group:
                name: docker
                state: present

            - name: Add user to docker group
            ansible.builtin.user:
                name: "{{ remote_regular_user }}"
                groups: docker
                append: yes



Playbook Overview
-----------------

The `configure_server.yml` playbook is designed to configure a server. It performs the following tasks:

1. Ensure that the server is running Ubuntu 20.xx.
2. Add an NOPASSWD rule to the sudoers file.
3. Set up the current directory and destination directory.
4. Copy the `run.sh` script from the `navidec` directory to the parent directory.
5. Install Containernet if it's not already installed.
6. Update the package list and install required packages.
7. Install Kubectl.
8. Install Sysbox.
9. Check the status of the Sysbox service.
10. Update the Docker daemon and restart it.
11. Install Python packages using pip3.
12. Install Node.js and nodemon.
13. Export `COLORTERM=truecolor` to the current user's environment.
14. Create a docker group and add the current user to it.

Please refer to the playbook source code for detailed task configurations.

For more information on Ansible, refer to the official documentation: https://docs.ansible.com/

For information on YAML syntax, refer to the YAML documentation: https://yaml.org/

Playbook Usage
--------------
You can run the playbook using the following command:

Firstly, initiate the installation of Ansible on a freshly installed version of Ubuntu 20.xx:

.. code-block:: shell

   sudo apt-get update && sudo apt-get install ansible -y

Next, clone the NaviDec repository:

.. code-block:: shell

   git clone -b v4-Auto https://gitlab.inria.fr/fgiarre/navidec.git

Lastly, run the Ansible playbook to install the required dependencies:

.. code-block:: shell

   sudo ansible-playbook -i "localhost," -c local navidec/ansible/configure_server.yml && exit

After the installation is complete, the current active terminal session will automatically log you out. You can log back in to ensure that your group membership is re-evaluated.

.. note::

   This playbook assumes that you have Ansible installed on your system.

.. warning::

   Be cautious when making changes to system configurations, especially when using `become` and `sudo` privileges.

For more information on using Ansible playbooks, consult the Ansible documentation.


Playbook Author
---------------

   Author: INRIA de l'Université de Rennes, IRISA