Drazisil.com

My Online Musings

If you see this page, the nginx web server is successfully installed and working. Further configuration is required. Or is it?

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for visiting.

Emmet is awesome

article>(header>h2)+p+footer>ul>li

expands to

<article> <header> <h2></h2> </header> <p></p> <footer> <ul> <li></li> </ul> </footer> </article>

Blogging for fun and fun

In keeping with Lev's demands and my own obsession for doing things the hardest way possible, I'm converting my blog here from wordpress to a static html 5 site.

I'll be trying to keep a running log here to record what I do each day, I do like to write but never know what to say, maybe this will help.

Today I went back to ansible and used it to update nginx on my 3 servers. I also deciced I really need to start backing up things. One of the servers is running 3 minecraft servers and that could stand to be backed up. It's also the only server that's running debian and not ubuntu.

rsync is amazing, I'm not sure why I've never used it before.

Back to the blog. I don't have a lot of goals for the site currently. I'd like it to have an RSS feed. RSS holds a special place in my heart, having spent many hours playing with it back in the day. I still follow all my web comics by their RSS feeds.

Another thing I want to do and create an Emmet shortcut for a new article here. Emmet looks really cool and is something I would like to learn more about.

As a static site, I probably should still have pagnation, I'm not a personal fan of scroll bars, and walls of text tend to turn people off.

Oh, the weird unordered lists at the bottom of each post are the "tags" from the posts on wordpress. I'm not sure I will need them unless I add search, but I ported them anyway.

Mocha with Q and Promises

There are many posts that explain how to use promise libraries to wrap existing JavaScript functions that use callbacks, but very few that explain how to write a function that returns a promise from scratch. We will be using Q, a promise library that conforms to the Promises/A++ spec. The magic here is going to be Q's Deferred method. Since my use case was to use this with Mocha, a very popular testing library for NodeJS and Javascript, the  code examples for creating and using the function will be in the form of a unit test

Example Code

file.js

const Q = require('q')
             
            function myCoolFunction(currentTimestamp) {
              var deferred = Q.defer()
              if (currentTimestamp) {
                deferred.resolve(['1'])
              } else {
                deferred.reject(new Error('Missing timestamp'))
              }
              return deferred.promise
            }
             
            module.exports = {
              getCurrentItems,
            }
            

index.spec.js

/* global describe it */ require('chai').should()
require('q')
             
            const index = require('./index.js')
             
            describe('Schedule', function () {
              it('should return one entry for today', function (done) {
                const rightNow = new Date('2017-04-02 03:30:00 EST')
                index.myCoolFunction(rightNow)
                .then((items) =&gt; {
                  items.length.should.equal(1)
                })
                .then(done, done)
              })
              it('should throw an error', function (done) {
                index.myCoolFunction()
                .catch((err) => {
                  err.message.should.equal('Missing timestamp')
                })
                .then(done, done)
              })
            })
I hope this code saves you some time when learning how to write pre-ES6 promised functions.

Using nock with a socket connection

I'm working on a Node.JS app that connects to a unix socket, or named pipe, as it's called on Windows.   As part of my tests, I wanted to mock the connection and nock seemed the likely choice. One problem, there was nothing in the docs about socket connections, and the internet didn't seem to have ever tried this either. So I decided to do a quick writeup for myself and others in the feature. Thanks to nock's recording feature it turns out that nock treats sockets connections as localhost. Here is the code:

nock('http://localhost:80')
    .get('/info')
     .reply(200, {
         Containers: 0
})
Much easier than I thought it would be, and you get to guess what I'm making. Happy hacking!  

Posting to WordPress from Vim

My friend Lev ( levlaz.org, you should follow him) has been motivating me a lot with his recent blog posts, so I decided I should as well. I like to overcomlicate things, so I figured since I would learning vim I would see if there was a way to tie that in for easy blog posting at the same time. I knew that WordPress has a post by email ability, but I wasn't sure how to get best email from my debian machine. Luckily I found this great project called vmail ( https://github.com/danchoi/vmail) on Github. On of the great things I'm finding about vim is its awesome editing abilities let me type at the speed I think, and then go back and clean it up, without feeling the need to backspace as much. But we are gettin off track, lets get this posting thing going! Vmail needs ruby, sqlite3 and thats it. So I did the following: * `sudo apt-get install sqlite3 libsqlie3-dev * `sudo gem install vmail Then came time to configure vmail. My Gmail has two factor authentication, so at first I wasn't sure how to login using vmail. Turns out I can use an app password ( https://support.google.com/mail/answer/185833?hl=en&visit_id=1-636298093628599059-604302321&rd=1) Anyway, if all goes well, this post will publish on drazisil.com straight from vmail via vim and post by email. Here goes!

Force Disconnecting a connection from the command line in Linux

I was scanning my server and I discovered I had many connections from a friend to my Minecraft server. The only problem was said friend wasn't actually connected. Since they frequently have issues where it says they are already connected when they try, and because I'm learning sysadmin things, I wanted to see if there was a way to sever the connection without killing the process. Initially, my search results were coming up with the wrong answers, (kill the process, use iptables, use cutter to sever the connection at the firewall), but I knew there had to be a way. I finally found a SuperUser answer that did it. I have included the link at the bottom for credit, but there was some confusion, and I like examples myself, so here is a live one: I know my server is running java, so let's check for connections to that first...

[email protected]:~$ netstat -p | grep java (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp6       0      0 163-172-11-141.re:36123 74.124.124.xxx:57545 ESTABLISHED 4292/java tcp6       0      0 163-172-11-141.re:36123 74.124.124.xxx:58135    ESTABLISHED 4292/java tcp6       0      0 163-172-11-141.re:36123 74.124.124.xxx:54094    ESTABLISHED 4292/java --- snip---
Great, we have the process. Now we need to locate the file descriptors for the connections
[email protected]:~$ lsof -np 4292 | grep 74.124.124.xxx COMMAND  PID     USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME java    4292 drazisil  254u  IPv6          864292907      0t0       TCP 163.172.11.141:36123->74.124.124.xxx:55779 (ESTABLISHED) java    4292 drazisil  361u  IPv6          864251849      0t0       TCP 163.172.11.141:36123->74.124.124.xxx:54094 (ESTABLISHED) java    4292 drazisil  368u  IPv6          864290355      0t0       TCP 163.172.11.141:36123->74.124.124.xxx:56087 (ESTABLISHED) java    4292 drazisil  370u  IPv6          864398875      0t0       TCP 163.172.11.141:36123->74.124.124.xxx:56847 (ESTABLISHED) java    4292 drazisil  371u  IPv6          864433976      0t0       TCP 163.172.11.141:36123->74.124.124.xxx:57545 (ESTABLISHED)
We have our File Descriptors (FD) now, so let's go close them. We need to install gdb, the GNU Debugger
[email protected]:~$ sudo apt-get install gdb
After we install it, we need to connect to the process. Replace the <FD> with the file descriptor, but make sure to put it in quotes.
[email protected]:~$ gdb -p 4292 (gdb): call shutdown("<FD>") (gdb): quit
The (gdb): is the prompt and may appear differently. It's not part of the command. You can also call close in place of shutdown, if the polite way don't disconnect the connection. The great part is it looks you may only need to do one, so if you have more then one connection from the same client check if they are still there before bothering to kill all of them. It was a lot of fun learning how to do this, I hope it's helpful to others. As promised, full credit goes to Dankó Dávid @ https://superuser.com/a/668155/54442

Thoughts on a PHP monster

That's the first date of jwebgen.com, a monolithic PHP application whose primary class file contains 11.4k lines. No wonder i dont want to update it anymore. It did make me money in ad revenue when i kept it current, sl i should do so ething with it. I want to turn it into a Dockerized set of microservices, or at least seperate the frontend and backend. I plan to turn it into a NodeJS backend, amd frontend. The great news, is this codebase predates any knowledge of functional programming, and therefore can probably get a lot smaller and cleaner. Converting that main class will take woek though.]

Resetting Debian 9 root password when it is locked

For some odd reason my Debian 9 installed with a locked root password. This wouldn't have been a huge issue, except my user account wasn't added to the sudo group either. Here are the modified steps to gain access: Follow the directions here http://www.debianadmin.com/how-to-reset-debian-root-password.html Since grub config's are now multi-line, you want to add the init=/bin/bash to the end of the line that looks like this: search --no-floppy --fs-uuid --set=root a07d9dd4-90c3-4e50-83ab-d396e281ecad You can then remount your drive, change the password and reboot. Not sure what happened (tried the install twice), but hopefully this helps anyone else who ends up with a locked root account.

Debian non-free with firmware

Yes, we want to be free, but sometimes you need non-free firmware. Like for your wireless card. Turns out that Debian makes images containing non-free firmware, but this information doesn't seem linked anywhere on their site (or it's really nested deep) http://cdimage.debian.org/cdimage/unofficial/non-free/cd-including-firmware/ Also currently seeding debian-live-9.0.1-amd64-cinnamon+nonfree.iso because it looks like no one else is.

Selenium Testing with CircleCI 2.0

To start, the CircleCI *-browsers images don't ship with Selenium. This wouldn't be a concern if WebdriverIO didn't silently pass. https://circleci.com/gh/drazisil/webdriverio-test/3 Let's add Selenium. We have another success, except it clearly failed because we don't have any web drivers, like chromedriver and geckodriver: https://circleci.com/gh/drazisil/webdriverio-test/10 Let's download and specify geckodriver. We'll also move the log into an artifact while we are at it. https://circleci.com/gh/drazisil/webdriverio-test/14 Still failed. (passed). Also, the log doesn't exist. Hmm. Geckodriver works! https://circleci.com/gh/drazisil/webdriverio-test/15 Let's try Chrome. Chromedriver works great, once Selenium is installed and launched. https://circleci.com/gh/drazisil/webdriverio-test/17 Let's Workflows this! Perfect. https://circleci.com/workflow-run/f984272f-9994-4edb-ac93-58531cf5e459 Downloading all these things on each build isn't very efficient though. Since we are using CircleCI 2.0 with native support for Docker images, let's get this into a custom Docker image. Almost there. https://circleci.com/gh/drazisil/webdriverio-test/26#artifacts/containers/0 Let's start the Selenium server in the base Docker image though. Perfect. https://circleci.com/gh/drazisil/webdriverio-test/32#artifacts/containers/0

Settings goals

Settings some goals

I'm getting the hang of VIM, but it's not good at working on more than one file at once. Maybe Emacs will fit my needs. I love water. It's pricey, but I'm in a place where if I save regularly, I can afford this. PHP is old and slow. I want to get this working. This requires making a new MVP (minimum viable product) and not getting distracted trying to learn new things like React and Webpack. This is for mco-server, a somewhat classified chunk of madness that distils into needing a multi-user server that supports Winsock socket connections, and retains sessions while having no control over the packets the client is sending.

Asking questions

I don't ask questions unless I've already spent at least a day searching and trying to find the answer first. So why, when I ask (what I feel is) a carefully crafted question, does everyone always decide the best way to answer it is to ask 20 questions about the context and backstory details, and usually end up trying to talk me out of whatever I'm trying to do? Don't do it that way! Learn this other way which will take much longer to learn that what you know, and will result in 50 questions which will repeat the process, but will be better we swear. Why can't I get answers? Even an "I don't know the answer" would be nice. I don't think I'm that dumb, people are constantly telling me I'm pretty smart. So when I get told "That's a stupid way to do it, do it this simple way that won't work instead", after I've pushed myself to the point of feeling like a moron that I need to be in to ask the question, it really doesn't help. I'm trying the impossible. And I'm going to stop explaining it, because one, you generally don't understand, and two, I already know it's impossible, so don't try to talk me out of it. Just answer the question, or tell me you don't know. Because trying to explain that I'm being stupid only helps me feel more like that.

db:create and db:migrate, where do they come from?

I'm dipping my toe back into Ruby again and trying to learn how things work. So much of code documentation seems to be copy/paste, that it's hard sometimes to know exactly what is happening. When using Rails and Rake, a lot of times you will see the db:create and db:migrate tasks called to set up the database. I wanted to see what they did, so I went looking for them. As they are both related to Rails, I decided they had to be declared in the Rakefiles for that project. db:create https://github.com/rails/rails/blob/master/activerecord/Rakefile#L44-L48 That's part of the Rakefile for ActiveRecord, the part of Rails that handles databases. Makes sense. What about db:migrate? https://github.com/rails/rails/blob/master/railties/lib/rails/tasks/engine.rake#L29-L76 That's nested quite far down, in a .rake file for Railties. Still Rails, but a sub-module. There's no real point to this post I guess, but I love learning and wanted to share what I found in case others like to go code-diving as well. Back to learning Rspec!

My First iOS Project

hat's what I searched for on DuckDuckGo https://www.appcoda.com/learnswift/build-your-first-app.html I added a button to the storyboard, and it appears for a second, and then vanishes when I run the simulator. http://discourse.djp3.net/t/first-ios-app-button-and-label-disappear-in-simulator/104/13?u=drazisil Of course, I put it in the wrong storyboard!  

R1D10 #100DaysOfCode

Hi there! I wanted to get started better blogging, but my entry to @CodeNewbie's #CNC2018 Blog More challenge seems to have gotten lost. That said, my updates and learning for #100DaysOfCode are getting larger then I can put on Twitter, even with the expanded letter count. I want to be able to share links too! So, moving here I guess. Started the day by wanting to switch from GitBash to WSL (Windows Subsystem for Linux) as the integrated terminal in my VS Code editor since Docker volume mounts were giving me grief. I was referred to Setting Up Docker for Windows and WSL to Work Flawlessly by my fellow support engineers, and while it worked mostly perfectly, I botched my settings file changing the windows terminal and managed to completely hose my VSCode install. Turns out that you can fix everything by deleting the ~/.vscode directory, even on Windows. Postgres in Docker is working, but it still doesn't want to bind mount to the directory in my project, so any advice there would be great. It seems to want to use the system directory instead. I'm using the following command: ` docker run --name postgres -p 5432:5432 -w "$(pwd )" -v "$(pwd )"/data:/var/lib/postgresql -e POSTGRES_PASSWORD="$POSTGRES_PASSWORD" -d postgres :9.4-alpine` I've also started #Javascript30 by @wesbos. While I'm not sure I plan on creating any of the projects (we'll see) I've already learned that querySelectors are a thing, and have a much better handle on understanding CSS Transitions.  Makes me really want to move CSS Grid up my learning list and better pretend I can frontend design. I think that's it for this update. Completely offtopic, that WordPress supports backtick code blocks and lets me paste hyperlinks into text is amazing and greatly helps my writing. Lets me stick with flow and less with getting distracted with formatting.  

Copying your SSH keys from Windows to WSL

Since I switched my integrated terminal in VS Code from Git Bash to the Windows Subsystem for Linux (WSL) I discovered that my SSH keys didn't carry over.  No worries, I thought, let's just copy the .ssh directory from Windows to the Linux root on my filesystem. Turns out it's not quite that easy. First, where exactly is the Linux root? The internet seems to think it's located at %locaappdata%/lxss but I can't locate it there. I decided to use the Ubuntu terminal. cp -a /c/Users/<me>/.ssh ~ will work, right? Nope. Turns out Linux sees my Windows .ssh directory as permission 700 for all files, which makes Git (and probably everyone who lives in Linux) very unhappy. Using the answers from this SuperUser question, I settled on the following permissions:

Along the way, I researched how to get the file permissions in octal (number) form. Thanks to this AskUbuntu answer, the command stat -c "%a %n" ~/.ssh works perfectly.

Login, Interactive, non-interactive. Remembering the bash shell types

Taken directly from man bash https://linux.die.net/man/1/bash, saved here because I always forget.

Invocation

A login shell is one whose first character of argument zero is a -, or one started with the --login option. An interactive shell is one started without non-option arguments and without the -c option whose standard input and error are both connected to terminals (as determined by isatty(3)), or one started with the -i option. PS1 is set and $- includes i if bash is interactive, allowing a shell script or a startup file to test this state. The following paragraphs describe how bash executes its startup files. If any of the files exist but cannot be read, bash reports an error. Tildes are expanded in file names as described below under Tilde Expansion in the EXPANSION section. When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior. When a login shell exits, bash reads and executes commands from the files ~/.bash_logout and /etc/bash.bash_logout, if the files exists. When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists. This may be inhibited by using the --norc option. The --rcfile file option will force bash to read and execute commands from file instead of ~/.bashrc. When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute. Bash behaves as if the following command were executed: if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi but the value of the PATH variable is not used to search for the file name. If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well. When invoked as an interactive login shell, or a non-interactive shell with the --login option, it first attempts to read and execute commands from /etc/profile and ~/.profile, in that order. The --noprofile option may be used to inhibit this behavior. When invoked as an interactive shell with the name sh, bash looks for the variable ENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute. Since a shell invoked as sh does not attempt to read and execute commands from any other startup files, the --rcfile option has no effect. A non-interactive shell invoked with the name sh does not attempt to read any other startup files. When invoked as sh, bash enters posix mode after the startup files are read. When bash is started in posix mode, as with the --posix command line option, it follows the POSIX standard for startup files. In this mode, interactive shells expand the ENV variable and commands are read and executed from the file whose name is the expanded value. No other startup files are read. Bash attempts to determine when it is being run with its standard input connected to a a network connection, as if by the remote shell daemon, usually rshd, or the secure shell daemon sshd. If bash determines it is being run in this fashion, it reads and executes commands from ~/.bashrc, if that file exists and is readable. It will not do this if invoked as sh. The --norc option may be used to inhibit this behavior, and the --rcfile option may be used to force another file to be read, but rshd does not generally invoke the shell with those options or allow them to be specified. If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, no startup files are read, shell functions are not inherited from the environment, the SHELLOPTS, BASHOPTS, CDPATH, and GLOBIGNORE variables, if they appear in the environment, are ignored, and the effective user id is set to the real user id. If the -p option is supplied at invocation, the startup behavior is the same, but the effective user id is not reset.   =============================================== TL;DR:

Interactive, Login:

Interactive, Non-Login

You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

 [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build. (found in <Root>)
I got this error when I tried using vue with npm. Not using webpack, or the CLI. So I can't change any of the configs, because they don't exist.
The default export in VUE's package.json is vue.runtime.js
To change this, change your import to be `/dist/vue`
Error goes away :)

TypeScript: error TS2304: Cannot find name

error TS2304: Cannot find name 'Blob'.
                error TS2304: Cannot find name 'XMLHttpRequest'.
If you are wrecking your brain over trying to solve this error, the fix is to add "dom" to your tsconfig file:
{
                  "compilerOptions": {
                    "outDir": "dist",
                    "lib": [
                      "dom",
                      "es2015"
                    ],
                    "module": "commonjs",
                    "sourceMap": true
                  },
                  "files": [
                    "index.ts"
                  ],
                  "exclude": [
                    "node_modules",
                  ]
                }