From 048aff6c981241190ee3584d3f22053465d02605 Mon Sep 17 00:00:00 2001
From: Ian Wienand <iwienand@redhat.com>
Date: Mon, 17 Aug 2020 08:44:00 +1000
Subject: [PATCH] Add ensure-rust role

Add a role to install Rust via the rustup tool.  It defaults to
installing globally, which avoids having to worry too much about
setting paths for follow-on jobs.

Packaged Rust and the upstream rustup install tool can live together,
and there's various documentation about it.  Thus I've made this such
that we can expand it with packaged Rust support if there is a need,
but I have not implemented that yet.

Change-Id: I32f9b285904a7036f9a80ada8a49fa9cf31b5163
---
 doc/source/roles.rst                 |   1 +
 doc/source/rust-roles.rst            |   4 +
 roles/ensure-rust/README.rst         |  28 ++++++
 roles/ensure-rust/defaults/main.yaml |   4 +
 roles/ensure-rust/tasks/main.yaml    |   8 ++
 roles/ensure-rust/tasks/rustup.yaml  |  13 +++
 test-playbooks/rust/ensure-rust.yaml |  21 ++++
 test-playbooks/rust/files/hello.rs   |   5 +
 zuul-tests.d/rust-jobs.yaml          | 140 +++++++++++++++++++++++++++
 9 files changed, 224 insertions(+)
 create mode 100644 doc/source/rust-roles.rst
 create mode 100644 roles/ensure-rust/README.rst
 create mode 100644 roles/ensure-rust/defaults/main.yaml
 create mode 100644 roles/ensure-rust/tasks/main.yaml
 create mode 100644 roles/ensure-rust/tasks/rustup.yaml
 create mode 100644 test-playbooks/rust/ensure-rust.yaml
 create mode 100644 test-playbooks/rust/files/hello.rs
 create mode 100644 zuul-tests.d/rust-jobs.yaml

diff --git a/doc/source/roles.rst b/doc/source/roles.rst
index 4492d0931..b3b88b087 100644
--- a/doc/source/roles.rst
+++ b/doc/source/roles.rst
@@ -25,5 +25,6 @@ Roles
    launchpad-roles
    puppet-roles
    python-roles
+   rust-roles
    system-roles
    translation-roles
diff --git a/doc/source/rust-roles.rst b/doc/source/rust-roles.rst
new file mode 100644
index 000000000..b15ffbcdb
--- /dev/null
+++ b/doc/source/rust-roles.rst
@@ -0,0 +1,4 @@
+Rust Roles
+==========
+
+.. zuul:autorole:: ensure-rust
diff --git a/roles/ensure-rust/README.rst b/roles/ensure-rust/README.rst
new file mode 100644
index 000000000..79a4ea323
--- /dev/null
+++ b/roles/ensure-rust/README.rst
@@ -0,0 +1,28 @@
+Install Rust
+
+Install the Rust toolchain
+
+**Role Variables**
+
+.. zuul:rolevar:: ensure_rust_rustup
+   :default: True
+
+   Install Rust via the ``rustup`` installer.
+
+.. zuul:rolevar:: ensure_rust_rustup_toolchain
+   :default: stable
+
+   The Rust toolchain to install with ``rustup``.
+
+.. zuul:rolevar:: ensure_rust_rustup_path
+   :default: /usr
+
+   Where to install Rust/Cargo with ``rustup``.  ``/usr`` provides the
+   tools globally.  This may conflict with distribution Rust packages
+   if installed.
+
+.. zuul:rolevar:: ensure_rust_packages
+   :default: False
+
+   Install Rust via system packages.  This role does not currently
+   support package install.
diff --git a/roles/ensure-rust/defaults/main.yaml b/roles/ensure-rust/defaults/main.yaml
new file mode 100644
index 000000000..ea739b307
--- /dev/null
+++ b/roles/ensure-rust/defaults/main.yaml
@@ -0,0 +1,4 @@
+ensure_rust_rustup: true
+ensure_rust_packages: false
+ensure_rust_rustup_toolchain: stable
+ensure_rust_rustup_path: /usr
diff --git a/roles/ensure-rust/tasks/main.yaml b/roles/ensure-rust/tasks/main.yaml
new file mode 100644
index 000000000..f88c87737
--- /dev/null
+++ b/roles/ensure-rust/tasks/main.yaml
@@ -0,0 +1,8 @@
+- name: Use rustup
+  include_tasks: 'rustup.yaml'
+  when: ensure_rust_rustup
+
+- name: Install packages
+  fail:
+    msg: 'Packaged rust install not yet implemented'
+  when: ensure_rust_packages
diff --git a/roles/ensure-rust/tasks/rustup.yaml b/roles/ensure-rust/tasks/rustup.yaml
new file mode 100644
index 000000000..3341b5f9a
--- /dev/null
+++ b/roles/ensure-rust/tasks/rustup.yaml
@@ -0,0 +1,13 @@
+- name: Install Rust
+  shell: |  # noqa 303
+      set -o pipefail
+      curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain {{ ensure_rust_rustup_toolchain }}
+  environment:
+    RUSTUP_HOME: '{{ ensure_rust_rustup_path }}'
+    CARGO_HOME: '{{ ensure_rust_rustup_path }}'
+  args:
+    executable: /bin/bash
+  become: yes
+
+- name: Use as selected Rust toolchain
+  command: rustup default {{ ensure_rust_rustup_toolchain }}
diff --git a/test-playbooks/rust/ensure-rust.yaml b/test-playbooks/rust/ensure-rust.yaml
new file mode 100644
index 000000000..ce81dffde
--- /dev/null
+++ b/test-playbooks/rust/ensure-rust.yaml
@@ -0,0 +1,21 @@
+- hosts: all
+  tasks:
+
+    - include_role:
+        name: ensure-rust
+
+    - name: Test cargo run
+      shell: |
+        cargo new foo
+
+    - name: Copy hello world
+      copy:
+        src: hello.rs
+        dest: hello.rs
+        mode: 0644
+
+    - name: Compile hello world
+      command: rustc hello.rs
+
+    - name: Run hello world
+      command: ./hello
diff --git a/test-playbooks/rust/files/hello.rs b/test-playbooks/rust/files/hello.rs
new file mode 100644
index 000000000..138c5f1ec
--- /dev/null
+++ b/test-playbooks/rust/files/hello.rs
@@ -0,0 +1,5 @@
+fn main() {
+
+   println!("Hello, World!");
+
+}
diff --git a/zuul-tests.d/rust-jobs.yaml b/zuul-tests.d/rust-jobs.yaml
new file mode 100644
index 000000000..ebd5e08b7
--- /dev/null
+++ b/zuul-tests.d/rust-jobs.yaml
@@ -0,0 +1,140 @@
+- job:
+    name: zuul-jobs-test-rust
+    description: Test the rust roles
+    tags: all-platforms
+    run: test-playbooks/rust/ensure-rust.yaml
+    files:
+      - playbooks/ensure-rust.yaml
+      - roles/ensure-rust
+      - zuul.d/rust-jobs.yaml
+
+# -* AUTOGENERATED *-
+#  The following project section is autogenerated by
+#    tox -e update-test-platforms
+#  Please re-run to generate new job lists
+
+- job:
+    name: zuul-jobs-test-rust-centos-7
+    description: Test the rust roles on centos-7
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: centos-7
+          label: centos-7
+
+- job:
+    name: zuul-jobs-test-rust-centos-8
+    description: Test the rust roles on centos-8
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: centos-8
+          label: centos-8
+
+- job:
+    name: zuul-jobs-test-rust-debian-stretch
+    description: Test the rust roles on debian-stretch
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: debian-stretch
+          label: debian-stretch
+
+- job:
+    name: zuul-jobs-test-rust-fedora-31
+    description: Test the rust roles on fedora-31
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: fedora-31
+          label: fedora-31
+
+- job:
+    name: zuul-jobs-test-rust-gentoo-17-0-systemd
+    description: Test the rust roles on gentoo-17-0-systemd
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: gentoo-17-0-systemd
+          label: gentoo-17-0-systemd
+
+- job:
+    name: zuul-jobs-test-rust-opensuse-15
+    description: Test the rust roles on opensuse-15
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: opensuse-15
+          label: opensuse-15
+
+- job:
+    name: zuul-jobs-test-rust-opensuse-tumbleweed-nv
+    voting: false
+    description: Test the rust roles on opensuse-tumbleweed
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: opensuse-tumbleweed
+          label: opensuse-tumbleweed
+
+- job:
+    name: zuul-jobs-test-rust-ubuntu-bionic
+    description: Test the rust roles on ubuntu-bionic
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: ubuntu-bionic
+          label: ubuntu-bionic
+
+- job:
+    name: zuul-jobs-test-rust-ubuntu-xenial
+    description: Test the rust roles on ubuntu-xenial
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: ubuntu-xenial
+          label: ubuntu-xenial
+
+- job:
+    name: zuul-jobs-test-rust-ubuntu-focal
+    description: Test the rust roles on ubuntu-focal
+    parent: zuul-jobs-test-rust
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: ubuntu-focal
+          label: ubuntu-focal
+
+- project:
+    check:
+      jobs:
+        - zuul-jobs-test-rust-centos-7
+        - zuul-jobs-test-rust-centos-8
+        - zuul-jobs-test-rust-debian-stretch
+        - zuul-jobs-test-rust-fedora-31
+        - zuul-jobs-test-rust-gentoo-17-0-systemd
+        - zuul-jobs-test-rust-opensuse-15
+        - zuul-jobs-test-rust-opensuse-tumbleweed-nv
+        - zuul-jobs-test-rust-ubuntu-bionic
+        - zuul-jobs-test-rust-ubuntu-xenial
+        - zuul-jobs-test-rust-ubuntu-focal
+    gate:
+      jobs:
+        - zuul-jobs-test-rust-centos-7
+        - zuul-jobs-test-rust-centos-8
+        - zuul-jobs-test-rust-debian-stretch
+        - zuul-jobs-test-rust-fedora-31
+        - zuul-jobs-test-rust-gentoo-17-0-systemd
+        - zuul-jobs-test-rust-opensuse-15
+        - zuul-jobs-test-rust-ubuntu-bionic
+        - zuul-jobs-test-rust-ubuntu-xenial
+        - zuul-jobs-test-rust-ubuntu-focal