Thursday, August 29, 2013

Network Device Organization

Most ISPs provide customers with modem/router combination units these days, but if you find yourself with more than one device, you generally have a mess on your hands.

I have a modem, router, and switch. When these guys hang out together they tend to heat up something fierce. Being a strict administrator, I decided to separate them to stop the shenanigans.
I did this for about $1.00. 


Materials


There's a dollar store not far from my house that has a great selection of... well... everything. This includes cheap cooling racks.

> Cooling rack
> Wire cutters, metal file
> Thin hard surface


The Process


Step 1.  Cut a wire for either side of the device you want to secure, being sure to leave a wire in between

Step 2.  Bend  the cut ends up at a 45 degree angle and inwards so that it can apply firm pressure on the device it's holding

Step 3. Use your file to take off any sharp edges that may have been created when you cut the wire.

Step 4. Slide the hard surface under the cut wires and over the uncut ones.

Step 5. Put your devices in the rack and rest easy!


The Product





Tuesday, August 27, 2013

Custom Wall Shelving

I decided to install some shelves. After seeing what 'off the shelf' shelving had to offer, I thought it best if I made my own. Unfortunately this blog was an afterthought so I don't have much content in terms of process, but here it is.

The Concept


After consulting more experienced persons than myself, I was advised to secure a wooden board to the wall stud and then attach the shelving track to the board.
I've seen many shelves that run around the inside corner of a room, but I really wanted to see a shelf that wraps around the outer corner of a wall. Not only is it more interesting, but it would be a perfect spot for a digital projector. This outside cornering is only on the top shelf which is high enough that it's out of the way. If this were carried through the other shelves, it would cause several support issues as well as encroaching on a high traffic area.

Concentrating on function in my form, I chose to cut the shelf ends at 45 degree angles. This makes sure the boards are out of the way when you walk around the corner since they are flush to the edge of the wall.

look concept, suspension concept


Having the shelf run around the outside corner of a wall poses one major problem - the corner will be a significant distance away from the support. Having any weight that far out from the wall isn't a great idea and options are limited, so I chose to use metal cable to suspend the outer edge from the ceiling.


Materials


Unfortunately this section and the next are pretty bare. I have no photos, but here's the skinny.
- Knotty pine boards (cheap) making sure it was as straight, and in varying width.
- Matching brackets in sets of 3
- Metal cable
- Turnbuckles
- Rings to fix the cable to the shelf/ceiling
- Cable crimps to create fastening loops in the cable
- Screws
- Horizontal and vertical L brackets
- Shellac
- Wax

The Process


First thing is cutting everything to size. It's a good idea, so you can seal all of the cut ends when you apply your wood finish.

Preparing the wood was pretty easy. Since I wanted a nice natural look, it's just a matter of applying the shellac, allowing it to dry, and then buffing it with some wax. It looks great and it's water resistant.

I then marked off the studs in the wall, secured the boards to the studs making sure they are level horizontally, and fixed the shelving track to the boards.

Add the brackets, check the level, add a shelf, check the level, screw shelf to brackets, check the level...

Fixing the top shelf was easy, using horizontal L brackets fix the 90 degree corner, and vertical L brackets to secure the top of the shelf to the wall discreetly. After creating the cable supports (cutting that cable was incredibly difficult without the right tools), I measured, leveled, and installed them. The turnbuckles are useful for making sure the cable is nice and taught.

The Product


And there you have it. Not too far off from my original concept art. It's sturdy and the lower shelf is a nice height for a bar or perhaps a few turntables!

A small piece of scrap wood and a few extra brackets made a nice floating shelf

Wednesday, August 21, 2013

Bathroom Vanity

When I first moved into my new apartment, It came set with a small bathroom vanity mirror. I'm sure at one point it was very charming, but the years were starting to show and it looked as though it could use a little bit of elbow grease.

wave to her majesty

I started with the open shelving. Having all of your personal hygiene products left out in the open just didn't feel right.

It's a small space, so it didn't make much sense to build a door or two. I decided to go with tiny curtains instead.


Materials




> Fabric
> Iron-on Fabric Glue Ribbon
> Metal Fabric Rings
> Coat Hanger
> Tools [Drill/Dremel, Pliers, Iron, etc...]


The Process

I measured the opening of the cabinet, and taped off a piece of fabric. I added to the length for slack, and included a border around that area the size of a width of ribbon, so it can be folded back in the hem.




Then I punched in the fabric rings, spacing them evenly down the length. The extra ring on the end in the picture is to make the ends less likely to move.


I drilled a hole on either end of the inside of the cubby, and popped in the wire.
I put an extending mirror on the side where a panel was missing, and there you have it.





The Product




Sunday, August 18, 2013

Synology Diskstation Disk Checking Python Script

After purchasing a Synology Diskstation, I thought it would be a good idea to familiarize myself with the inner workings and customizations.

One feature that is useful for power users is the command line interface that is accessible through ssh.

There's a few tutorials on how to bootstrap your Diskstation and gain root ssh access, but I'm not going to be covering it in this post.

There's a bunch of tutorials on how to run a proper disk check on your system, but I thought I would write a script to do it for me.

WARNING: I wrote this for my system specifically. I did write it as generally as possible, taking user input, so it should work on almost all systems.

note: I was also unaware of the python argparse module, so it's not as elegant as it could be. I may update it in my repository, but I likely won't update this post.

At this point, I would also like to say that the Synology Diskstation is the most spectacular NAS unit on the market. It costs a little more, but it is well worth it! 


The Script

#! /usr/bin/env python2

import subprocess as sp
from datetime import datetime as dt
from os import path, geteuid, getcwd
from sys import argv, exit



def run(test):
 """
 Run the functions that comprise the disk checking routine.
 """
 rootCheck()
 continueCheck()
 print 'Volume Checking For /volume1'
 mountPoint, optMount, fileSystem = getFileSystem()
 logfile = setLogFile(test, fileSystem)
 initLog(logfile)
 logFileSystem(logfile, mountPoint, optMount, fileSystem)
 stopRunningProcesses(test, logfile)
 umountVolumes(test, logfile, optMount)
 flags = getFlags(test, logfile)
 runCheck(test, logfile, fileSystem, mountPoint, flags)
 rebootSystem(test, logfile)



def getTime():
 """
 Get the current time
 """
 now = dt.now().strftime
 time = now('%H:%M:%S')
 return time



def getDate():
 """
 Get the current date
 """
 now = dt.now().strftime
 date = now('%d/%m/%y')
 return date



def writeLog(logfile, data):
 """
 Open the specified log file, get the current time,
 print it to the screen and append it to the log.
 Close the log file.
 """
 with open(logfile, 'a') as outFile:
  time = getTime()
  print '%s ->  %s' % (time, data)
  outFile.write('%s ->  %s\n' % (time, data))
  outFile.close()



def initLog(logfile):
 """
 Open the specified log file, get the current time/date,
 print it to the screen and append it to the log file with a
 --- START LOG --- opening tag. Close the file.
 """
 with open(logfile, 'a') as outFile:
  time = getTime()
  date = getDate()
  dateTime = '%s  %s' %(date, time)
  print dateTime
  print 'Starting Log: %s' % logfile
  startLog = '\n\n%s\n--- START LOG ---\n\n' %dateTime
  outFile.write(startLog)
  outFile.close()



def closeLog(logfile):
 """
 Open the specified log file, get the current time
 print it to the screen and append it to the log with a
 --- END OF LOG --- tag. Close the file.
 """
 with open(logfile, 'a') as outFile:
  time = getTime()
  print 'End Log: %s' % logfile
  endLog = '\n\n%s\n--- END OF LOG ---\n' %time
  outFile.write(endLog)
  outFile.close()



def exitError(logfile, err):
 """
 Write to the specified log file the given error (err) message.
 Close the file, and exit the script.
 """
 writeLog(logfile, err)
 closeLog(logfile)
 exit(err)



def rootCheck():
 """
 If the current user id is not root, exit.
 If the current working directory is not /, exit.
 """
 if geteuid() != 0:
  err = 'This script must be run as the root user!\nExiting Now.'
  exit(err)
 if getcwd() != '/':
  err = 'This script must be run from \'/\'!\nExiting Now.'
  exit(err)



def continueCheck():
 """
 Prompt the user with a warning, ask for confirmation before continuing.
 If 'n', exit the script. If 'y', continue.
 """
 proceed = 'x'
 warning = "\n\
 WARNING: THIS PROGRAM STOPS FILESYSTEM PROCESSES AND UNMOUNTS VOLUMES!\n\
          PLEASE MAKE SURE YOU'VE STOPPED ALL RUNNING PROCESSES\n\
          AND DISCONNECTED FROM NETWORK SHARES BEFORE YOU CONTINUE.\n\
          THE SYSTEM WILL REBOOT TO COMPLETE THE PROCESS.\n\
  (it's also recommended that you disable your system beep temporarily)\n\
 "
 print warning
 while proceed not in ['Y','y','N','n']:
  proceed = raw_input('Are you sure you want to continue? (y/n): ')
 if proceed == 'n' or 'N':
  exit('Maybe next time. Take it easy.')
 if proceed == 'y' or 'Y':
  print 'Continuing...\n\n'



def getFileSystem():
 """
 Get the mounted volume information from the system.
 Check for /volume1 and /opt. If they don't exist, exit.
 Return the mountPoint, optMount, fileSystem of /volume1.
 """
 system = sp.check_output('mount').split('\n')
 optMount = 0
 for mount in system:
  try:
   if '/volume1' in mount:
    if not '/opt' in mount:
     volumeInfoList = mount.split(' ')
     mountPoint = volumeInfoList[0]
     fileSystem = volumeInfoList[4]
    if '/opt' in mount:
     optMount = 1
  except:
   err = 'Can\'t find volume1!!' 
   exit(err)
 return (mountPoint, optMount, fileSystem)



def setLogFile(test, fileSystem):
 """
 With the specified fileSystem and test value, check for/create the
 /log directory and a log file of either fsck.ext4.log, e2fsck.log,
 or test.log.
 Print the results to the screen and return logfile.
 """
 logdir = '/log'
 if not path.exists(logdir):
  print 'Log directory %s does not exist. Creating it now.' % logdir
  try:
   sp.check_output(['mkdir', logdir])
   print 'Directory successfully created.'
  except:
   exit('Something went wrong.')
 if test:
  logfile = '%s/test.log' % logdir
 else:
  if fileSystem == 'ext4':
   logfile = '%s/fsck.ext4.log' % logdir
  if fileSystem == 'ext2':
   logfile = '%s/fsck.ext2.log' % logdir
 if not path.exists(logfile):
  print 'Log file does not exist. Creating it now.'
  try:
   sp.check_output(['touch', logfile])
  except:
   exit('Something went wrong.')
 print 'Log directory: %s' % logdir
 print 'Log file: %s' % logfile
 return logfile



def logFileSystem(logfile, mountPoint, optMount, fileSystem):
 """
 Write the system information to the given log file.
 """
 if not optMount:
  writeLog(logfile, '/opt Mount: No')
 writeLog(logfile, '/opt Mount: Yes')
 writeLog(logfile, 'Mount Point: %s' % mountPoint)
 writeLog(logfile, 'File System: %s' % fileSystem)



def stopRunningProcesses(test, logfile):
 """
 Stop the file services specified in the list.
 Log the service as it's stopped.
 If it's a test, log the command but do not execute.
 """
 fileServiceList = ['S25download.sh', 'S20pgsql.sh', 'S80samba.sh', 'S83nfsd.sh', 'S81atalk.sh']
 serviceDir = '/usr/syno/etc/rc.d/'
 cmd = 'stop'
 writeLog(logfile, 'Running Commands:') 
 for fileService in fileServiceList:
  if path.exists('%s%s' %(serviceDir,fileService)):
   service = '%s%s' %(serviceDir, fileService)
   stopService = '%s %s' %(service, cmd)
   if test:
    writeLog(logfile, stopService)
   else:
    try:
     writeLog(logfile, stopService)
     sp.check_output([service,cmd])
    except:
     err = 'Error Stopping Processes!\nSomething went wrong...'
     exitError(logfile, err)



def umountVolumes(test, logfile, optMount):
 """
 Unmount the volumes /volume1 and /opt (if available).
 Append to the log. If it's a test, log the command but do not execute.
 """
 writeLog (logfile, 'Unmounting volumes...')
 if test:
  writeLog (logfile, 'umount /volume1')
  if optMount:
   writeLog (logfile, 'umount /opt')
 else:
  writeLog (logfile, 'umount /volume1')
  sp.check_output(['umount','/volume1'])
  if optMount:
   writeLog (logfile, 'umount /opt')
   sp.check_output(['umount','/opt'])



def getFlags(test, logfile):
 """
 Set the fsck flags to p (auto-fix), v (verbose), f (force).
 If it's a test, change p to n (no action).
 If not the default flags, enter the desired sequence.
 Log and print the flags.
 """
 if not test:
  useDefault = 'x'
  while useDefault not in ['y','Y','n','N']:
   useDefault = raw_input('Use the default -pvf flags for the disk check? (y/n): ')
  if useDefault in ['y','Y']:
   flags = '-pvf'
  else:
   sp.check_output(['fsck.ext4'],['--help'])
   flags = raw_input('Please specify the flags you would like to use.\n\
   (example: -nvf): ')
 else:
  flags = '-nvf'
 writeLog(logfile, 'Using flags: %s' % flags)
 return flags



def runCheck(test, logfile, fileSystem, mountPoint, flags):
 """
 Choose the correct checking system given the file system provided.
 ext2 and ext4 are supported. Other systems will exit the script.
 Log the running command, run the command and
 write the output to the logfile.
 """
 if fileSystem == 'ext4':
  checkCommand = 'fsck.ext4'
 elif fileSystem == 'ext2':
  checkCommand = 'e2fsck'
 else:
  err = 'Unrecognized file system!\nSomething went wrong!' 
  exitError(logfile, err)
 running = 'Running Command: %s %s %s' % (checkCommand, flags, mountPoint)
 writeLog(logfile, running)
 if test:
  writeLog(logfile, 'sp.check_output([checkCommand,flags,mountPoint])')
 else:
  writeLog(logfile, sp.check_output([checkCommand,flags,mountPoint]))

  

def rebootSystem(test, logfile):
 """
 Log the reboot step and close the logfile.
 If it's not a test, reboot the system.
 """
 writeLog(logfile, '* Rebooting System *')
 if test:
  closeLog(logfile)
 else:
  closeLog(logfile)
  sp.check_output('reboot')



if __name__=="__main__":
 test = 0
 help = "\n\
 SYNOCHK HELP!\n\
 Usage: [python] synochk [-h, -t]\n\
 \n\
         You will be prompted later for flags relating to the disk checking process.\n\
 \n\
         Synochk must be run as the root administrator from the root directory '/'.\n\
 \n\
 [Invalid Flags]  Bring up this help dialog\n\
 -t, -test        Run synochk in 'test' mode. Your file system will not be modified.\n\
                  Test mode will create a test.log file and log the results of the test.\n\
 -d               Display the disclaimer\n\n\
 "

 disclaimer = 'DISCLAIMER:\n\
 The author of this script is not responsible for any damage\n\
 caused during it\'s execution. There are many safeguards in place\n\
 to prevent harm, and let\'s be honest, if you\'re using this script\n\
 in an ssh shell, you probably know what you\'re doing.\n\
 Synology does not support any tampering in the terminal.\n\
 Neither does the author.\n\
 Play safe.\n\n\
 Peace in the middle east,\n\t\t\t- The Author\n\n'

 testMode = '\n\nTEST MODE ENABLED!\nYOUR SYSTEM WILL NOT BE MODIFIED.\n' 

 if len(argv)>2:
  exit(help)
 if argv[1] not in ['-t','-T','-test','-TEST']:
  exit(help)
 if argv[1] in ['-d','-D']:
  exit(disclaimer)
 if argv[1] in ['-t','-test']:
  print testMode
  print disclaimer
  test = 1

 test = 1
 run(test)

Desktop Wire Organization

When setting up my desktop computer, I noticed that the tabletop was too thick for the old bulldog/binder clip solution like the one shown at Lifehacker, Luckily I happened across a nice large spring! Holding wires is amazingly convenient.


The Process


Fixing the coil to the desk is simple and doesn't damage the tabletop. I used a plastic-coated coat hanger bent into a square 'C' shape to hug the surface snugly. I left some extra length on the top which I bent back to fit around one of the coils, holding it in place.



Before securing the spring to the top of the desk, you should consider the frequency you use the wires and for what function. 


 

Wires that are heavier and tend to lift up and wires that are meant for desktop use only, are placed between the desk and the spring, preventing the wires from lifting, though a gentle pull will release some slack allowing you to plug it in to the desired peripheral.

For wires that need to move away from the desk for use, you simply place it on top of the spring, sliding it in between the coils.




Pretty Nice, right? It works like a charm! While I was at it I thought it might be a good idea to make another clip to holster my headphones, which also proved to be quite useful.


Enjoy!