- name: eval-haskell
  hosts: eval-haskell.fi.muni.cz
  vars:
    dhcpcd: false
    postfix: true
    ghc_version: 9.2.1
    ghc_version_bootstrap: 9.0.2
    cabal_version: 3.6.2.0
    ghc_prefix: '/opt/ghc/{{ghc_version}}'
    cabal_dir: '/usr/local/bin'
    ib015_workers: 8
    ib016_workers: 2
    backports: false
    frag_eval_tools:
      - auto
      - cc
      - group
      - sandbox
      - sub

  tasks:
    - import_role:
        name: runner_install
      tags:
        - install

    - block:
      - import_role:
          name: common_deb

      - name: Install frag requisites
        apt:
          pkg:
            - darcs
            - clang
            - libcurl4-gnutls-dev
            - libexpat1-dev
            - libldap2-dev
            - libacl1-dev
            - libcap-dev

      - name: Postgres key
        apt_key:
          data: |
            -----BEGIN PGP PUBLIC KEY BLOCK-----

            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
            =DA1T
            -----END PGP PUBLIC KEY BLOCK-----


      - name: Postgres repo
        apt_repository:
          repo: deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main
          filename: postgres

      - name: Postgres
        apt:
          pkg:
            - postgresql-client-12
            - libpq-dev
          default_release: bullseye-pgdg


      - name: Frag dir
        file:
          state: directory
          path: /var/frag
          owner: root
          group: systemd-journal
          mode: 02755

      - name: frag checkout exits?
        stat:
           path: /var/frag/frag/_darcs
        register: frag_chekout

      - name: Checkout frag
        command:
          chdir: /var/frag
          cmd: darcs get https://paradise.fi.muni.cz/~xstill/src/frag/
        when: not frag_chekout.stat.exists

      - name: Update frag darcs
        command:
          chdir: /var/frag/frag
          cmd: 'darcs pull -a'

      - name: "Gib config for frag"
        copy:
          src: frag/gib.local
          dest: /var/frag/frag/gib/local

      - name: Update frag build
        command:
          chdir: /var/frag/frag
          cmd: make

      - name: Builder user
        user:
          name: builder
          create_home: True
          shell: /bin/bash
          system: True

      - name: GHC requisites
        apt:
          pkg:
            - libtinfo-dev
            - libtinfo5
            - libgmp-dev
            - libgmp10

      - name: GHC target dir
        file:
          state: directory
          path: '{{ghc_prefix}}'

      - name: GHC installed?
        stat:
           path: '/opt/ghc/{{ghc_version}}/bin/ghc'
        register: ghc_bin

      - block:
          - name: GHC bootstrap directory
            file: 
              state: directory
              path: /home/builder/ghc-bootstrap

          - name: Download GHC bootstrap
            get_url:
              url: 'https://downloads.haskell.org/~ghc/{{ghc_version_bootstrap}}/ghc-{{ghc_version_bootstrap}}-x86_64-deb9-linux.tar.xz'
              dest: /home/builder/ghc-bootstrap/ghc.tar.xz

          - name: Extract GHC bootstrap
            unarchive:
              src: /home/builder/ghc-bootstrap/ghc.tar.xz
              dest: /home/builder/ghc-bootstrap/
              remote_src: True

          - name: Build GHC bootstrap
            shell:
              chdir: '/home/builder/ghc-bootstrap/ghc-{{ghc_version_bootstrap}}'
              cmd: '{{item}}'
            loop:
              - './configure --prefix=/home/builder/ghc-bootstrap'
              - make install -j8

          - name: Download GHC
            get_url:
              url: 'https://downloads.haskell.org/~ghc/{{ghc_version}}/ghc-{{ghc_version}}-src.tar.xz'
              dest: /home/builder/ghc.tar.xz

          - name: Extract GHC
            unarchive:
              src: /home/builder/ghc.tar.xz
              dest: /home/builder/
              remote_src: True

          - name: Build GHC
            shell:
              chdir: '/home/builder/ghc-{{ghc_version}}'
              cmd: 'env LANG=en_US.UTF-8 PATH=/home/builder/ghc-bootstrap/bin:$PATH {{item}}'
            loop:
              - ./boot
              - './configure --prefix={{ghc_prefix}} --disable-large-address-space --with-system-libffi --with-ffi-includes=$(pkg-config --variable=includedir libffi)'
              - make -j8

        become_user: builder
        become: true
        when: not ghc_bin.stat.exists

      - name: Install ghc
        shell:
          chdir: '/home/builder/ghc-{{ghc_version}}'
          cmd: 'env LANG=en_US.UTF-8 {{item}}'
        loop:
          - make install
        when: not ghc_bin.stat.exists

      - name: Symlink GHC to /usr/local/bin
        file:
          src: '/opt/ghc/{{ghc_version}}/bin/{{item}}'
          dest: '/usr/local/bin/{{item}}'
          state: link
        loop:
          - 'ghc'
          - 'ghc-{{ghc_version}}'
          - 'ghc-pkg'
          - 'ghc-pkg-{{ghc_version}}'
          - 'ghci'
          - 'ghci-{{ghc_version}}'
          - 'haddock'
          - 'haddock-ghc-{{ghc_version}}'
          - 'hp2ps'
          - 'hpc'
          - 'hsc2hs'
          - 'runghc'
          - 'runghc-{{ghc_version}}'
          - 'runhaskell'

      - name: IB015 eval users
        user:
          name: 'ib015_eval_{{item}}'
          create_home: True
          home: '/var/frag/ib015_eval_{{item}}/'
          shell: /bin/bash
          system: True
        loop: '{{range(ib015_workers)}}'

      - name: IB015 evals' env
        copy:
          content: |
            FRAG_SUBJECT=ib015
            FRAG_HOST=frag-db.fi.muni.cz
          dest: '/var/frag/ib015_eval_{{item}}/env'
        loop: '{{range(ib015_workers)}}'

      - name: IB015 evals' progs
        copy:
          src: '/var/frag/frag/_build/eval-{{item[1]}}'
          dest: '/var/frag/ib015_eval_{{item[0]}}/{{item[1]}}'
          remote_src: True
          mode: 0555
        loop: '{{range(ib015_workers) | product(frag_eval_tools) | list}}'
        register: ib015_ev_progs

      - name: IB015 eval deamons
        copy:
          src: '/var/frag/frag/_build/frag-eval'
          dest: '/var/frag/ib015_eval_{{item}}/'
          remote_src: true
          mode: 0555
        loop: '{{range(ib015_workers)}}'
        register: ib015_eval

      - name: Eval service
        get_url:
          url: https://gitlab.fi.muni.cz/xstill/frag-utils/-/raw/master/systemd/frag-eval@.service
          dest: /etc/systemd/system/frag-eval@.service
        register: eval_service

      - name: Enable IB015 evals
        systemd:
          name: 'frag-eval@ib015_eval_{{item}}'
          enabled: true
          state: '{{"re" if ib015_eval.changed or ib015_ev_progs.changed else ""}}started'
          daemon_reload: '{{eval_service.changed}}'
        loop: '{{range(ib015_workers)}}'

      - name: Add cabal
        unarchive:
          src: "https://downloads.haskell.org/~cabal/cabal-install-{{cabal_version}}/cabal-install-{{cabal_version}}-x86_64-linux-deb10.tar.xz"
          dest: "{{cabal_dir}}"
          remote_src: true

      - name: .cabal exits?
        stat:
          path: '/var/frag/ib015_eval_{{item}}/.cabal'
        loop: '{{range(ib015_workers)}}'
        register: dot_cabal_ib015

      - name: Cabal update
        command: "{{cabal_dir}}/cabal v2-update"
        become: True
        become_user: 'ib015_eval_{{item}}'
#        when: not dot_cabal_ib015.results[item].stat.exists
        loop: '{{range(ib015_workers)}}'

      - name: Hackage modules
        command: "{{cabal_dir}}/cabal v2-install --lib --package-env=/tmp/env.ib015.{{item}} QuickCheck lens HUnit graph-wrapper data-default-class"
        become: True
        become_user: 'ib015_eval_{{item}}'
        loop: '{{range(ib015_workers)}}'

      - name: hsExprTest checkout
        git:
          dest: '/var/frag/ib015_eval_{{item}}/hsExprTest'
          repo: https://github.com/vlstill/hsExprTest.git
          update: True
        become: True
        become_user: 'ib015_eval_{{item}}'
        loop: '{{range(ib015_workers)}}'

      - name: Install hsExprTest
        command:
          chdir: '/var/frag/ib015_eval_{{item}}/hsExprTest/'
          cmd: "{{cabal_dir}}/cabal v2-install --lib --package-env=/tmp/env.ib015.{{item}} "
        become: True
        become_user: 'ib015_eval_{{item}}'
        loop: '{{range(ib015_workers)}}'

      - name: Create GHC environment dir
        file:
          state: directory
          path: "~/.local/share/ghc/x86_64-linux-{{ghc_version}}/environments"
        become: True
        become_user: 'ib015_eval_{{item}}'
        loop: '{{range(ib015_workers)}}'

      - name: Deploy modified GHC environment
        command: "mv /tmp/env.ib015.{{item}} ~/.local/share/ghc/x86_64-linux-{{ghc_version}}/environments/default"
        become: True
        become_user: 'ib015_eval_{{item}}'
        loop: '{{range(ib015_workers)}}'

      # TODO: deduplicate
      - name: IB016 evals' progs
        copy:
          src: '/var/frag/frag/_build/eval-{{item[1]}}'
          dest: '/var/frag/ib016_eval_{{item[0]}}/{{item[1]}}'
          remote_src: true
          mode: 0555
        loop: '{{range(ib016_workers) | product(frag_eval_tools) | list}}'
        register: ib016_ev_progs

      - name: IB016 eval deamons
        copy:
          src: '/var/frag/frag/_build/frag-eval'
          dest: '/var/frag/ib016_eval_{{item}}/'
          remote_src: true
          mode: 0555
        loop: '{{range(ib016_workers)}}'
        register: ib016_eval

      - name: Enable IB016 evals
        systemd:
          name: 'frag-eval@ib016_eval_{{item}}'
          enabled: true
          state: '{{"re" if ib016_eval.changed or ib016_ev_progs.changed else ""}}started'
          daemon_reload: '{{eval_service.changed}}'
        loop: '{{range(ib016_workers)}}'

      - name: .cabal exits?
        stat:
          path: '/var/frag/ib016_eval_{{item}}/.cabal'
        loop: '{{range(ib016_workers)}}'
        register: dot_cabal_ib016

      - name: Cabal update
        command: "{{cabal_dir}}/cabal v2-update"
        become: True
        become_user: 'ib016_eval_{{item}}'
        # when: not dot_cabal_ib016.results[item].stat.exists
        loop: '{{range(ib016_workers)}}'

      - name: Remove stale GHC environments
        file:
          path: "/tmp/env.ib016.{{item}}"
          state: absent
        loop: '{{range(ib016_workers)}}'

      - name: Remove GHC environemnt from ~/.ghc
        file:
          path: "~/.ghc/x86_64-linux-9.2.1/environments/default"
          state: absent
        become: true
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: Hackage modules
        command: "{{cabal_dir}}/cabal v2-install --lib --package-env=/tmp/env.ib016.{{item}} QuickCheck lens mtl exceptions base-unicode-symbols data-default-class HUnit"
        become: True
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: Install parsec last, it is broken somehow otherwise
        command: "{{cabal_dir}}/cabal v2-install --lib --package-env=/tmp/env.ib016.{{item}} parsec"
        become: True
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: hsExprTest checkout
        git:
          dest: '/var/frag/ib016_eval_{{item}}/hsExprTest'
          repo: https://github.com/vlstill/hsExprTest.git
          update: True
        become: True
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: Install hsExprTest
        command:
          chdir: '/var/frag/ib016_eval_{{item}}/hsExprTest/'
          cmd: "{{cabal_dir}}/cabal v2-install --lib --package-env=/tmp/env.ib016.{{item}}"
        become: True
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: Create GHC environment dir
        file:
          state: directory
          path: "~/.local/share/ghc/x86_64-linux-{{ghc_version}}/environments"
        become: True
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: Deploy modified GHC environment
        command: "mv /tmp/env.ib016.{{item}} ~/.local/share/ghc/x86_64-linux-{{ghc_version}}/environments/default"
        become: True
        become_user: 'ib016_eval_{{item}}'
        loop: '{{range(ib016_workers)}}'

      - name: Enable user namespaces
        sysctl:
          name: kernel.unprivileged_userns_clone
          value: "1"
          state: present
          reload: yes

      tags:
        - deploy

# vim: shiftwidth=2 tabstop=2 softtabstop=2 ft=yaml.ansible
