Hackviking He killed Chuck Norris, he ruled dancing so he took up a new hobby…

21Jul/170

Transfer Google Drive and photos between accounts

I ended up finally transferring everything from my old gmail.com based Google account over to my custom domain Google account. I have been running them in parallel for ages switching between them to access different services. I read a number of blog posts and forum discussions on how to do this, also took a look at Googles own documentation.

According to Google you can merge two Google accounts but only if both our in the same organisation. And since my "new" one was the only one actually in an organisation and the other one isn't this wasn't an option. I couldn't figure out, from the documentation alone, if merging two gmail.com based Google accounts are possible or if it has two be two proper organisation/custom domain accounts.

Google Drive

Started out with Google Drive by sharing all my files from one account to the next. Then I could just copy the files on the new account. The issue I ran into was that then all the filenames started with "copy of". I didn't want that so I started looking at other options.

Looked at the API with the plan to create a script that shared everything from the first account and then copied it on the second one. The kicker would be to remove the "copy of" part of the name on all the files.  I started messing around with the Javascript library provided by Google but didn't find an easy way to authenticate two accounts at the same time. Didn't wan't to spend to much time on it so I moved on.

By just selecting all the files and select download I received a zip file with all my files. Most of my files has been created on Google Drive with the built in apps and they got converted to excel and word respectively when downloaded. Then I downloaded the Google Drive app for windows, made sure I turned on the "convert uploaded files to Google..." option and then just dropped all the files in there.

Google Photos

This was a bit more tricky then Google Drive. I found a nice option of sharing my entire repository between the accounts and could set the new account the automatically save the shared photos to it's of repository. It did how ever take ages so I quit that and just used Google Takeout to download two huge zip files with all my photos. I then configured the Google Drive app to backup the folder with the unzipped content and add photos and videos directly to Google Photos.

Yes I lost all my albums but the improvements of the Google Photos Assistant gives my correct suggestions for creating albums matching my trips and events daily now.

20Jul/170

Free SSL certificates

StartSSL certificates isn't trusted by several major browsers anymore and will probably lose all credibility and disappear from the market completely. In it's place we have seen Let's Encrypt growth explode for the last 18 months. This post will cover some background and how to use setup Let's Encrypt on your Amazon EC2 Apache based server.

Continue reading...

20Mar/170

Kodi central db backup

Using a central database for all your Kodi media players is convenient. Only one of them need to scan for new content or you can even update the database straight away. It holds state across all the devices like paused movies, watched episodes etc. If you have a large library it takes time to scan it all again so you should keep it backed up. I didn't but now I do!

Continue reading...

14Mar/170

Windows: Set DNS and add to domain from command line

Just got 18 virtual servers delivered from a private cloud supplier. Since none of them are joined to our domain I need to access them one by one and set them up. After they are joined to the domain it's easier to manage them. So I wanted a quick way to add our internal DNS servers and add them to the domain. Doing this manually is a time consuming task, error prone and straight up boring. So by doing this from the command line I could do it fast, correct and less boring.

Continue reading...

6Mar/170

Free in flight Wifi

For the last year and a half I have been flying back and forth between Sweden and San Francisco. Most of the airlines I fly have in flight Wifi for a cost. Usually I think it's pretty reasonable money for the 11 hours or so I get a connection. But when ever I get bored I need a challenge and I have found several ways to get around the payment wall.

Most airlines are pretty bad at blocking things like SSH proxy's on unexpected ports or DNS tunneling. I realize that most people don't know how to do that or have a linux box around that responds to SSH on all different kind of ports. There is a few other tricks you can do as well.

Last time I flow from San Francisco to Frankfurt I found that I could either pay or login with my account. Since I had an  account since before I opted for the "Reset my password" link  and entered my e-mail. How would I be able to get my password? Didn't have any internet connection yet. Would they unblock the common ports for e-mail apps? No they unblocked everything for 20 minutes. Enough for me to download an audio book and chat with my wife on Skype. Then it blocked again...

But I forgot to download my password, right... So I did a reset again and chatted with my wife for another 20 minutes for free. Third time it directed me to call customer support but at least I got 40 minutes of free internet. After getting back to Sweden I Googled it, I couldn't have been the only one that found this, right?

Didn't find as much info as I thought I would on different travel forums that I frequent but there were a few posts. One similar to mine is this one GENIUS FLIGHT HACK: Free Wi-Fi on US Air, AA, Delta, and More! It's basicly the same principal but for downloading the airline app instead.

So if you just want to check something quickly or download something to listen to this is an easy way to get around the payment firewall. From a legal point of view I can't really see any issues since they allow you any type of internet access after sending the "Reset my password" form. Their mistake is to open up all ports instead of just e-mail ports and browsing to the most common webmails.

1Mar/172

RaspberryPI: Print server

The goal for this build was to create a print server for my Brother HL-110 and Dymo LabelWriter 450 that could be used by both Mac and Windows. It turned out to be more tricky then I expected! After some research, testing and re-installs I came up with a solution that worked. It involves compiling drivers, setting up CUPS and samba to get all the parts to work properly.

Continue reading...

24Aug/160

Reset Windows 10 password

Upgraded one of my laptops to Windows 10 and immediately locked the admin account. Googled and found a bunch of suggestions using the Windows 10 install CD? As most other people I upgraded via the Windows 10 upgrade notice that was bugging me for months. So how do you get back into a Windows 10 machine you locked your self out of?

Before the upgrade I decrypted my boot disk and uninstalled the old Truecrypt install I had on there so accessing the disk wasn't an issue. If you have full disk encryption enabled you will not be able to use this method.

Prepair Hiren's BootCD & Boot

Hiren's BootCD contains a miniXP version that is perfect for this. Download it and follow the instructions in Launching Hiren's BootCD from USB Flash Drive. They have a really good step by step guide there. Once that is all done restart your computer from the USB drive and select "Mini Windows XP".

Prepare for password reset

Once you are booted up locate your windows boot drive. In this example I will use E:\ as the Windows boot drive. Locate the following file:

E:\Windows\System32\utilman.exe

Rename it to:

E:\Windows\System32\utilman.exe.bak

Then make a copy of:

E:\Windows\System32\cmd.exe

And rename it to:

E:\Windows\System32\utilman.exe

You can also do this via the command prompt like this:

move d:\windows\system32\utilman.exe d:\windows\system32\utilman.exe.bak
copy d:\windows\system32\cmd.exe d:\windows\system32\utilman.exe

Then reboot your computer and let it start Windows 10.

Change the password

Once at the login screen press CTRL+ALT+DEL and click the icon for the "Utility Manager" in the lower right hand corner. This should launch a command prompt with admin rights. Just type in the following commands:

net user <username> /add
net localgroup administrators <username> /add

This will add a new account to the local admin group. Then close the command prompt and login with the new account, the password will be blank.

Clean up

Delete the C:\Windows\System32\utilman.exe and rename the utilman.exe.bak back to utilman.exe

23Aug/160

AngularJS: Drag & Drop

Implementing drag and drop in AngularJS is pretty straight forward using directives. This also makes the code re-usable throughout your app and/or other projects as well. As always there is a few fays of accomplishing this and the number of plugins available are many. If the plugins doesn't perform what you need you can easily write your own directives to take care of this. All the examples I found out there didn't take care of updating the actual data set in the background. One even did DOM manipulation outside of AngularJS which is a big NO NO! Just taking the DOM element and removing it from one div and adding it to another doesn't really help much when manipulating data in a webapp.

Background for this example

So we have two lists that we want to drag and drop between. In this case they are hard coded but it can be something retrieved from a REST API for example. Whenever we drag an item to a new list we need to update the data set. If we then chose to send the update up to the server directly or wait for the user to hit the "save" button is a different story. So for this example I just created a basic data set like this:

var dataModel = {
  'reds': [{
    'id': 'red1',
    'text': 'This is red 1'
  }, {
    'id': 'red2',
    'text': 'This is red 2'
  }],
  'greens': [{
    'id': 'green1',
    'text': 'This is green 1'
   }, {
    'id': 'green2',
    'text': 'This is green 2'
   }]
}

We then create a controller and bring in the data simply like this:

app.controller('DragDropCtrl', function($scope) {
    $scope.data = dataModel;

That gives us the ability to use ng-repeat to display the data like this:



<div ng-app="dragDrop" ng-controller="DragDropCtrl">

<div id="reds" class="list red" droppable>

<div class="item" id="{{ item.id }}" ng-repeat="item in data.reds" draggable>
    {{ item.text }}
   </div>

  </div>


<div id="greens" class="list green" droppable>

<div class="item" id="{{ item.id }}" ng-repeat="item in data.greens" draggable>
     {{ item.text }}
    </div>

  </div>

That will be the base for our drag and drop example. As you can see in the HTML above we have the directives droppable and draggable applied to the list and the items. These directives uses native javascript functions to make the items draggable the lists able to accept drops. The draggable directive is the most straight forward, it looks like this:

app.directive('draggable', function() {
  return function(scope, element, attrs) {
    // Get the native element
    var el = element[0];
    el.draggable = true; // Make dragable
    
    // Add event listeners
    el.addEventListener(
      'dragstart',
      function(e) {
        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('item_id', this.id);
        e.dataTransfer.setData('origin_id', el.parentElement.id);
        this.classList.add('dragging');
        return false;
      }, false
    );

    el.addEventListener(
      'dragend',
      function(e) {
        this.classList.remove('dragging');
        return false;
      },
      false
    );
  }
});

It just uses basic javascript functionality to make the object, in this case a fiv, draggable and attaches the ID as the data payload. It's the droppable directive that is the more interesting one and actually communicates back to the scope and in turn the controller. The droppable directive looks like this:

app.directive('droppable', function() {
  return function(scope, element, attrs) {
    // Get the native element
    var el = element[0];
    
    // Add event listeners
    el.addEventListener(
      'dragover',
      function(e) {
        e.preventDefault(); // Allow the drop
        
        // Set effects
        e.dataTransfer.dropEffect = 'move';
        this.classList.add('dragover');
        return false;
      }, false
    );

    el.addEventListener(
      'dragenter',
      function(e) {
        this.classList.add('dragover');
        return false;
      }, false
    );

    el.addEventListener(
      'dragleave',
      function(e) {
        this.classList.remove('dragover');
        return false;
      }, false
    );
    
    el.addEventListener(
      'drop',
      function(e) {
        this.classList.remove('dragover');
        
        // Get the data
        var destination = this.id;
        var item_to_move = e.dataTransfer.getData('item_id');
        var origin = e.dataTransfer.getData('origin_id');
        
        // Call the scope move function
        scope.MoveItem(origin, destination, item_to_move);

        return false;
      }, false
    );
  }
});

All this is also basic javascript for drag and drop functionality. The interesting part here is when we call the MoveItem function on the scope. The scope comes from the controller containing the list of items. So we need to define the function below on the controller scope to make this work. One thing to remember here is to be able to re-use this code throughout our application the controller scope must define this function where these directives are used.

$scope.MoveItem = function(origin, dest, item_id) {
  // Check if dropped in origin
  if (origin == dest) return;
  
  // Find item in origin array
  for (i = 0; i < $scope.data[origin].length; i++) {
    if ($scope.data[origin][i].id == item_id) {
      // Splice the item from the origin array
      var item = $scope.data[origin].splice(i, 1);
      // Push to the destination array
      $scope.data[dest].push(item[0]);
      // End loop
      break;
    }
  }
  
  // Update UI
  $scope.$apply();
}

So we basically manipulate the two arrays of items depending on the drag and drop direction. Since this was called from the directive we have to call the $apply() function on the scope so the update gets pushed to the UI. Depending on your data setup this can be handled id a service as well, the basic principal is the same.

This demo example is available on JSFiddle - AngularJS - Drag and Drop

18Aug/160

Google Compute Engine: Monitor disk usage with Stackdriver

Setting up monitoring of your cloud servers are not only useful to get alerts when a server goes down or run out of disk. It's also very good to have historical data over performance metrics when troubleshooting issues. In this post I cover the basic setup and issues you can run into using Stackdriver for monitoring your Google Compute Engine servers. There are several Stackdriver features already plugged into the Google Cloud, we will focus on monitoring. Keeping track of our virtual infrastructure and use. Out of the box, just by enabling monitoring in the Google Cloud console, it will collect 5 basic metrics for all your instances.

  • CPU Usage
  • Disk Read I/O
  • Disk Write I/O
  • Network Inbound Traffic
  • Network Outbound Traffic

To get to a basic monitoring level we need at least memory and disk usage. Then we can start to look into more metrics in regards to applications and their performance.

Monitoring agent

To be able to collect these metrics we need to install the Stackdriver agent on the servers. Google have install instructions for the agent in their documentation where you can get a basic understanding of the whole setup process. It's actually very straight forward as long as you didn't change any of the "Cloud API access scopes" when you created the VM. If so make sure that your VM have at least "Write only" for the "Cloud Monitor API". Then you can just download the agent from the link in the install instructions and you will see additional metrics come in. The additional metrics are:

  • Memory usage
  • Open TCP connections
  • Page File Usage
  • Volume Usage (disk usage)

Issues with Volume Usage (disk usage)

So far I have installed the agent on 20 windows machines and all of them report all additional metrics except for the the disk usage.  In high through put and data intensive solutions this is one of the most important metrics. After ours of trouble shooting and browsing of documentation and forums I realized that I'm not the only one having the problem but no one had a good solution for it.  I then noticed that the download link for windows in the install instructions was named stackdriverInstaller-GCM-17.exe while the latest I could find directly from Stackdriver was stackdriverInstaller-39.exe. This leads me to believe that the versioned linked from the install instructions are outdated.

The GCM branded one is an automatic install, no input needed. The one downloaded from Stackdriver needs the API key to install. I couldn't find a good download page on the Stackdriver homepage but after Googling found a Support Center entry linking to their repo. At the same time this entry is from April 21st 2015 it seems to be outdated. I did however try different version numbers on the download link and 39 seems to be the latest one. Anyhow it's much never then 17 at least, but as stated in the Google install instructions their is no way to check the current version of the Stackdriver agent currently installed on windows.

Enough about that! This install requires you to input your Stackdriver API key. If you open up the Stackdriver web-ui via the link in the Google Cloud Console and go under "Account settings" and "Agent" you will find it there. Account settings are found under the project dropdown next to the Stackdriver logo in the top left corner of the UI. Just copy the "Key" and past it into the install wizard.

Dashboards and filtering

Now you can create dashboards with different metric charts to get a good overview of your system. The charts can be filtered on resource name via regex. So far I have not been able to filter out specific drive letters. In the view, as well as the underlying JSON, the data is in the format of {instance name}(C:) for example. So a regex like ^.*\(C:\) should match all C:\ drives but it doesn't work. It's not a big issue but there is a few improvements that I hope will come shortly. We have to remember that at this point Stackdriver functionality comes to Google Cloud as beta and does not have any SLA at all.

15Aug/160

Visual studio: Dump data to file from immediate window

Friday afternoon I started a test run against an API to sort some file issues out. Saving the result in a List<string> while running to dump it out to a text file when done. Due to bad formatting of the filename I got an unhandled exception. Quick test code doesn't always include try-catch statements where they should as you know. Since the the information was in the list I went ahead and dumped it out to a new text file via the immediate window.

You can more or less run any code via the immediate window as long as everything you need are in the current context. I wrote a short example on how to do this if you ever run into the same issue. Immediate-window-demo on Github.