Rails 6 and Webpacker

I had to make a simple web app and thought that it would be a good idea to use the latest version of ruby (2.7.0) and rails (6.0.2.1).

I quickly discovered that the default way of setting up javascript had changed from sprockets to webpacker. I don’t really understand everything about this stuff, but I do know that I needed javascript and bootstrap because the app I was writing was basically just going to show a bootstrap carousel. So I needed to get this to work.

Here’s what was important.

  1. Add gem ‘bootstrap’ to my Gemfile
  2. Delete the file app/assets/stylesheets/application.css
  3. If I want to have my own css file to use, create it in app/javascript/file.css.
    Then, add the following to app/javascript/packs/application.js

    // Add for bootstrap
    require("bootstrap/dist/js/bootstrap")
    
    // Add my own css
    require("../file")
    
  4. In the layout/application.html.erb, put this in the head:
        <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    

That’s the bare minimum I needed. The other big change was to my deployment script. In config/deploy.rb I use:

namespace :deploy do
	desc 'Run everything else'
	task :wrap_up do
		on roles(:app) do
			execute "touch #{deploy_to}/current/tmp/restart.txt"
			execute "cd #{release_path}; export LC_ALL=en_US.UTF-8; bundle install --deployment --without development test"
			execute "cd #{release_path} && yarn install"
			execute "cd #{release_path}; /usr/local/bin/rake assets:precompile RAILS_ENV=production"
		end
	end
	after :finishing, :wrap_up
end

And add “public/packs” and “node_modules” to the append :linked_dirs line.

Note that node and yarn have to be installed on both my development and production systems.

There are a ton more details on doing this. And I still don’t have much of an idea of how to write my own javascript, which I’m sure will change things. But for my basic stuff, this got me back on track with being able to deploy my app.

Making a Windows 10 Bootable USB Drive

I’m trying to update some computers to Windows 10. I have an iso file with windows 10 on it. I could write it to a dvd, but most of the computers I’m updating no longer have dvd players. I’d like to write it to a usb drive and boot from that. Over the past few days, I’ve found that this is a problem with windows 10 because there is one file, sources/install.wim that’s over 4gb. My systems will only boot from a fat or fat32 partitioned drive. On those drives, 4gb is the maximum file size. I also normally work on a mac, so I was trying to find a way to make these bootable usb drives on my mac. I was not successful. The key to making this work is to use a windows program called split-windowsImage. Here’s what I did, though making the NTFS filesystem on my usb drive was not necessary.

On my mac, I had a 1tb drive sitting around, so I partitioned it with two FAT32 partitions.

$ diskutil partitionDisk disk3 MBR fat32 DOS 300gb FAT32 NTFS 300gb
Started partitioning on disk3
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk3s1 as MS-DOS (FAT32) with name DOS
512 bytes per physical sector
/dev/rdisk3s1: 585794432 sectors in 9153038 FAT32 clusters (32768 bytes/cluster)
bps=512 spc=64 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=2 drv=0x80 bsec=585937504 bspf=71509 rdcl=2 infs=1 bkbs=6
Mounting disk
Formatting disk3s2 as MS-DOS (FAT32) with name NTFS
512 bytes per physical sector
/dev/rdisk3s2: 1367186816 sectors in 21362294 FAT32 clusters (32768 bytes/cluster)
bps=512 spc=64 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=585937507 drv=0x80 bsec=1367520669 bspf=166893 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished partitioning on disk3
/dev/disk3 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *1.0 TB     disk3
   1:                 DOS_FAT_32 DOS                     300.0 GB   disk3s1
   2:                 DOS_FAT_32 NTFS                    700.2 GB   disk3s2

I have NTFS for mac on my laptop, so I then formatted the NTFS partition as an NTFS drive. Then I mounted my windows 10 iso file and copied the files to both partitions. (Again, I didn’t need to do this, but I didn’t realize that at the time.)

be:CPBA_X64FRE_EN-US_DV9 $ sudo cp -r . /Volumes/DOS
cp: /Volumes/DOS/./sources/install.wim: File too large
be:CPBA_X64FRE_EN-US_DV9 $ sudo cp -r . /Volumes/NTFS
be:CPBA_X64FRE_EN-US_DV9 $ 

At this point, I took the external drive to my windows laptop and started powershell as an administrator. The DOS drive came up as D and the NTFS drive came up as E.

I moved to the E:\sources directory and ran this:

PS E:\sources> Split-WindowsImage -imagepath install.wim -splitimagepath "D:\sources\install.swm" -FileSize 1024

It took about 10 minutes and then showed the log file. After that I was able to boot windows 10 and install it.

2020 Projects #1 & #2

I’ve written more about these in my journals, but I thought I’d post a picture of my first two projects for the year. I made a new house number for my Mom and I made a calendar for my sister. I actually added a calendar hanger to this, but forgot to take a picture of it before I gave it to my sister.

On to 2020!

I worked yesterday and have a somewhat pressing deadline for a server and website I need to have up soon, so I didn’t think much about it being the last day of the year. We’re also waiting for the arrival of my brother’s baby which could be any time now, so my thoughts were elsewhere. And one of the things I wanted to do last year was do more with physical objects. I’m going to call that an unquestioned success. And the idea of continuing to do these blog posts is not as appealing anymore. I may switch over to doing them in my journals which I’ve been using a lot more. For the first time, ever, I think, I even ordered a planner. It should arrive in a few days and I’m going to try it to even more organize by thoughts and days.

Anyway, to keep this short, here’s my review of 2019. It was a great year. Did I eat more vegetables? Unquestionably, yes. Were there a wide variety, unquestionably no. But I very much did get in the habit of taking a salad to work most days. So I could this as a success.

Doing more with physical objects? Yep, I finished the quilt for Annie at the start of the year and made a baby one for my brother. I also did quite a bit of woodworking in fixing stools for my brother. And I wrote a lot in my journal. More on this later.

Be more present? Yes, I think I am. I also don’t think I’m on my phone too much, which is a good thing. I should probably be on my computer less (a-hem), thus the move to more writing with pens and paper.

Bike more? Ok, that’s a fail. My total miles for last year was only 861. I can do better and will.

Fail more? I think that’s probably a fail too. I did make a printer stand that has a shelf on it and the shelf really doesn’t slide open because the box isn’t square. But that’s the only fail that’s come to mind right now. So I clearly didn’t stretch myself enough.

However, overall, I don’t think I’ve ever been happier in my life. Life is good?

For 2020? I kind of think I want to keep the same resolutions that I had last year. But now that I’m going to start using my paper planner (note I’m going to use a Clever Fox Planner that should arrive soon), I’ll hopefully be more mindful throughout the year. I think my journal so far is just me doing a weekly summary. But the thought of sitting down to breakfast each day with a paper planner and pen instead of my laptop seems very appealing to me. We’ll see.

One thing I want to do today is to make a wall calendar to track on big habit over the year. And while I definitely started eating more salads over the year, I didn’t get that adventurous with other vegetables. I just read the book The Blue Zones last week and my takeaway there is I should be eating more beans. People in the blue zones eat around a cup of beans a day. So I think that’s going to be my tracker. Try to eat some beans (black beans, white beans, tofu, etc.) every day.

And now, since I’m off, I’m going to do some woodworking today. And probably clean my room up a bit. I’m also trying to get over a cold, so I’ll take it easy a little too. And life is good. I’m looking forward to 2020 being even better than 2019.

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.