Categories
Samuel Voluntary Discomfort

Wake Up Before 6:30 a.m. for 30 straight days

We are just about to the end of this months voluntary discomfort. The discomfort was waking up early for the whole month of February. In general we did really well, there were definitely a few days where I slept past 6:30 a.m. Once I was coming down with a cold and let myself sleep in. Another time I stayed up late drinking with friends and slept in.

But overall 95% of the days I woke up before 6:30 a.m. and I did really enjoy the amount of time this gave me to start my day. Ultimately I learned throughout this process that now I’m working for myself the time I wake up doesn’t matter as much as me following my morning ritual does. The morning rituals I started doing that really improved my mood are:

– making the bed every day. For some reason this really makes me slow down and realize I should go slow and be precise with everything for the day.
– morning workouts are just killer. I start the day with a big win, feel great about myself physically and it just puts me in a great mood for the rest of the day
– eating a full breakfast. I started the habit of drinking warm water when I first get up, followed by a protein shake in 15 or 20 mins before the workout, then after working out I’ll make eggs, avocado toast, and turkey bacon. I really love eating a big breakfast like that!
– reading in the morning, I got into the great habit of what my friend BP calls “unthawing” and a big part of that is reading to start the day. Sometimes I would read before the workout, sometimes after. Having the ability to have that variance is something I really need, I’ve found a super strict this, then this, then that activity list is not for me. Just having a general outline to how the morning will flow but allowing for the order of activity’s to change works perfectly for me.

That list pretty well sums it up, this challenge was a big success and I’m going to continue this morning ritual allowing for slack and changes in the exact wake-up time and order of activity’s since I’ve learned that’s what I enjoy the most. I’ve already decided on next months discomfort and will post back about that at the end of March.

Categories
Fixing Stuff Freenas Samuel

Fixing Freenas Boot Error

We ran into an issue today with our freenas machine, when the machine was starting we received the message:
This is a FreeNAS data disk and can not boot system. System Halted

We restarted the machine, hit F9 to enter BIOS boot setup, and selected our flash drive from the list and pressed enter. The machine then went through its normal boot up sequence, and hung up on this error:


trying to moun root from usf:/dev/ufs/FreeNASs1a
mount /dev/ufs/FreeNASs3 :No such file or directory
-o ro /dev/usf/FreeNASs3 /conf/default/etc failed: dropping into /bin/sh

we then run the command:
zpool status and it shows 0 pools avaliable

we then run the command:
zpool import -f files

this didn’t work either, it could not mount the files. Now we went searching for more help. Looking online it looks like our sand disk drive (where FreeNAS lives has gone bad). We downloaded a copy of FreeNAS From here: http://www.freenas.org/download/

Next we converted the file to be bootable using the program Win32, which can be downloaded from this page: https://launchpad.net/win32-image-writer. Click on “external downloads” button to be taken to download. Once we install Win32 we complete the following steps to make the FreeNAS file bootable:

  • launch Win32DiskImager and use its “browse” button to browse to the location of the .iso file. Insert a USB thumb drive and select its drive letter from the “Device” drop-down menu. Click the “Write” button and the image will be written to the USB thumb drive.
  • plug this USB device into FreeNAS, along with another blank USB device (we will install the operating system on the blank USB device, it can’t be installed directly onto the same USB so we will need 2 devices)
  • After we write to the jump drive I got the error “this device needs to be formatted before it can be used”. So we formatted the device using the windows default tool, and re-installed FreeNASA following the same steps outlined above….

Now were going to install the new version of FreeNAS onto our machine:

  • plug both devices into FreeNAS machine, boot the machine up and hit F12 to select boot device, choose the jump drive…. I got lucky and chose the jump drive with Freenas Installed on it on the first try
  • when we get to the install screen select “install/upgrade” then choose to install FreeNAS on the empty jump drive
  • give the device a root password (the write the root password down on a sheet of paper)
  • select to install FreeNAS with BIOS boot since our hardware is over 5 years old
  • Once the install completes, select to reboot the machine and remove the jump drive with the FreeNAS installer on it, leaving the jump drive that we installed too plugged in

Now is the moment of Truth, we fire the machine back up, let it go through the boot up sequence and hopefully it spits out the IP address we can use to access the web interface….

— Update —

We get the IP address and we can access files but once we import our volume we get a panic error to fix this we need to do:

1.) Reboot Freenas, then When GRUB loads up and asks how to boot FreeNAS, hit the letter “e” on the keyboard to edit.
2.) Go down to the SINGLE USER MODE section and insert two lines. Type in the following into the two lines.

set kFreeBSD.vfs.zfs.recover=1
set kFreeBSD.vfs.zfs.debug=1

3.) Look on the bottom of the screen for instructions. You want to boot by hitting CTRL-X or F10. When it restarts hit single user mode

4.) press enter to start /bin/sh

5.) Now you are ready to start trying to import your pools.

First pass is just trying a straight import:

zpool import -R /mnt poolname

If this works, great. Backup your data and life goes on. In our case we get the error:
can't mount files in use by another system so we run

zpool import -f poolname

If you get a panic then repeat the above steps, but try:

zpool import -o readonly=on -R /mnt poolname

If this works your pool imported read only. Backup your data and life goes on.

As a final desperation move, or after you’ve managed to import the pool readonly and copy everything off you can try:

# zpool import -R /mnt -FX poolname

The above command has a good chance of grenading your pool, but it also has a chance of importing it.

— Useful Links —

https://forums.freenas.org/index.php?threads/zfs-has-failed-you.11951/

https://forums.freenas.org/index.php?threads/unable-to-import-zfs-volume-into-freenas-11.54871/

Categories
Uncategorized

Adding Recaptcha to Laravel Project

Using this package here: https://github.com/anhskohbo/no-captcha

composer require anhskohbo/no-captcha
This gave us the error:

Could not fetch https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2 ec8b39c38cb16674bbf3fea2b6ce5bf117e1296, please create a GitHub OAuth token to g o over the API rate limit
Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+ on+laptop_01-PC+2018-02-20+2229

To fix that we simply retrieved an API token from the URL referenced in the message, pasted it into the command line and hit enter.

In app/config/app.php add the following :

1- The ServiceProvider to the providers array :

Anhskohbo\NoCaptcha\NoCaptchaServiceProvider::class,

2- The class alias to the aliases array :

'NoCaptcha' => Anhskohbo\NoCaptcha\Facades\NoCaptcha::class,

3- Publish the config file

php artisan vendor:publish --provider="Anhskohbo\NoCaptcha\NoCaptchaServiceProvider"

Add NOCAPTCHA_SECRET and NOCAPTCHA_SITEKEY in .env file :

NOCAPTCHA_SECRET=secret-key
NOCAPTCHA_SITEKEY=site-key

4- In templates frontend.blade add this snippet before /head:
{!! NoCaptcha::renderJs() !!}

5- In contact_us.blade add:

{!! NoCaptcha::display() !!}

in the actual form section:

@if ($errors->has('g-recaptcha-response'))

{{ $errors->first('g-recaptcha-response') }}

@endif

6- In The contact us controller, add the validation requirement to the array of requirements:
'g-recaptcha-response' => 'required|captcha',

7- Now we have everything installed correctly on the form, it should prevent a submission unless the recaptcha is filled out. Once submitted though the form will now error out with the error below:
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

Lets fix this error:
Go to http://curl.haxx.se/ca/cacert.pem and download the pem file and save in your php installation directory (C:\wamp64\bin\php) make sure while saving it retains the extension and not saved as a text file.

Now, open your php.ini file, scroll to the bottom and add the following line:

[cURL]
curl.cainfo="C:\wamp64\bin\php\cacert.pem"

Replace the file path above with the path to the certificate on your machine
*once you save the php.ini file restart all services on wamp*

Categories
Fixing Stuff Laravel

Laravel -Searching Multiple Database Tables

This week we had a request come in from a client that involved creating a new database column and then performing a search across multiple columns to collect and display the data to end users of the system. While completing this task we learned the following great information:

1.) DD in the new google chrome. In the latest version of google chrome we were not able to dump and die from our controller. To get around this we added the following command to our controller:


#When using dd() in an ajax call, chrome needs a response code set
http_response_code(500);
dd($results);

The code above was added in place of the normal return results that sends results data from our DB query to the view. In total for testing purposes our public function now looks like:


public function datatables()
// do stuff


#When using dd() in an ajax call, chrome needs a response code set
http_response_code(500);
dd($results);
#return $results;

Now that our controller will spit out information that we can use to test/troubleshoot we will then fire up our local environment, navigate to the view for the page we are working on and then do the following:

1.) Hit F12 to pull up the chrome developer tools.
2.) Click on Network > XHR > Preview. This should take us to a page that looks like:

Chrome Developer Tools XHR Results Preview
Chrome Developer Tools XHR Results Preview

3.) Now when we update code in our controller we can save the file then go over to chrome dev tools right click on the results link and reload to see the result of our updated code. Example screenshot is below:

XHR-Refresh-Results

2.) Now we are onto the actual query that allows us to search through multiple DB tables and organize the results. I’ve copied the query below and bolded the two new lines that allow us to get the results the client wanted.


$datatable->set_query(function($search_sql, $order_sql, $having_sql, $limit_sql, $values) use ($form_id) {

$values['form_id'] = $form_id;

$results = DB::select("
SELECT SQL_CALC_FOUND_ROWS
u.id AS user_id,
CONCAT(u.first_name, ' ', u.last_name) AS name,
ec.cell_phone,
ec.home_phone,
shift_code,
DATE_FORMAT(u.employment_began_at, '%m/%d/%Y') AS start_date,
SUM(IF(YEAR(date_in) = YEAR(CURDATE()), total_hours, 0)) AS ytd_hours,
SUM(total_hours + historical_overtime) AS total_hours

FROM

form_submissions fs
JOIN forms f ON fs.form_id = f.id
LEFT JOIN users u ON fs.user_id = u.id
JOIN fs_overtime_documentation a ON a.form_submission_id = fs.id
LEFT JOIN forms ec_form ON ec_form.slug = 'emergency_contact'
LEFT JOIN form_submissions ec_form_submission ON ec_form_submission.form_id = ec_form.id AND ec_form_submission.user_id = u.id
LEFT JOIN fs_emergency_contact ec ON ec.form_submission_id = ec_form_submission.id
WHERE
u.active = 1 AND
f.id = :form_id AND
fs.status != 'denied'
{$search_sql}
GROUP BY u.id
HAVING 1=1 {$having_sql}
{$order_sql}
{$limit_sql}
", $values);
return $results;

Expanding on on the explanation above the first line we added is the easier of the two, it takes the Sum of the total hours column if the year = our current year:

SUM(IF(YEAR(date_in) = YEAR(CURDATE()), total_hours, 0)) AS ytd_hours,

The next thing we had to do was total up hours from two different database tables. We do this with:

SUM(total_hours + historical_overtime) AS total_hours

Its important to note the only reason this works is because of the LEFT JOIN a few lines below. This join takes total_hours and historical_overtime and adds them together if the particular user has hours in their historical_overtime DB column:

LEFT JOIN users u ON fs.user_id = u.id