Network Cards and Device Names

I know there’s a page on the Red Hat website that explains the new network device names and how they’re created. But, for me, a concrete example that I worked with is always much better. I set up a new server yesterday and had some issues with a fiber network card, so I thought I’d write up what I learned.

The system has two built-in ethernet cards and I added a fiber card as well. The first thing I want to mention is that this server has space for two cpus, but we’re only using one. And on my first attempt at adding the fiber card, I put it in a slot that was for things for cpu2, which we’re not using. After I moved the card to a slot for cpu1, it showed up. So here is the info on my cards:


# lspci|grep Eth
65:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 06)
b5:00.0 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GBASE-T (rev 09)
b5:00.1 Ethernet controller: Intel Corporation Ethernet Connection X722 for 10GBASE-T (rev 09)

The Realtek card is the fiber one and the other two are built in. Note the numbers for the built-in cards, b5:00.0 and b5:00.1. This number is the basis for how the device names are made. If you convert b5 from hex to decimal, you get 181. Now if I look in /etc/sysconfig/network-scripts, I see two device files: ifcfg-enp181s0f0 and ifcfg-enp181s0f1. These devices all start with en. Then they’re followed by the numbers from the lspci command.

enp#s#f#

For b5:00.0, the p is b5 in decimal, the s is 00 (though you only need one 0) and since there are two cards .0 and .1, add the f with 0 or 1.

Now the device for my fiber card didn’t show up. But if I want to make my own device, I can. The hex number 65 in decimal is 101. So I created enp101s0. I don’t need the f because there’s only one card here. And I created the file /etc/sysconfig/network-scripts/ifcfg-enp101s0 with the information needed for the fiber card.

The other thing that I needed to do is to assign the mac address of the card to that device. I ran this command:


# ifconfig enp101s0 hw ether aa:bb:cc:dd:ee:ff
# ifup enp101s0

I found a number on the actual card that is the length of the mac address, so I used that in my command. After the ifup command, the card showed with the ifconfig command.

The big question was did it work. Right now, I don’t know. I didn’t have a fiber cable to test things out. I hope that next week the student who is using this card will get back to me and let me know how things go.

My other issue is that this card doesn’t come up automatically at boot. I’m not sure why I have to manually assign the hw address to it with the ifconfig command. This makes me think that perhaps I did something wrong as there’s no reason for it not to come up automatically. I’ll find out next week when things are actually set up so I can test it.

First Mitered Corner Attempt

Since my corners are not so good, I’ve decided that I need to make around 50 napkins with mitered corners for practice. I found a YouTube Video on Sewing Mitered Corners to try to follow. The pictures below are from my first attempt. It’s lousy. Though I thought I was very careful to iron and measure things. I also took my time and sewed as instructed, but when I tried to lay the seam flat, the mitered corners just didn’t line up properly. So perhaps I need to find a book or something with more detailed instructions. Or I just need to practice and come up with my own system. Anyway, this is why I’m practicing. The other problem I had was that I must have mismeasured something. My intent was to make a 16″ square napkin. I wanted the edge to be 1/2″. And according to the video, I also need an extra 1/2″ folded under first. So I think that means I need an extra 1″ all around. I cut the square at 18″. But when I measured the final napkin, it’s more like 15″ square. So I guess I didn’t measure as perfectly as I thought. Oh well.

Here is napkin #1.

Latest Quilt

I just finished a baby quilt for my brother and brother-in-law. John’s friend Richard picked out the great material. I’m fairly certain I would have gone with more plain, solid colors. So it was great that he picked such great colorful ones.

My skills are getting better, though they’re still not great. All my corners don’t match perfectly, which I’m ok with. To me, that’s a sign of a handmade quilt. My corners are getting better, but they’re still not good. I think I’m just going to have to buckle down and do a bunch as practice to get better.

Ruby Gem Error

I’ve been doing a bit more work with Sinatra and I got the following error. I’m just documenting how I fixed it.

yo:digital_signs $ ruby display.rb 
Traceback (most recent call last):
	10: from display.rb:2:in `
' 9: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:39:in `require' 8: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:128:in `rescue in require' 7: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems.rb:217:in `try_activate' 6: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems.rb:224:in `rescue in try_activate' 5: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/specification.rb:1440:in `activate' 4: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/specification.rb:1458:in `activate_dependencies' 3: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/specification.rb:1458:in `each' 2: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/specification.rb:1472:in `block in activate_dependencies' 1: from /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/specification.rb:1438:in `activate' /Users/maryh/Software/rubies/2.5.7/lib/ruby/2.5.0/rubygems/specification.rb:2325:in `raise_if_conflicts': Unable to activate dm-serializer-1.2.2, because json-2.1.0 conflicts with json (~> 1.6) (Gem::ConflictError)

I couldn’t start my Sinatra app due to this json error. My first idea was to just uninstall the json v2.1.0 gem.

yo:2.5.7 $ gem list json

*** LOCAL GEMS ***

json (default: 2.1.0, 1.8.6)
json_pure (1.8.6)
multi_json (1.13.1)

yo:2.5.7 $ gem uninstall json -v 2.1.0
ERROR:  While executing gem ... (Gem::InstallError)
    gem "json" cannot be uninstalled because it is a default gem

I’ve compiled my own version of ruby because I have a bunch of different versions on my computer. So I went to the directory for the version I wanted to use and searched for 2.1.0.

yo:2.5.7 $ find . -name '*2.1.0*' -print
./lib/ruby/gems/2.5.0/cache/chromedriver-helper-2.1.0.gem
./lib/ruby/gems/2.5.0/cache/sassc-rails-2.1.0.gem
./lib/ruby/gems/2.5.0/cache/spring-2.1.0.gem
./lib/ruby/gems/2.5.0/doc/chromedriver-helper-2.1.0
./lib/ruby/gems/2.5.0/doc/sassc-rails-2.1.0
./lib/ruby/gems/2.5.0/doc/spring-2.1.0
./lib/ruby/gems/2.5.0/gems/chromedriver-helper-2.1.0
./lib/ruby/gems/2.5.0/gems/sassc-rails-2.1.0
./lib/ruby/gems/2.5.0/gems/spring-2.1.0
./lib/ruby/gems/2.5.0/specifications/chromedriver-helper-2.1.0.gemspec
./lib/ruby/gems/2.5.0/specifications/default/json-2.1.0.gemspec
./lib/ruby/gems/2.5.0/specifications/sassc-rails-2.1.0.gemspec
./lib/ruby/gems/2.5.0/specifications/spring-2.1.0.gemspec


yo:2.5.7 $ rm ./lib/ruby/gems/2.5.0/specifications/default/json-2.1.0.gemspec

Once I found the gemspec file, I deleted it and things worked as expected.

A Toy for My Nephew

My nephew really likes light switches, so I made him this toy out of junk that I found in my house. He does know the word “hot”, so I think he’ll understand not to touch the bulbs. If he doesn’t, I may have to cover them with something or use a different bulb. He’s a smart kid, so I’m not too worried about it.

My First Sinatra Project

I have a wufoo form that I’m using and I want to automatically see the results on a webpage. One of the hangups of this process is that I can’t put any script on the webserver. But what I can do is embed an iframe. So I could download the information that I wanted from my form to another server and then display that page in the iframe. My question was what to run on my second server, which I’m going to call my results server. All it really needed to do was get the results and then show them. So using a ruby on rails app for this seemed to be overkill. After reading about it, sinatra seemed to be the perfect fit. I could still use ruby and just show the results I wanted. This seemed to be the perfect project to test out sinatra.

The only gems that I needed were sinatra and wuparty. Wuparty is a gem specifically written for wufoo. I installed it with gem install and found that it didn’t install correctly. I looked at the source code on git and saw that everything except the /lib/wuparty/* files got installed. If I knew how to use git better, I’d submit a ticket. But it was easy for me to just fix manually.

Anyway, ignoring all the files I need to deploy or set things up, here’s what I needed.

Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '>= 2.5.0'

gem 'wuparty' # For using wufoo API
gem 'capistrano' # For deployment
gem 'rake', '12.3.2'
gem 'rack', '2.0.7'
gem 'sinatra', '2.0.5'

config.ru

require 'rubygems'
require 'sinatra'
require File.expand_path '../display_results.rb', __FILE__

run Sinatra::Application

entry.rb (this is where I define which fields are for what)

Entry = Struct.new(:firstname, :lastname, :institution, :attending, :guestfirstname, :guestlastname, :guestattending)

module Entries

end

if __FILE__ == $0
x = Entry.new('George', "Washington", "White House", "Dinner and Talks", "Martha", "Washington", "Dinner").to_h
puts x[:firstname]
end

display_results.rb

require 'rubygems'
require 'sinatra'
require 'wuparty'
require_relative 'entry'

config = YAML.load_file("config/wufoo.yml")
account = config["ACCOUNT"]
api_key = config["API_KEY"]

get '/results.html' do
erb `cat public/results.html`, layout: false
end

post '/results' do
@entries = []
wufoo = WuParty.new(account, api_key)
form = wufoo.form('FormName')
count = form.count.to_i
pageSize = 100
times = (count / pageSize).to_i
(0..times).each do |l|
form.entries(limit: pageSize, pageSize: pageSize, pageStart: (pageSize * l)).each do |e|
@entries << Entry.new(e["Field1"], e["Field2"], e["Field4"], e["Field6"], e["Field215"], e["Field216"], e["Field218"]).to_h
end
end
output = erb :'results.html'
File.open("public/results.html", "w") do |f|
f.puts(output)
end
end

That’s basically it. It’s really simple, but does exactly what I want it to do. And wufoo has webhooks that you can set up. I use those to send a post request each time someone signs up. This post request generates a new results.html file for me. And that’s the file that I put in an iframe on the website where I’m very limited in what I can do. I store a few things in a config file that I don’t want to store in my repo.

This is pretty simple, that I’m pretty sure it would be easy for me to add another get/post combo for another wufoo form when I add it.

This was a fun project and I like being able to set up sinatra to handle simple things like this. Rails would have been overkill here.

Quick Baby Quilt

After the success of my Dr. Seuss quilt, I was in the mood to make another quilt. So I used only leftovers from my previous quilts to make a baby quilt for a cousin who is having a baby. My original idea was to make it in 30 days, but I think I took longer than that. I’d have to check my journal to find out exactly when I started it, but I finished it on July 31st. And the baby is due the first week of August, so I’m happy with that. I’m not happy that I haven’t yet mailed it to them, but I’ll try to do that soon.

The other thing I really like about the quilt is that I think I’m finally getting the hang of correctly mitering the corners. Look at how good this corner looks. I actually stopped sewing to take a picture of it because I was so pleased. I’d like to say the other corners all looked like this, but they weren’t as good.

My best corner ever

And here are some pictures of the final quilt. I’m quite pleased with how it turned out.

cmake

I haven’t been doing much with writing/compiling c programs of late. So I didn’t really notice the move from using make to using cmake for the build environment. We’ve been having some issues at work with this, so I’ve spent a few days trying to learn it. I’m not at expert at this at all, but I have picked up a few things. So I want to document them here.

Here’s a simple hello.c program.

#include <stdio.h>

int main() {
printf("Hello world!\n");
return 0;
}

It can be compiled with:

yo:hello $ gcc hello.c -o hello
yo:hello $ ./hello
Hello world!

How would I do this using cmake?

yo:hello $ mkdir build
yo:hello $ touch CMakeLists.txt
yo:hello $ ll
total 32
-rw-r--r--  1 maryh  staff     0 Apr 24 10:23 CMakeLists.txt
drwxr-xr-x  2 maryh  staff    68 Apr 24 10:23 build
-rwxr-xr-x  1 maryh  staff  8432 Apr 24 10:09 hello
-rw-r--r--  1 maryh  staff    73 Apr 24 10:06 hello.c

The file that cmake looks for is called CMakeLists.txt. Edit this file so it looks like this:

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(hello)
add_executable(hello hello.c)

All this does is check that we’re using at least version 3 of cmake. Not necessary for this, but for some other work programs, I needed that. The project line sets up the project and stores the name in the variable PROJECT_NAME. And if it’s the top-level CMakeLists.txt file, it also stores it in CMAKE_PROJECT_NAME. And the add_executable line adds an executable target (for us called hello) that’s built from the source file(s) (for us we only have hello.c).

That’s all that is needed. It’s nice to make the build directory and run the cmake program there because it makes things much easier to delete all the files if you’re doing various iterations on things.

To compile then, go to the build directory and run:

yo:hello $ cd build
yo:build $ cmake ../
-- The C compiler identification is AppleClang 9.1.0.9020039
-- The CXX compiler identification is AppleClang 9.1.0.9020039
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/maryh/Documents/C/hello/build

Now use make to compile the program.

yo:build $ make
Scanning dependencies of target hello
[ 50%] Building C object CMakeFiles/hello.dir/hello.c.o
[100%] Linking C executable hello
[100%] Built target hello
yo:build $ ll
total 80
-rw-r--r--   1 maryh  staff  13521 Apr 24 10:33 CMakeCache.txt
drwxr-xr-x  15 maryh  staff    510 Apr 24 10:34 CMakeFiles
-rw-r--r--   1 maryh  staff   4751 Apr 24 10:33 Makefile
-rw-r--r--   1 maryh  staff   1373 Apr 24 10:33 cmake_install.cmake
-rwxr-xr-x   1 maryh  staff   8432 Apr 24 10:34 hello
yo:build $ ./hello
Hello world!

This is definitely overkill for such a simple program, but those are the basic steps for more elaborate programs. And the key file to edit is basically CMakeLists.txt.