Friday, June 21, 2013

[Resolved] virtualbox: Could not find an open hard disk with UUID

I have a CentOS vm for Oracle DB running with Virtual Box.
This morning can not load it after reboot, and got the following error message.



Failed to open virtual machine located in /home/XXX/vms/redhat-oracle-base/redhat-oracle-base.vbox.
Could not find an open hard disk with UUID {ecfd6828-1131-467e-8836-570bfdca0581}.
Result Code:
VBOX_E_OBJECT_NOT_FOUND (0x80BB0001)
Component:
VirtualBox
Interface:
IVirtualBox {c28be65f-1a8f-43b4-81f1-eb60cb516e66}


Solution: 

1) open the .vbox file by using vi or other editor.
2) copy the hard disk uuid from the error message window, and search it in vi.
3) you will find something similar like:


<StorageController name="SATA Controller" type="AHCI" PortCount="1" useHostIOCache="false" Bootable="true" IDE0MasterEmulationPort="0" IDE0SlaveEmulationPort="1" IDE1MasterEmulationPort="2" IDE1SlaveEmulationPort="3">
        <AttachedDevice type="HardDisk" port="0" device="0">
          <Image uuid="{ecfd6828-1131-467e-8836-570bfdca0581}"/>
        </AttachedDevice>
      </StorageController>

4) remove it.
5) open virtual box, select that VM and right click it, then go to settings->storage
    -- delete all the medium of IDE Controller.
    -- add a SATA Controller and add a hard disk to it by select the .vdi file in you VM directory.
6) Boot VM, you will find it works this time.

Cheers!

[Resolved]Can not run gvm in terminal


For some unknow reasons, suddenly I am not able to run gvm in terminal and get the following error message.

No command 'gvm' found, but there are 20 similar ones
gvm: command not found

And I can run gvm command if switch to root user.

Solution: source ~/.gvm/bin/gvm-init.sh

Tuesday, June 18, 2013

Write gant script for Automated Deployment to Tomcat

This post is tutorial show how to write a gant script for tomcat deployment automation, and to keep your life simple, just using the grails tomcat plugin which provides all we need.


Set TOMCAT_HOME

before you can start write gant script, you need to make sure you have Tomcat installed and TOMCAT_HOME set to the location where you installed it.

Do this in .bashrc

Add the following content to .bashrc

TOMCAT_HOME=/home/htxiong/apache-tomcat-7.0.39
export TOMCAT_HOME

Set up a user in Tomcat and assign the essential roles to it.

See http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html for more info.

Add the following content to $TOMCAT_HOME/conf/tomcat-users.xml.

<user username="deployer" password="secret" roles="manager-gui,manager-script,manager-jmx,manager-status,manager"/>


Write a Gant script

Create the script

run the grails create-script command as follows:
$ grails create-script tomcat-deploy
With that done, you should have a TomcatDeploy.groovy file in the scripts directory of your project.

Modify the script TomcatDeploy.groovy

To begin with, you’re going to need to figure out the path to the Tomcat installation directory.
Inspecting the TOMCAT_HOME environment variable can help you achieve this:
grailsHome = ant.project.properties."environment.GRAILS_HOME"
tomcatHome = ant.project.properties."environment.TOMCAT_HOME"

the next thing to do is include the War.groovy script
available in GRAILS_HOME/scripts. The _GrailsWar.groovy template contains targets that allow you to construct a valid WAR file:
includeTargets << grailsScript("_GrailsWar") OR includeTargets << grailsScript("War")

To take advantage of the Tomcat Ant tasks, you have to define them by calling the taskdef method.
This method relates to the <taskdef> target of Ant, so defining Ant tasks in Gant is pretty much identical to doing so in pure Ant—minus the angle brackets:

ant.path(id:"tomcat.lib.path") {
fileset(dir:"${tomcatHome}/lib",includes:"*.jar")
}
ant.taskdef(name:"deploy",
classname:"org.apache.catalina.ant.DeployTask",
classpathref:"tomcat.lib.path")

Then, moving onto the main target of the TomcatDeploy.groovy script, you can change it to depend on the war target, which will ensure a valid WAR file is constructed before the rest of the code runs:

target(main: "Deploys the Grails application to Tomcat") {
depends war
...
}

Once that is done, you need to establish the destination to publish the WAR to by adding following line to you target.

def dest = argsMap.params ? argsMap.params[0] : "http://localhost:8080/manager"

OR for Tomcat 7

def dest = argsMap.params ? argsMap.params[0] : "http://localhost:8080/manager/text"

The final step is left to the deploy target supplied by the org.apache.cat-alina.ant.

Add the following content to your target.

deploy(  war:warName,
      url:dest,
      path:serverContextPath,
      username:"deployer",
      password:"secret")

DONE

The full copy of TomcatDeploy.groovy will looks like: 

grailsHome = ant.project.properties."environment.GRAILS_HOME"
tomcatHome = ant.project.properties."environment.TOMCAT_HOME"

includeTargets << grailsScript("War")

ant.path(id:"tomcat.lib.path") {
fileset(dir:"${tomcatHome}/lib",includes:"*.jar")
}
ant.taskdef(name:"deploy",
classname:"org.apache.catalina.ant.DeployTask",
classpathref:"tomcat.lib.path")

target(main: "The description of the script goes here!") {
depends(parseArguments, war)
def dest = argsMap.params ? argsMap.params[0] : "http://localhost:8080/manager/text"
deploy(war:warName,
url:dest,
path:serverContextPath,
username:"deployer",
password:"secret")

}

setDefaultTarget(main)


Add support to updeploy and list

The taskdef method of undeploy and list related to <taskdef> targets of Ant are org.apache.catalina.ant.UndeployTask and org.apache.catalina.ant.ListTask respectively.

So enable supporting of updeploy and list, just add the following content to script.

ant.taskdef(name:"list",classname:"org.apache.catalina.ant.ListTask")
ant.taskdef(name:"undeploy",classname:"org.apache.catalina.ant.UndeployTask")

and the corresponding list and undeploy methods body are shown below.

 list(
url:dest,
username:user,
password:pass)



undeploy(
url:dest,
path:serverContextPath,
username:user,
password:pass)


Cheers!

Install Jenkins on Ubuntu and Setting up it on port 80

How to install Jenkins on Ubuntu

You can find the best instruction from Jenkins official site https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu

Setting up it on any other port

Be default Jenkins will run on port 8080 which is also the default port used by Tomcat. So For Java developer, it is not a good idea to let Jenkins use port 8080. 

To modify the default port of Jenkins is very simple, do it by modifying /etc/default/jenkins.

# port for HTTP connector (default 8080; disable with -1)
HTTP_PORT=8080 

Change the post number to any port you want rather than 80 which will be covered in the following content.


The following content is a modification of Hans Häggström's  post

Setting up it on port 80

To set up jenkins to run on port 80 (the normal http port) instead of 8080 you could edit /etc/default/jenkins and add --httpPort=80 to JENKINS_ARGS and the modified content will looks like:

JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT --httpPort=80 --prefix=/jenkins"

Jenkins Prefix

We want to see jenkins running on servername/jenkins/.  The first step is to change the prefix jenkins uses, so we get from servername:8080/ to servername:8080/jenkins/.  To do that, add
  
    --prefix=/jenkins


and the modified content will looks like:

JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT --httpPort=80 --prefix=/jenkins"


to the JENKINS_ARGS string in /etc/default/jenkins and restart Jenkins with e.g.:

    sudo /etc/init.d/jenkins force-reload


Apache

If you don't have apache installed, use

    sudo apt-get install apache2

to install it.


mod_proxy

In many distributions it should be included by default with apache, but you may need to install the mod_proxy module separately:

    sudo apt-get install libapache2-mod-proxy-html

In any case you need to enable it with:

    sudo a2enmod proxy
    sudo a2enmod proxy_http   

In your /etc/apache2/sites-enabled/ directory there should be some file like 000-default or similar, with settings for the site.  Add proxy configurations in it for mapping the /jenkins path on the website to localhost:8080/jenkins:

    ProxyPass /jenkins http://127.0.0.1:8080/jenkins

In my case the file looks something like:

    <VirtualHost *:80> 
        ....
        ProxyPass /jenkins http://127.0.0.1:8080/jenkins
    </VirtualHost>

You can stop and restart apache to enable the new configuration, or just use:

    /etc/init.d/apache2 force-reload

And you can follow the apache logs for troubleshooting by running

    tail -f /var/log/apache2/error.log

And you probably will get this error message:


$ sudo /etc/init.d/apache2 force-reload
 * Reloading web server config apache2                                                                                                                                                                       apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName



This just because you have not edit /etc/apache2/httpd.conf which is by default a empty file. 
Add the following line to it and then reload apache2 configuration.

ServerName localhost

/etc/init.d/apache2 force-reload

DONE and good luck!

Monday, June 17, 2013

[Grails] How to test controllers that use i18n messages.

Issue description:

1) If the controller action I want to test calls "message()" or "g.message()" then I all of my integration tests that use that line of code will error with, "No bean named 'messageSource' is defined".
2) If the controller action I want to test calls "message()" or "g.message()" then I will get the following error message.

message() is applicable for argument types: (java.util.LinkedHashMap) values


Solution Or Walk Around:

Write a ControllerUnitTestCase extension to support tests controllers that use i18n messages, then let all your unit test cases of controllers extends it.


class ExtendedControllerUnitTestCase extends ControllerUnitTestCase {
def props

protected void setUp() {
super.setUp()

props = new Properties()
def stream = new FileInputStream("grails-app/i18n/messages.properties")
props.load stream
stream.close()

mockI18N(controller)
}

def mockI18N = { controller ->
controller.metaClass.message = { Map map ->
if (!map.code)
return ""
if (map.args) {
def formatter = new MessageFormat("")
formatter.applyPattern props.getProperty(map.code)
return formatter.format(map.args.toArray())
} else {
return props.getProperty(map.code)
}
}
}
}

More info about this solution can be found: http://jira.grails.org/browse/GRAILS-5926