Wednesday, April 19, 2017

Install VMware Horizon Client (VMware View) on Ubuntu



If like me, you had issues with VMware horizon client package on your Ubuntu desktop, here are my tips.

Step 1 : download the installation package

https://my.vmware.com/en/web/vmware/info/slug/desktop_end_user_computing/vmware_horizon_clients/4_0#linux

Step 2 : make it executable and run it

chmod +x VMware-Horizon-Client-*******.x64.bundle
sudo ./VMware-Horizon-Client-*******.x64.bundle

This will install files but it's not runnable because you need some libs.

Step 3 : find and fix libs not found

To view needed libs, run : ldd /usr/lib/vmware/view/bin/vmware-view

Results is something like :
linux-vdso.so.1 =>  (0x00007ffdb45e6000)
libatk-1.0.so.0 => /usr/lib/x86_64-linux-gnu/libatk-1.0.so.0 (0x00007fcb631a6000)
libgdk_pixbuf-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.so.0 (0x00007fcb62f84000)
libgtk-x11-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 (0x00007fcb62938000)
libgdk-x11-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0 (0x00007fcb62683000)
libgio-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0 (0x00007fcb622ee000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007fcb620ea000)
libpixman-1.so.0 => /usr/lib/x86_64-linux-gnu/libpixman-1.so.0 (0x00007fcb61e42000)
libpng12.so.0 => /lib/x86_64-linux-gnu/libpng12.so.0 (0x00007fcb61c1d000)
libXss.so.1 => /usr/lib/x86_64-linux-gnu/libXss.so.1 (0x00007fcb61a19000)
libudev.so.0 => /lib/x86_64-linux-gnu/libudev.so.0 (0x00007fcb619f8000)
libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fcb616e5000)
libgobject-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 (0x00007fcb61490000)


For some not found libs, you should fix this with a symbolic link such as :

sudo ln -s /lib/x86_64-linux-gnu/libudev.so.1.6.5 /lib/x86_64-linux-gnu/libudev.so.0
sudo ln -s /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 /lib/x86_64-linux-gnu/libcrypto.so.1.0.2
sudo ln -s /lib/x86_64-linux-gnu/libcrypto.so.1.0.0 /lib/x86_64-linux-gnu/libcrypto.so.1.0.2

For libpng12.so.0, I fixed it by installing an extra package :

wget http://mirrors.kernel.org/ubuntu/pool/main/libp/libpng/libpng12-0_1.2.54-1ubuntu1_amd64.deb && sudo dpkg --install libpng12-0_1.2.54-1ubuntu1_amd64.deb 

Then, you should run and enjoy vmware-view :)



Monday, January 23, 2017

Declare secured connector on Tomcat for https connections

To access your tomcat threw https, you have to declare a secured connector. There are two parts to do that :


  1. modify your server.xml with the new connector configuration
  2. generate a java keystore the connector will refer to

Step 1 : Modify your serveur.xml like this


<Connector
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           port="${ssl.port}" maxThreads="200"
           scheme="https" secure="true" SSLEnabled="true"
           keystoreFile="${java.home}/lib/security/tomcat_java.keystore" keystorePass="changeit"
           clientAuth="false" sslProtocol="TLSv1.1" ciphers="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_RC4_128_SHA" />

Step 2 : generate the keystore which contains the certificate used to secure connections

To generate your keystore, you need openssl and keytool (%JAVA_HOME%/jre/bin/keytool). 

If you use an existing certificate in PEM format (cer or pem files) , you will need to convert it to PKCS#12 format (p12 file). To acheive that, you need :
  • your private key which was used to generate the certificate
  • your certificate
  • the root certificate form your Certificate Authority (Verisign, GoDaddy, Symantec, etc...)

Convert it with :

openssl pkcs12 -export -in [your_certificate].cer -inkey [your private key].key -out result-certificate.p12 -name tomcat -CAfile [Veridign certificate].cer -caname root

Then generate your keystore (NOTE -->  'tomcat' alias is important) :

keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore tomcat_java.keystore -srckeystore result-certificate.p12 -srcstoretype PKCS12 -srcstorepass changeit -alias tomcat

Restart Tomcat and check logs to see if connector is started.


PS : many thanks to John Willis. His post (http://www.johnwillis.com/2015/07/tomcat-errsslversionorciphermismatch.html) really helped me.


Acces Apache Tomcat on port 80 or 443 from Linux

Default Linux security rules don't allow to access network ports < 1024 to non rooted processes. A bad idea would be to start your Tomcat as ROOT. Very bad idea!!! But these's another solution. You can start your Tomcat with a port > 1024 and then redirect requests from standard ports (such as HTTP/80  or HTPS/443) to ports > 1024.

Let's imagine you bound Tomcat https connector to 8301. We'll add a rule to iptables like this :

Prequisites : switch to root (su -)

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 443 -j REDIRECT --to-port 8301
/etc/init.d/iptables save
/etc/init.d/iptables restart

Then, just check if rule is active with iptables -L

target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https 

Now, you can access your tomcat threw a classic https url :)

Friday, January 20, 2017

Use Spring profiles and yaml configuration without Spring Boot

That's a refinement you can do to updgrade legacy applications. Using yaml config files combines with Spring profiles is a great way to configure your apps. Let's see how to do that.

Firstly, let's consider that we weill inject something in a java class depending on the runtime  environment.

@Service
public class MyService {

@Value("${service.url}")
private String URL;

}

application.yaml should be like this :

service:
   url: http://alexdp.free.fr/violetumleditor

---
spring:
  profiles: production

service:
   url: http://violet.sourceforge.net


Thus, if I lauch my applicatin without JVM Spring profile params, URL will be http://alexdp.free.fr/violetumleditor. If I launch it with -Dspring.profiles.active=production, URL will be http://violet.sourceforge.net. Great! But this feature is natively supported only for Spring Boot based applications. So, let's active this on legacy apps with this XML spring config file fragment :

<bean id="yamlProperties"
class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
<property name="resources">
<list>
<value>classpath:application.yml</value>
</list>
</property>
<property name="documentMatchers">
<bean
class="mypackage.SpringProfileDocumentMatcher" />
</property>
</bean>
<context:property-placeholder properties-ref="yamlProperties" />

Of course, you saw that we wrote our custom SpringProfileDocumentMatcher.

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set;

import org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher;
import org.springframework.beans.factory.config.YamlProcessor.MatchStatus;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;


/**
 * Allows to use Spring profiles without Spring Boot for legacy Spring based apps
 * 
 * @author Alexandre de Pellegrin
 *
 */
public class SpringProfileDocumentMatcher implements DocumentMatcher, EnvironmentAware {

private static final String[] DEFAULT_PROFILES = new String[] { "default" };

private String[] activeProfiles = new String[0];

public SpringProfileDocumentMatcher() {
}

public SpringProfileDocumentMatcher(String... profiles) {
addActiveProfiles(profiles);
}

public void addActiveProfiles(String... profiles) {
LinkedHashSet set = new LinkedHashSet(
Arrays.asList(this.activeProfiles));
Collections.addAll(set, profiles);
this.activeProfiles = set.toArray(new String[set.size()]);
}

@Override
public MatchStatus matches(Properties properties) {
String[] profiles = this.activeProfiles;
if (profiles.length == 0) {
profiles = DEFAULT_PROFILES;
}
return new ArrayDocumentMatcher("spring.profiles", profiles).matches(properties);
}

@Override
public void setEnvironment(Environment environment) {
if (environment != null) {
       addActiveProfiles(environment.getActiveProfiles());
   }
}


private class ArrayDocumentMatcher implements DocumentMatcher {

private final String key;

private final String[] patterns;

public ArrayDocumentMatcher(final String key, final String... patterns) {
this.key = key;
this.patterns = patterns;

}

@Override
public MatchStatus matches(Properties properties) {
if (!properties.containsKey(this.key)) {
return MatchStatus.ABSTAIN;
}
Set values = StringUtils.commaDelimitedListToSet(properties
.getProperty(this.key));
for (String pattern : this.patterns) {
for (String value : values) {
if (value.matches(pattern)) {
return MatchStatus.FOUND;
}
}
}
return MatchStatus.NOT_FOUND;
}
}
}


That's it!

Wednesday, January 18, 2017

Install Oracle Java Development Kit on Ubuntu

First of all, you need to download it from Oracle web site

http://www.oracle.com/technetwork/pt/java/javase/downloads/index.html

Then unzip it somewhere (be carefull that location is reachable from users who would use java)

tar xvzf jdk-*-linux-x64.tar.gz

The fun part would be here...

You should set your JAVA_HOME. Set it in your /etc/environment for every users or .profile for your current user

Now, we will create two symbolic links for java and javac command using update-alternatives command. There's two steps : install and set. The first create a symbolic link and register it to etc/alternatives with its alias. The second actives this alias. So, let's do this :


sudo update-alternatives --install /usr/bin/java java /home/..../jdk*/bin/java 1
sudo update-alternatives --install /usr/bin/javac javac /home/..../jdk*/bin/javac 1

sudo update-alternatives --set java /home/..../jdk*/bin/java
sudo update-alternatives --set javac /home/..../jdk*/bin/javac

Tuesday, August 30, 2016

Git rebase without conflicts

If you worked on a branch and have difficulties to rebase it from another branch (like master), you can you use Git automatic conflicts resolution strategy which prioritize files in conflict from your branch or from the branch you need to rebase from.

So, let's go. Consider you're on your branch (git checkout my_branch). You have a local branch 'master' you want to rebase from because master is up-to-date  and you want to retrieve last bug fxes and features from it.

If you want to prioritize your files in case of conflict, do :
git rebase master -Xtheirs

If you want to prioritize files from 'master' branch in case of conflict, do :
git rebase master -Xours

Hope this helps!

Tuesday, July 19, 2016

Reduce PDF size

You have a very large PDF file with high definition photos. It could be difficult to host on a server. So, to reduce its weight (and its quality of course), you can use ghostscript like this :

gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.6 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

Of course this suppose you use Linux. 

Enjoy!