MaterializeCSS vs ReactJS: the case of the select

For historical reasons, the COMBAT TB web interface uses materialize for its styling. So far so good. That is, until I tried to deploy my code, written with React.JS. See, as I understand it, materialize has in some cases decided to replace some HTML elements with its own version of them. Notably the <select> element. And ReactJS relies on these elements for its own operation.

The first problem I had was that <select> elements vanished. Turns out you need a bit of Javascript to make them work:

$(document).ready(function() {

The next problem, however, was that the onChange handlers that ReactJS uses don’t trigger events. Luckily that has been discussed before.

I’ve got two types of <select> element in the code I was writing for the COMBAT TB Explorer web application: static ones (there from the birth of the page) and dynamically generated ones. For the static ones I added some code to link up the events in the componentDidMount handler:

componentDidMount: function() {
    $(document).ready(function() {
    $('#modeselectdiv').on('change', 'select', null, this.handleModeChange);
    $('#multicompselectdiv').on('change', 'select', null, this.handleMultiCompChange);


but this didn’t work for the dynamically generated elements, I think because they are only rendered after an AJAX call returns. For since I know a state change triggers the render event, I added the handler hook-up after the data was return and deployed (to the application’s state), for example:

success: function(datasets) {
    var dataset_list = [];
    var dataset_list_length = datasets.length
    for (var i = 0; i < dataset_list_length; i++) {
        dataset_list.push({'name': datasets[i]['name'], id: datasets[i]['id']});
    this.setState({datasets: dataset_list, dataset_id: dataset_list[0].id});
    $('#datasetselectdiv').on('change', 'select', null, this.handleDatasetChange);

Turns out this works. The state change handlers are now linked in, they keep the state up to date with what the user is doing on the form, and the whole thing (that links the application to a Galaxy instance) works. Yay!

Making Ubuntu 14.04 and CentOS 7 NFS work together

I just spent a frustrating morning configuring our servers to talk NFS to each other properly. So we have:

1) NFS servers (ceph-mon1 and so on) running CentOS 7.
2) NFS clients (gridj1 and so on) running Ubuntu 14.04.

The first problem: RBD mounting and NFS startup were not configured on the servers. I fixed that by adding entries in /etc/ceph/rbdmap and enabling the rbdmap and nfs-server services using systemctl enable. I also used e2label to label the ext4 filesystems in the RBDs and then used these labels in /etc/fstab instead of device names. And used the _netdev option in the mount options because these devices are network devices.

The second problem: I had to add the insecure option to the exports in /etc/exports. This is because the mount request comes from a port higher than 1024, a so-called insecure port. And then exportfs -r to resync everything.

And the third problem: Ubuntu autofs makes a NFS4 mount request by default (even though I had specified nfsvers=3 in the mount options), and I haven’t configured NFS4’s authenticated mounts, so I was getting authenticated mount request from messages in /var/log.messages on the NFS server. I switched the NFS server to not do NFS4 by adding --no-nfs-version 4 to the RPCNFSDARGS variable in /etc/sysconfig/nfs on the server, restarted the NFS server (systemctl restart nfs-server) and the mounts finally worked.

Finally, documented this here for posterity…