Ajitabh Pandey's Soul & Syntax

Exploring systems, souls, and stories – one post at a time

Category: FLOSS

About Free/Libre/Open Source Software

  • Expanding HardDisk of VirtualBox Guest

    VirtualBox is a beautiful piece of virtualisation software created for users, first acquired by Sun and then by Oracle as a part of Sun acquisition. I have been using VirtualBox for quite a few testing projects, however until today have never needed to expand my hard drive on a guest. I am running a Windows 7 guest for some client side related tests. I started with a 25Gb disk for Windows 7, but after applying all security patches (I like my machines patched and upto-date), I realised that 25GB is all gone.

    This is where I love virtualisation. I do not need to buy a new disk if I need more space on my virtual machine (as far as my physical disk has enough space). I can just expand the existing virtual hard disk and get all the space I need. VirtualBox does not yet have a GUI option to do storage expansion work, but fortunately VirtualBox comes with an excellent command line, so I followed the following steps in order to increase my hard drive space.

    In order to see the virtual hard disk info, following command can be used.

    $ VBoxManage showhdinfo VirtualBox\ VMs/Win764/Win764.vdi
    UUID: e2272600-df31-4dbc-a71d-56af5f5714df
    Parent UUID: base
    State: created
    Type: normal (base)
    Location: /Users/ajitabhp/VirtualBox VMs/Win764/Win764.vdi
    Storage format: VDI
    Format variant: dynamic default
    Capacity: 25600 MBytes
    Size on disk: 25502 MBytes
    In use by VMs: Win764 (UUID: 1beda97f-4222-49ad-993e-342e1d44e288)
    

    To expand this to 50GB and then verify that the operation is done

    $ VBoxManage modifyhd --resize 50000 VirtualBox\ VMs/Win764/Win764.vdi
    0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
    $ VBoxManage showhdinfo VirtualBox\ VMs/Win764/Win764.vdi
    UUID:           e2272600-df31-4dbc-a71d-56af5f5714df
    Parent UUID:    base
    State:          created
    Type:           normal (base)
    Location:       /Users/ajitabhp/VirtualBox VMs/Win764/Win764.vdi
    Storage format: VDI
    Format variant: dynamic default
    Capacity:       50000 MBytes
    Size on disk:   25502 MBytes
    In use by VMs:  Win764 (UUID: 1beda97f-4222-49ad-993e-342e1d44e288)
    

    Now so far we have only been able to expand the Hard disk drive, but the partition table still would say that the NTFS filesystem is still the original size. However, we can not use Windows to expand the partition table of the same partition wherein it is installed. The System Rescue CD came to help here. I attached the System Rescue CD ISO to the windows virtual machine and booted the system.

    In the command prompt, I used the GNU parted to expand the partition table (partition 2 in my case)

    % parted resizepart 2 50GB /dev/sda
    

    In case you want to check which is your NTFS partition, which you want to expand use the following command –

    % parted print /dev/sda
    

    After expanding the partition table, we need to expand the NTFS filesystem on it, which can be done by ntfsresize utility as below. First I ran the utility in info mode to find out the exact size to which to expand to and then in dry run (test) mode and finally actually ran it.

    % ntfsresize --info /dev/sda2
    % ntfsresize -n -s 52294093824 /dev/sda2
    % ntfsresize -s 52294093824 /dev/sda2
    

    Finally remove the the System Rescue CD ISO file and boot the system normally in windows, a check will be force and you are done.

  • Build An MP3 Catalogue System With Perl – Conclusion

    In the last post we saw how to read ID3v1 and ID3v2 tags using perl. In this post we will continue our journey towards creating a simple catalog for the MP3 collection.

    Quickly Getting the Desired Information out of the MP3 – autoinfo()

    Usually in my catalog I am interested in the following information about an MP3 – Title, Artist, Album, Track, Year, Genre, Comment and the Artwork. However, I do not want to loop through all available information in my program to get this data. Fortunately the MP3::Tag module provides a autoinfo() function which gets almost all the information needed for us except the Artwork, which we may need to gather separately. The autoinfo() function returns the information about the title, album, artist, track, tear, genre and comment. This information is obtained from ID3v2 tag, ID3v1 tag, CDDB file, .inf file and the mp3 filename itself, where-ever it is found first. The order of this lookup can be changed with the config() command. I want to restrict my cataloging to only ID3v2  and ID3v1 tags.

    Following lines provides us with the needed information.

    $mp3->config("autoinfo", "ID3v2", "ID3v1");
    my ($title, $track, $artist, $album, $comment, $year, $genre) = $mp3->autoinfo();

    Getting Artwork Information

    The artwork information is stored in the ID3v2 tag in a frame called APIC (stands for Attached PICture). This frame has _Data and MIME Type which we would need for our purpose. In order to extract this frame and its data we do not need to loop in through all the tags. The MP3::Tag module provides us with the get_frame() method, using which we can extract any frame directly like as shown below for artwork –

    my $apic_frame = $mp3->{ID3v2}->get_frame("APIC");
    my $img_data = $$apic_frame{'_Data'};
    my $mime_type = $$apic_frame{'MIME type'};

    This $img_data can be written out in a file and the $mime_type can be used as an extension. Thus we can extract the artwork from the MP3 file. The MIME type is something like “image/jpeg” and I have used the split function to get the string for the extension of the file.

    my ($mime1, $mime2) = split(/\//, $mime_type);
    my $artwork_name = "artwork.$mime2";
    open ARTWORK_FILE, ">$artwork_name" 
      or die "Error creating the artwork file";
    binmode(ARTWORK_FILE);
    print ARTWORK_FILE $img_data;
    close ARTWORK_FILE;

    Generating the HTML using HTML

    This is a simple project so I have used HTML::Template module to generate HTML code to the standard output, which can then in turn be redirected to a file using shell redirection. For a making the table layout less cumbersome, I have used the purecss.io CSS framework. Here my HTML template code.

    my $template = <<HTML;
    <html>
    <head>
    <title>My MP3 Catalog</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.5.0/pure-min.css">
    </head>
    <body>
    <h1>My MP3 Collection</h1>
    <table class="pure-table pure-table-horizontal">
        <thead>
            <tr>
                <th>Album Artwork</th>
    			<th>Album</th>
                <th>Track</th>
                <th>Title</th>
                <th>Artist</th>
    			<th>Year</th>
    			<th>Genre</th>
    			<th>Comment</th>
            </tr>
        </thead>
    
        <tbody>
    		<!-- TMPL_LOOP NAME=SONGS -->
    		<tr>
    			<td><a src="<TMPL_VAR NAME=FILEPATH>"><img src="<TMPL_VAR NAME=IMG>" height="150" width="150"/></a></td>
    			<td><!-- TMPL_VAR NAME=ALBUM --></td>
    			<td><!-- TMPL_VAR NAME=TRACK --></td>
    			<td><!-- TMPL_VAR NAME=TITLE --></td>
    			<td><!-- TMPL_VAR NAME=ARTIST --></td>
    			<td><!-- TMPL_VAR NAME=YEAR --></td>
    			<td><!-- TMPL_VAR NAME=GENRE --></td>
    			<td><!-- TMPL_VAR NAME=COMMENT --></td>
    		</tr>
    		<!-- /TMPL_LOOP -->
        </tbody>
    </table>
    
    </body>
    </html>
    HTML
    my $tmpl = HTML::Template->new(scalarref => \$template);

    Complete Script

    The complete script is on github, you can have a look at –

    https://github.com/ajitabhpandey/learn-programming/blob/master/perl/id3-tags-manipulation/genCatalog.pl.

  • Raspberry Pi Wireless Device Power Off

    I use my device as headless as a home server and as a jump box. From past quite some time I was noticing that my Raspberry Pi was not accessible over the network after some period of in-activity. And since it is headless, the only way to get the network back was either take out the USB Wireless adapter or Reboot the Pi (through the power switch). I chose to take out the adapter and reseat it. However, this was causing my RPi to reboot also, may be because in the process the power connector was getting disturbed. I will revisit this point later.

    In order to switch off the power saving for my wireless device I tried

    $ sudo iwconfig wlan0 power off
    Error for wireless request "Set Power Management" (8B2C) :
        SET failed on device wlan0 ; Operation not permitted.

    I am using NetGear USB wireless adapter and it load the kernel module 8192cu. Checking

    $ cat /sys/module/8192cu/parameters/rtw_power_mgnt 
    1

    I realized that the power saving is still on (1 indicates minimum power saving). So I created a module config file as below to permanently set the power saving to 0 and rebooted the RPi.

    $ sudo vi /etc/modprobe.d/8192cu.conf 
    # Disable the power management during boot - Ajitabh
    options 8192cu rtw_power_mgnt=0
    $ sudo reboot

    Checking again confirmed that the power management has been disabled.

    $ cat /sys/module/8192cu/parameters/rtw_power_mgnt 
    0
  • Build An MP3 Catalogue System With Perl – Basics

    My mp3 collection was increasing and I wanted to build a catalogue for the same. There are various steps in having even a simple catalogue system. In this post and a few posts that will follow, I will be explaining how to write such a system using perl as the programming language.

    MP3 Format and ID3 Tags

    MP3 is an audio coding format for digital audio. The audio data in this file is in a compressed format. The compression is a lossy compression, meaning the sound quality is not very clear. In spite of being a lossy format, it is one of the most popular format for audio streaming and storage. The mp3 file has built in bibliographic information such as title, artist, album. This information is stored in a field inside the file known as ID3 tag. Using this information, the MP3 players are able to display the Song Title, Album name and Artist name(s) etc.

    There are couple of versions of these ID3 tags in use. ID3v1 (1.1 being the last in version 1 series) and ID3v2 (ID3v2.4 being the latest version).

    Perl MP3::Tag Module

    The MP3::Tag module of perl can be used to read and write both the versions of the ID3 tag. Here are few of the sample perl programs to do that. This will help in understanding the usage of the modules before we proceed to the next steps.

    Below are couple of examples showing how to read ID3v1 and ID3v2 tags.

    #!/usr/bin/perl
    #
    # id3v1_read.pl
    #
    use 5.010;
    use warnings;
    use strict;
    use MP3::Tag;
    
    # set filename of MP3 track
    my $filename = "your_mp3_file";
    
    # create new MP3-Tag object
    my $mp3 = MP3::Tag->new($filename);
    
    # get tag information
    $mp3->get_tags();
    
    # check to see if an ID3v1 tag exists
    # if it does, print track information
    if (exists $mp3->{ID3v1}) {
      #$mp3->{ID3v1}->remove_tag();exit;
    
      say "Filename: $filename";
      say "Artist: " . $mp3->{ID3v1}->artist;
      say "Title: " . $mp3->{ID3v1}->title;
      say "Album: " . $mp3->{ID3v1}->album;
      say "Year: ". $mp3->{ID3v1}->year;
      say "Genre: " . $mp3->{ID3v1}->genre;
    } else {
      say "$filename: ID3v1 tag not found";
    }
    
    # clean up
    $mp3->close();

    ID3v2 tags are a bit more complex as they allow a lot more information to be stored in the MP3 file such as the album artwork etc. If you run the following script on one of your MP3 files it will print all the ID3v2 information to the screen. I have used the getc() function in order to allow you to observe the output and press <Enter> to proceed to the next set of key-value pair. After couple of keystrokes you will see there are lot of junk characters printed. These junk characters are nothing but the album artwork and following the junk characters is the MIME type of the artwork. In my case the MIME types were all “image/jpeg”.

    #!/usr/bin/perl
    #
    # id3v2_read.pl
    #
    use 5.010;
    use warnings;
    use strict;
    use MP3::Tag;
    
    # set filename of MP3 track
    my $filename = "mp3_file_name;
    
    # create new MP3-Tag object
    my $mp3 = MP3::Tag->new($filename);
    
    # get tag information
    $mp3->get_tags();
    
    # check to see if an ID3v2 tag exists
    # if it does, print track information
    if (exists $mp3->{ID3v2}) {
      # get a list of frames as a hash reference
      my $frames = $mp3->{ID3v2}->get_frame_ids();
    
      # iterate over the hash, process each frame
      foreach my $frame (keys %$frames) {
        # for each frame get a key-value pair of content-description
        my ($value, $desc) = $mp3->{ID3v2}->get_frame($frame);
        if (defined($desc) and length $desc) {
          say "$frame $desc: "; 
        } else {
          say "$frame :";
        }
        # sometimes the value is itself a hash reference containing more values
        # deal with that here
        if (ref $value eq "HASH") {
          while (my ($k, $v) = each (%$value)) {
            say "\n     - $k: $v";
          }
        } else {
          say "$value";
        }
        # allows to view each iteration
        getc(STDIN);
      }
    } else {
      say "$filename: ID3v2 tag not found";
    }
    
    # clean up
    $mp3->close();

    Next Steps

    Most of the current MP3 players read ID3v2 tags. It will be good to understand the structure of the ID3v2 tags, using one of the links I provided above. This will help you prepare for understanding the further articles in this series. In next part we will see how to extract desired information quickly and how to extract the artwork data from the MP3 file. Stay tuned for more.

  • Setting up a Git Repository on A Remote Server

    Git is a wonderful distributed version control system and we can have a personal repository quickly set up without any technical difficulties. However at times we may need to work on shared development model where multiple people need commit access to the code. In such cases we would need a centralized repository store.

    By following  the given steps we will be able to set up a shared git repository accessible over SSH.

    • First a user needs to be created to hold the git repository (multiple repositories can also be set up under the same git user). Next a password need to be set up for the same user. Since this user will  never log on using shell, a password which is secure, random, very long string is a good option.
    $ sudo /usr/sbin/useradd -c "Git Version Control" -d /home/git -m -s /bin/bash git
    $ sudo passwd git
    • Next login as git user and create the project directory to hold the repository and then initialize that directory as a barebones (blank) git repository
    $ mkdir -p /home/git/projects/myproject1.git
    $ cd /home/projects/myprojects.git
    $ /usr/bin/git --bare init
    • Set up the .ssh directory for the git user to hold the authorized_keys file with the public ssh keys for the user allowed to log in a git user and access the repository
    $ cd /home/git
    $ mkdir .ssh
    $ chmod -R 700 .ssh
    $ touch .ssh/authorized_keys
    $ chmod 644 .ssh/authorized_keys
    • Finally change the shell of the git user to git-shell so that interactive logins for the user are not possible and only selected remote git commands are allowed.
    $ /usr/bin/chsh -s /usr/bin/git-shell

    Add the public key of the user(s) to the authorized key file. These users will be able to access the repository. Now all that needs to be done is to clone the repository and start working. Following command can be used to clone the repository on a *nix box. The 7652 is the port number where ssh daemon is listening. If your port is the default, 22, you can skip this port number.

    $ git clone ssh://git@myhost.mydomain.com:7652/home/git/projects/myproject1.git/