.. _`ris-software-development-workshop`: ================================= RIS Software Development Workshop ================================= .. contents:: :depth: 1 :local: .. Note:: Connecting to get command line access: ``ssh wustlkey@compute1-client-1.ris.wustl.edu`` Queue to use: ``workshop, workshop-interactive`` Group to use: ``compute-workshop`` (if part of multiple groups) .. _`ris-software-development-workshop-video`: Software Development Workshop Video ----------------------------------- - Coming Soon! .. _`ris-software-development-workshop-provides`: What will this documentation provide? ------------------------------------- - An introduction to using the RIS Compute Platform for software development. - An example of creating a development environment and versioning software. - All examples are done in Perl. .. _`ris-software-development-workshop-needed`: What is needed? --------------- - Access to the RIS Compute Platform. - An account on Docker Hub. (https://hub.docker.com/) - Knowledge of containers and using them. - Knowledge of programming languages, particularly Perl. - An account on GitHub. (https://github.com/) - Visual Studio Code downloaded and installed. (https://code.visualstudio.com/) - GitHub repository for the Dockerfile: https://github.com/elynrfw/perl-docker - GitHub repository for the Perl script: https://github.com/elynrfw/ris-perl-example Getting Started --------------- - When creating either a Docker image or developing software, it is considered best practices to develop in an environment that has the following aspects. - Allows for versioning. - Allows for collaboration in creation. - Allows for the potential to be easily shared. - GitHub is a great free resource that allows for this. - If you don't already have a GitHub account, you can head over to https://github.com/ and create one. Bringing It All Together ------------------------ - The image below is a simple diagram of how all of the pieces and parts come together when using the Compute Platform in this manner. .. image:: images/soft-dev-workshop/soft-dev-diagram.png Setting Up Our Environment -------------------------- - Before we start work on the Compute Platform, we're going to want to set up our environment there. - The basic thing we're going to be doing is adding the ``LSF_DOCKER_VOLUMES`` variable to our ``.bash_profile``. - To do this, we'll want to login to the Compute Platform. .. code:: ssh wustlkey@compute1-client-N.ris.wustl.edu - The N can be replaced with the client number you're using to connect, there are currently 4 (1, 2, 3, 4). - Once logged in, we'll want to edit our ``.bash_profile`` file in our home directory. We'll do that quickly with ``vi(m)``. .. code:: vi .bash_profile - There may already be some code in the file. We don't want to change any of that, we simply want to go to the end of the file and add our code. - We'll add the following at the end of the file. .. code:: export STORAGE1='/storage1/fs1/${STORAGE_ALLOCATION}/Active:/storage1/fs1/${STORAGE_ALLOCATION}/Active' - ``${STORAGE_ALLOCATION}`` can be replaced with what ever storage allocations you would like to have your account load by default. - Once we have that added to the end of the file, we'll save the file. - Once our ``.bash_profile`` is updated and saved, to make it active in our current instance, we'll have to source the file with the following command. .. code:: source .bash_profile - Now our account is set up to load the directories we told it to when we start up a session and we don't have to worry about loading them when we submit a job. - We can do this for any of the LSF environement variables that we would like to use by default. - In the end, your file should look something like the following. .. code:: # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/.local/bin:$HOME/bin export PATH export STORAGE1='/storage1/fs1/elyn/Active:/storage1/fs1/elyn/Active' .. admonition:: LSF_DOCKER_VOLUMES in .bashrc and .bash_profile - It is considered best practices not to include LSF_DOCKER_VOLUMES in your .bashrc or .bash_profile files. - Including this directly can cause issues with some software. - It is considered best practices to declare LSF_DOCKER_VOLUMES for each job individually. Creating a Repository --------------------- - Once you have an account and are logged in, you are ready to create a project within GitHub. - You can do this by clicking the New button. .. image:: images/soft-dev-workshop/github.home.page.png - This will take you to a page where you can put in the info necessary for creating a new repository for work. .. image:: images/soft-dev-workshop/create.repository.png - First we will create a repository for our perl code project. - We will name the repository ``ris-perl-example``. - Once this is done, you will be taken to the repository page, which will look like the following. .. image:: images/soft-dev-workshop/ris-perl-example.repository.png - From here, we can get the information necessary to make a clone of the repository in the Storage Platform. - Clicking on the Code button will create a popup that will have the necessary information. - We will want to copy the ``HTTPS`` information to clone this. .. image:: images/soft-dev-workshop/github.clone.info.png - Once we have that copied, we can log onto the Compute Platform. - Once logged on, we'll navigate to the directory we want to put our new github repository. - Users can use their storage allocation for this and that is what we'll be doing in this workshop. - We will use the following command to clone our repository. .. code:: git clone https://github.com/username/ris-perl-example.git - This will clone the repository and all files within it. .. image:: images/soft-dev-workshop/git.clone.example.png .. image:: images/soft-dev-workshop/cloned.repository.png Finding a Docker Image ---------------------- - The next thing we'll want to do is find a Perl Docker image to use for our development. - If we head to hub.docker.com, we see that there are official Perl images. .. image:: images/soft-dev-workshop/perl.dockerhub.png - Looking through the different versions available, for this example we will be using the ``slim-threaded`` version. - We can go ahead and load into an interactive job session of the image to explore what the image all has. - The first thing we'll want to check is to see if the image as git installed. .. code:: bsub -Is -G compute-workshop -q workshop-interactive -a 'docker(perl:slim-threaded)' /bin/bash .. image:: images/soft-dev-workshop/git.not.installed.png - It appears that git is not installed in the image. Therefore we will have to create our own image to make sure it is. Creating Our Docker Image ------------------------- Creating the Repository ~~~~~~~~~~~~~~~~~~~~~~~ - The first thing we will want to do, is find out what OS and version the image is running. - We can do that with the following command. .. code:: cat /etc/os-release .. image:: images/soft-dev-workshop/get.os.version.png - Once we have that information, we know how we need to install packages or software. - The container we're using has a Debian OS, so we will be using apt-get to install git. - Since we are creating our own Docker image and will want to potentially version this as well, we'll create another GitHub Repository. - Using the same process above, we'll create one called, ``perl-docker``. .. image:: images/soft-dev-workshop/github.perl.docker.png - Once we have the repository created, we can clone the repository like was done above with the following command. .. code:: git clone https://github.com/username/perl-docker.git Editing the Dockerfile ~~~~~~~~~~~~~~~~~~~~~~ - Once we have the repository set up, we can create and edit our Dockerfile. - There are mutliple text editors you can use to do this. Vi(m) is installed on Compute1 and you can use that. - However, for this example, we are going to demonstrate using Visual Studio Code (VSC). (https://code.visualstudio.com/) - This is a rather expansive editor that has many features and extensions that you can add to help customize your experience. - VSC is also free and open source and has Mac OS, Windows, and Linux versions available. - Once the editor is installed, we will go ahead and open it up and we will see the default page along with a sidebar menu. .. image:: images/soft-dev-workshop/vsc.sidebar.png - One of the features available in VSC is the ability to directly connect to a remote machine via ``SSH``. - In order to use that feature we will need to install an extension. To find the extensions we will need to click on the 3 squares with a square offset in the sidebar. - Once we have done that, we can search for the extension we need, in this case ``visual studio code remote ssh`` .. image:: images/soft-dev-workshop/remote.ssh.extension.png - Once we've searched and found our extension, we simply need to click the install button and it will be installed for us. - In order to connect to a remote server, we will need to click the green button in the bottom left corner of the software window. .. image:: images/soft-dev-workshop/open.remote.window.png - After clicking there, it will open a new window and at the top of the window, there will be box that if we click, will give us a drop down menu of options. - We want to select, ``Connect to Host...`` .. image:: images/soft-dev-workshop/connect.to.host.png - This will open the option to open either a configured SSH host or to enter the information like connecting via a terminal. - In this window simply enter the information like you were connecting to Compute1 via a terminal. .. code:: wustlkey@compute1-client-N.ris.wustl.edu .. image:: images/soft-dev-workshop/select.ssh.host.png - It will then prompt for your password. This will be the password you use to connect to Compute1. .. image:: images/soft-dev-workshop/password.prompt.png - Once you are connected, it will default to a screen without any directories open. You will then need to click on the Open Folder button. .. image:: images/soft-dev-workshop/open.folder.menu.png - Then it will ask you what folder to open. It defaults to your home directory on Compute1, but from here, we will select our ``perl-docker`` directory. .. image:: images/soft-dev-workshop/directory.select.png - Once we have our directory open, we can see everything that was cloned in the step above, which at this point is the README file. .. image:: images/soft-dev-workshop/docker.dir.vsc.png - From here, we can create a new file that we will call ``Dockerfile``. This will be our Dockerfile that we will create our container from. - Our Dockerfile will be really simple as we're simply adding git to the Perl base that we'll be using. As such, our file will look like the following. .. code:: FROM perl:slim-threaded RUN apt-get update && apt-get install -y --no-install-recommends git && apt-get clean - This code lets the container know, it's building from the ``slim-threaded`` Perl container. - It also tells the container to install ``git``. But we also want to update ``apt-get`` and need some install options so that git can cleanly install in a container. - At the end we want ``apt-get`` to clean up as it will help keep our container clean and as slim as necessary as this helps with load times of the container. - Once we have our code in our ``Dockerfile`` file, we can save it and it will save it through the Compute1 system so we can access it via connecting to Compute1. .. image:: images/soft-dev-workshop/dockerfile.code.png - Now that we have our Dockerfile all ready to go, we can go to Compute1 and commit our changes. - First we will need to ``cd`` to our ``perl-docker`` directory. - Then once there, we will need to add the files we want to submit to the commit we do this by using the ``git add`` command. .. code:: git add Dockerfile git add README.md - Once that is done we can submit our commit with the ``git commit`` command. - The commit command also allows you to label your commit. So we'll label it like the following. .. code:: git commit -m "Create Dockerfile and Update README" - This creates the commit and it is now ready to be pushed to GitHub. - To do this we will use the ``git push`` command. .. code:: git push - It will ask you for your username and either a password or personal access token as GitHub is moving away from passwords with commits. - GitHub is moving away from passwords and instead using personal access tokens. `You can find more information here. `__ - Once you have entered the required information it will push our changes to the repository on GitHub. .. image:: images/soft-dev-workshop/git.commit.push.png - We can now see these changes in the repository at GitHub. .. image:: images/soft-dev-workshop/github.push.results.png Building The Dockerfile ~~~~~~~~~~~~~~~~~~~~~~~ - Now that we have our Dockerfile created and pushed to GitHub, we can build our container. - This can be done directly on Compute1. For complete details, check out our :ref:`Docker On Compute ` docs. - We will want to use the following command on Compute1 to build and push our container. - Before using this command, we will want to be in the directory that contains our ``perl-docker`` directory. .. code:: bsub -G compute-workshop -q workshop-interactive -Is -a 'docker_build(username/perl-docker)' -- --tag 1.0.0 perl-docker/ .. image:: images/soft-dev-workshop/docker.build.png - This command will provide the Docker image with the tag we supply but also with the ``latest`` tag. - Now that we have our Perl Docker image with ``git`` installed, we can test to make sure everything works. - We can test it like we did the base Perl Docker image earlier. .. code:: bsub -Is -G compute-workshop -q workshop-interactive -a 'docker(username/perl-docker:latest)' /bin/bash .. image:: images/soft-dev-workshop/perl.with.git.png Creating Our Perl Script ------------------------ - Now that we have our Dockerimage how we want it, we can begin working on our Perl script. - We've already created and cloned the repository so now we just need to connect to it like we did the Dockerfile repository. .. image:: images/soft-dev-workshop/perl.example.dir.png - For ease of doing this, we will want to open up a terminal within VSC. - If we go to the Terminal menu and click new, this will open a terminal up within our ``ris-perl-example`` directory. - From here we can do git commands. .. image:: images/soft-dev-workshop/terminal.in.vsc.png - From the ``git branch`` command, you can see we are currently on the main branch. - In order to do versioning, we will want to create a new branch. - We can do that with the following command. .. code:: git checkout -b v1.0.0 .. image:: images/soft-dev-workshop/git.checkout.png - Now we have a branch for version 1.0.0 of the script we will be creating. - Now we can start working on our Perl script. The first part we will want to include in the Perl script is the declaration. - We need to let the interpreter know it's a Perl script and we want to make sure ``strict`` and ``warnings`` are turned on. - These will keep us from potentially making mistakes in our Perl script. .. code:: #!/usr/bin/perl use strict; use warnings; - Now that we have that set up, we will want to set up the fact that we're going to be reading in a file via standard input. - And we want to set up any variables that will be needed. - Do do this, we need to understand what we'll exactly be doing. - We will be taking the tab delimited file provided above (and here) and calculating statistics on every column. - To do this, we will need an array for the input and an array for each statistics we want to calculate. - For the first version of our script, let's say we will simply calculate average and standard deviation. - We will also need a counter to use for the input array. .. code:: my $inputFile = $ARGV[0]; my @dataArray = @_; my @avgArray = @_; my @stdevArray = @_; my $counter = 0; - The first thing we need to do is to read in the file we gave the script via the command line. - As we read in the file, we'll store the data into an array. - We can do that with the following code. .. code:: open (DATAFILE, "<$inputFile"); while(my $finput = ) { chomp $finput; my @inputArray = split(/\t/, $finput); for(my $i=0; $i