[libvirt] [PATCH] Network is ported

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
 README                           |   12 ++--
 src/org/libvirt/Connect.java     |  102 ++++++++++++++++++++++++++++----------
 src/org/libvirt/Network.java     |   65 +++++++++++-------------
 src/org/libvirt/jna/Libvirt.java |   23 ++++++++-
 src/test.java                    |   58 +++++++++++----------
 5 files changed, 164 insertions(+), 96 deletions(-)

diff --git a/README b/README
index 4fd68be..655090f 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ To use it, your program needs to access both the java library (.jar file),
 and the JNI library (.so file)
 
 1. You must have the libvirt.jar file in your classpath.
-By default the installs it to /usr/share/java/libvirt-0.2.1.jar
+By default the installs it to /usr/local/share/java/libvirt-0.2.1.jar
 
 2. You must have the libvirt_jni.so accessible by the dynamic linker.
 By default the RPM installs it to /usr/lib or /usr/lib64, so the linker will
@@ -13,16 +13,16 @@ the LD_LIBRARY_PATH variable to the directory containing the libvirt_jni.so
 file.
 
 There is a rudimentary functional test program that the libvirt-java-devel
-installs put it into /usr/share/doc/libvirt-java-devel-0.2.1/test.java
+installs put it into /usr/local/share/doc/libvirt-java-devel-0.2.1/test.java
 
 To run it, first copy the test.java file to writeable directory
-cp /usr/share/doc/libvirt-java-devel-0.2.1/test.java ~
+cp /usr/local/share/doc/libvirt-java-devel-0.2.1/test.java ~
 
 Compile the java file to a class:
-javac -classpath /usr/share/java/libvirt-0.2.1.jar test.java
+javac -classpath /usr/local/share/java/libvirt-0.2.1.jar test.java
 
 Then run the program:
-java -classpath .:/usr/share/java/libvirt-0.2.1.jar test
+java -classpath .:/usr/local/share/java/libvirt-0.2.1.jar test
 
-There is full javadoc for the API in /usr/share/javadoc/libvirt-java-0.2.1/
+There is full javadoc for the API in /usr/local/share/javadoc/libvirt-java-0.2.1/
 
diff --git a/src/org/libvirt/Connect.java b/src/org/libvirt/Connect.java
index bc560d0..b559b52 100644
--- a/src/org/libvirt/Connect.java
+++ b/src/org/libvirt/Connect.java
@@ -347,7 +347,12 @@ public class Connect {
 	 */
 	public Network networkLookupByName(String name)
 	throws LibvirtException {
-		return new Network(this, libvirt.virNetworkLookupByName(VCP, name));
+	    Network returnValue = null ;
+	    Pointer ptr = libvirt.virNetworkLookupByName(VCP, name) ;
+	    if (ptr != null) {
+	        returnValue = new Network(this, ptr) ;
+	    }
+		return returnValue ;
 	}
 
 
@@ -365,7 +370,12 @@ public class Connect {
 	    for (int i : UUID) {
 	        uuidString.append(i) ;
 	    }
-		return new Network(this, libvirt.virNetworkLookupByUUID(VCP, uuidString.toString()));
+        Network returnValue = null ;
+        Pointer ptr = libvirt.virNetworkLookupByUUID(VCP, uuidString.toString()) ;
+        if (ptr != null) {
+            returnValue = new Network(this, ptr) ;
+        }
+        return returnValue ;	    
 	}
 
 	
@@ -378,12 +388,14 @@ public class Connect {
 	 */
 	public Network networkLookupByUUIDString(String UUID)
 	throws LibvirtException {
-        return new Network(this, libvirt.virNetworkLookupByUUIDString(VCP, UUID));
+        Network returnValue = null ;
+        Pointer ptr = libvirt.virNetworkLookupByUUIDString(VCP, UUID);
+        if (ptr != null) {
+            returnValue = new Network(this, ptr) ;
+        }
+        return returnValue ;              
 	}
 
-//	private native long _virNetworkLookupByUUIDString(long VCP, String UUID)
-//	throws LibvirtException;
-
 
 	/**
 	 * Creates and starts a new virtual network.
@@ -396,7 +408,12 @@ public class Connect {
 	 */
 	public Network networkCreateXML(String xmlDesc)
 	throws LibvirtException {
-		return new Network(this, libvirt.virNetworkCreateXML(VCP, xmlDesc));
+        Network returnValue = null ;
+        Pointer ptr = libvirt.virNetworkCreateXML(VCP, xmlDesc) ;
+        if (ptr != null) {
+            returnValue = new Network(this, ptr) ;
+        }
+        return returnValue ; 		
 	}
 
 
@@ -411,7 +428,12 @@ public class Connect {
 	 */
 	public Network networkDefineXML(String xmlDesc)
 	throws LibvirtException {
-        return new Network(this, libvirt.virNetworkDefineXML(VCP, xmlDesc));
+        Network returnValue = null ;
+        Pointer ptr = libvirt.virNetworkDefineXML(VCP, xmlDesc) ;
+        if (ptr != null) {
+            returnValue = new Network(this, ptr) ;
+        }
+        return returnValue ;                
 	}
 
 	
@@ -423,12 +445,14 @@ public class Connect {
 	 * @throws LibvirtException
 	 */
 	public Domain domainLookupByID(int id) throws LibvirtException {
-	    throw new RuntimeException("Not Implemented") ;	    
-//		return new Domain(this, _virDomainLookupByID(VCP, id));
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainLookupByID(VCP, id) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;      
 	}
 
-//	private native long _virDomainLookupByID(long VCP, int id)
-//	throws LibvirtException;
 
 	/**
 	 * Looks up a domain based on its name.
@@ -438,13 +462,14 @@ public class Connect {
 	 * @throws LibvirtException
 	 */
 	public Domain domainLookupByName(String name) throws LibvirtException {
-	    throw new RuntimeException("Not Implemented") ;	    
-//		return new Domain(this, _virDomainLookupByName(VCP, name));
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainLookupByName(VCP, name) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;     
 	}
 
-//	private native long _virDomainLookupByName(long VCP, String name)
-//	throws LibvirtException;
-
 
 	/**
 	 * Looks up a domain  based on its UUID in array form.
@@ -455,13 +480,18 @@ public class Connect {
 	 * @throws LibvirtException
 	 */
 	public Domain domainLookupByUUID(int[] UUID) throws LibvirtException {
-	    throw new RuntimeException("Not Implemented") ;	    
-//		return new Domain(this, _virDomainLookupByUUID(VCP, UUID));
+        StringBuilder uuidString = new StringBuilder() ;
+        for (int i : UUID) {
+            uuidString.append(i) ;
+        }
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainLookupByUUID(VCP, uuidString.toString()) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;
 	}
 
-//	private native long _virDomainLookupByUUID(long VCP, int[] UUID)
-//	throws LibvirtException;
-
 	/**
 	 * Looks up a domain  based on its UUID in String form.
 	 *
@@ -471,7 +501,12 @@ public class Connect {
 	 */
 	public Domain domainLookupByUUIDString(String UUID)
 	throws LibvirtException {
-		return new Domain(this, libvirt.virDomainLookupByUUIDString(VCP, UUID));
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainLookupByUUIDString(VCP, UUID) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;	    
 	}
 
 
@@ -488,7 +523,12 @@ public class Connect {
 	 */
 	public Domain domainCreateLinux(String xmlDesc, int flags)
 	throws LibvirtException {
-        return new Domain(this, libvirt.virDomainCreateLinux(VCP, xmlDesc, flags));
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainCreateLinux(VCP, xmlDesc, flags) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;        	    
 	}
 
 
@@ -501,7 +541,12 @@ public class Connect {
 	 * @see <a href="http://libvirt.org/format.html#Normal1"; > The XML format description </a>
 	 */
 	public Domain domainDefineXML(String xmlDesc) throws LibvirtException {
-        return new Domain(this, libvirt.virDomainDefineXML(VCP, xmlDesc));
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainDefineXML(VCP, xmlDesc) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;  	    
 	}
 	
 	
@@ -514,7 +559,12 @@ public class Connect {
      * @see <a href="http://libvirt.org/format.html#Normal1"; > The XML format description </a>
      */
     public Domain domainCreateXML(String xmlDesc, int flags) throws LibvirtException {
-        return new Domain(this, libvirt.virDomainCreateXML(VCP, xmlDesc, flags));
+        Domain returnValue = null ;
+        Pointer ptr = libvirt.virDomainCreateXML(VCP, xmlDesc, flags) ;
+        if (ptr != null) {
+            returnValue = new Domain(this, ptr) ;
+        }
+        return returnValue ;          
     }	
 
 
diff --git a/src/org/libvirt/Network.java b/src/org/libvirt/Network.java
index a194ca7..063345c 100644
--- a/src/org/libvirt/Network.java
+++ b/src/org/libvirt/Network.java
@@ -3,6 +3,8 @@ package org.libvirt;
 import org.libvirt.jna.Libvirt;
 
 import com.sun.jna.Pointer;
+import com.sun.jna.ptr.IntByReference;
+import com.sun.jna.ptr.PointerByReference;
 
 public class Network {
 
@@ -47,11 +49,9 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public String getXMLDesc(int flags) throws LibvirtException{
-//		return _getXMLDesc(VNP, flags);
-        throw new RuntimeException("Not Implemented") ;	    
+	    return libvirt.virNetworkGetXMLDesc(VNP, flags) ; 
 	}
 
-//	private native String _getXMLDesc(long VNP, int flags) throws LibvirtException;
 
 	/**
 	 * Provides a boolean value indicating whether this network is configured to be automatically started when the host machine boots.
@@ -60,11 +60,11 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public boolean getAutostart() throws LibvirtException{
-//		return _getAutostart(VNP);
-        throw new RuntimeException("Not Implemented") ;	    
+	    IntByReference autoStart = new IntByReference() ;
+	    libvirt.virNetworkGetAutostart(VNP, autoStart) ;
+	    return autoStart.getValue() != 0 ? true : false ;
 	}
 
-//	private native boolean _getAutostart(long VNP) throws LibvirtException;
 
 
 	/**
@@ -74,11 +74,10 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public void setAutostart(boolean autostart) throws LibvirtException{
-//		_setAutostart(VNP, autostart);
-        throw new RuntimeException("Not Implemented") ;		
+	    int autoValue = autostart ? 1 : 0 ;
+        libvirt.virNetworkSetAutostart(VNP, autoValue) ;	
 	}
 
-//	private native int _setAutostart(long VNP, boolean autostart) throws LibvirtException;
 
 	/**
 	 * Provides a bridge interface name to which a domain may connect a network interface in order to join this network.
@@ -87,11 +86,8 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public String getBridgeName() throws LibvirtException{
-//		return _getBridgeName(VNP);
-        throw new RuntimeException("Not Implemented") ;		
+	    return libvirt.virNetworkGetBridgeName(VNP) ;	
 	}
-
-//	private native String _getBridgeName(long VNP) throws LibvirtException;
 	
 
 
@@ -115,7 +111,6 @@ public class Network {
 		return libvirt.virNetworkGetName(VNP);   
 	}
 
-//	private native String _getName(long VNP) throws LibvirtException;
 
 	/**
 	 * Gets the UUID for this network
@@ -125,12 +120,18 @@ public class Network {
 	 * @see <a href="http://www.ietf.org/rfc/rfc4122.txt";>rfc4122</a>
 	 */
 	public int[] getUUID() throws LibvirtException{
-//		return _getUUID(VNP);
-        throw new RuntimeException("Not Implemented") ;	    
+	    byte[] bytes = new byte[Libvirt.VIR_UUID_BUFLEN] ;
+	    int success = libvirt.virNetworkGetUUID(VNP, bytes) ;
+	    int[] returnValue = new int[0] ; 
+	    if (success == 0) {
+	        returnValue = new int[Libvirt.VIR_UUID_BUFLEN] ;
+	        for (int x = 0 ; x < Libvirt.VIR_UUID_BUFLEN ; x++) {
+	            returnValue[x] = (int) bytes[x] ;
+	        }
+	    }
+        return returnValue ;   
 	}
 
-//	private native int[] _getUUID(long VNP) throws LibvirtException;
-
 	/**
 	 * Gets the UUID for a network as string.
 	 *
@@ -139,11 +140,15 @@ public class Network {
 	 * @see <a href="http://www.ietf.org/rfc/rfc4122.txt";>rfc4122</a>
 	 */
 	public String getUUIDString() throws LibvirtException{
-//		return _getUUIDString(VNP);
-        throw new RuntimeException("Not Implemented") ;	    
+        byte[] bytes = new byte[Libvirt.VIR_UUID_STRING_BUFLEN] ;
+        int success = libvirt.virNetworkGetUUIDString(VNP, bytes) ;
+        String returnValue = null ; 
+        if (success == 0) {
+            returnValue = new String(bytes) ;
+        }
+        return returnValue ;   	    
 	}
 
-//	private native String _getUUIDString(long VNP) throws LibvirtException;
 
 	/**
 	 * Creates and starts this defined network.
@@ -152,11 +157,9 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public void create() throws LibvirtException{
-//		_create(VNP);
-	       throw new RuntimeException("Not Implemented") ;
+	    libvirt.virNetworkCreate(VNP) ;
 	}
 
-//	private native int _create(long VNP) throws LibvirtException;
 
 	/**
 	 * Destroy this network object.
@@ -167,11 +170,9 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public void destroy() throws LibvirtException{
-//		_destroy(VNP);
-	       throw new RuntimeException("Not Implemented") ;
+        libvirt.virNetworkDestroy(VNP) ;
 	}
 
-//	private native int _destroy(long VNP) throws LibvirtException;
 
 	/**
 	 * Frees this network object.
@@ -181,12 +182,10 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public void free() throws LibvirtException{
-        throw new RuntimeException("Not Implemented") ;	    
-//		_free(VNP);
-//		VNP=0;
+		libvirt.virNetworkFree(VNP) ;
+		VNP=null;
 	}
 
-//	private native int _free(long VNP) throws LibvirtException;
 
 	/**
 	 * Undefines this network but does not stop it if it is running
@@ -194,10 +193,8 @@ public class Network {
 	 * @throws LibvirtException
 	 */
 	public void undefine() throws LibvirtException{
-        throw new RuntimeException("Not Implemented") ;	    
-//		_undefine(VNP);
+        libvirt.virNetworkUndefine(VNP) ;
 	}
 
-//	private native int _undefine(long VNP) throws LibvirtException;
 
 }
diff --git a/src/org/libvirt/jna/Libvirt.java b/src/org/libvirt/jna/Libvirt.java
index 1874d3e..30ab49d 100644
--- a/src/org/libvirt/jna/Libvirt.java
+++ b/src/org/libvirt/jna/Libvirt.java
@@ -6,6 +6,7 @@ import com.sun.jna.Library ;
 import com.sun.jna.Native;
 import com.sun.jna.Pointer;
 import com.sun.jna.Structure.ByReference;
+import com.sun.jna.ptr.IntByReference;
 import com.sun.jna.ptr.LongByReference;
 import com.sun.jna.ptr.PointerByReference;
 
@@ -13,6 +14,10 @@ public interface Libvirt extends Library
 {
     Libvirt INSTANCE = (Libvirt) Native.loadLibrary("libvirt", Libvirt.class) ;
     
+    // Constants we need
+    public static int VIR_UUID_BUFLEN = 16 ;
+    public static int VIR_UUID_STRING_BUFLEN = (36+1) ;    
+    
     //Callbacks 
     interface virErrorFunc extends Callback {
         void handleError(Pointer userData, virError error) throws Exception ;
@@ -50,17 +55,31 @@ public interface Libvirt extends Library
     public int virNodeGetInfo(Pointer virConnectPtr, virNodeInfo virNodeInfo) ;
     
     // Network functions
+    public int virNetworkCreate(Pointer virConnectPtr) ;    
     public Pointer virNetworkCreateXML(Pointer virConnectPtr, String xmlDesc) ;
     public Pointer virNetworkDefineXML(Pointer virConnectPtr, String xmlDesc) ;  
-    public String virNetworkGetName(Pointer virNetorkPtr) ;
+    public int virNetworkDestroy(Pointer virConnectPtr) ;
+    public int virNetworkFree(Pointer virConnectPtr) ;        
+    public int virNetworkGetAutostart(Pointer virNetworkPtr, IntByReference value) ;   
+    public String virNetworkGetBridgeName(Pointer virNetworkPtr) ;
+    public String virNetworkGetName(Pointer virNetworkPtr) ;
+    public int virNetworkGetUUID(Pointer virNetworkPtr, byte[] uuidString) ;    
+    public int virNetworkGetUUIDString(Pointer virNetworkPtr, byte[] uuidString) ;
+    public String virNetworkGetXMLDesc(Pointer virNetworkPtr, int flags) ;     
     public Pointer virNetworkLookupByName(Pointer virConnectPtr, String name) ;
     public Pointer virNetworkLookupByUUIDString(Pointer virConnectPtr, String uuidstr) ;    
-    public Pointer virNetworkLookupByUUID(Pointer virConnectPtr, String uuidstr) ;        
+    public Pointer virNetworkLookupByUUID(Pointer virConnectPtr, String uuidstr) ;       
+    public int virNetworkSetAutostart(Pointer virConnectPtr, int autoStart) ;
+    public int virNetworkUndefine(Pointer virConnectPtr) ;       
     
     // Domain functions
     public Pointer virDomainCreateLinux(Pointer virConnectPtr, String xmlDesc, int flags) ;    
     public Pointer virDomainCreateXML(Pointer virConnectPtr, String xmlDesc, int flags) ;
     public Pointer virDomainDefineXML(Pointer virConnectPtr, String xmlDesc) ;       
+    public Pointer virDomainLookupByID(Pointer virConnectPtr, int id) ;
+    public Pointer virDomainLookupByName(Pointer virConnectPtr, String name) ;    
+    public Pointer virDomainLookupByUUID(Pointer virConnectPtr, String uuidstr) ;    
     public Pointer virDomainLookupByUUIDString(Pointer virConnectPtr, String uuidstr) ;
+      
 
 }
diff --git a/src/test.java b/src/test.java
index 2ca6a92..34d3518 100644
--- a/src/test.java
+++ b/src/test.java
@@ -2,6 +2,7 @@ import org.libvirt.*;
 
 public class test {
 
+    public static String FIXME = "<============== FIXME ================> " ;
 	/**
 	 * @param args
 	 */
@@ -9,13 +10,13 @@ public class test {
 		//Create the connection
 		Connect conn=null;
 		Network testNetwork=null;
-		
+
 		//Need this for the lookup method testing, it's absolutely horrible in java, but let's be complete
 		int UUID[] = {Integer.decode("0x00"), Integer.decode("0x4b"), Integer.decode("0x96"), Integer.decode("0xe1"), 
 				Integer.decode("0x2d"), Integer.decode("0x78"),
 				Integer.decode("0xc3"), Integer.decode("0x0f"),
 				Integer.decode("0x5a"), Integer.decode("0xa5"),
-				Integer.decode("0xf0"), Integer.decode("0x3c"), Integer.decode("0x87"), Integer.decode("0xd2"), Integer.decode("0x1e"), Integer.decode("0x69")} ;
+				Integer.decode("0xf0"), Integer.decode("0x3c"), Integer.decode("0x87"), Integer.decode("0xd2"), Integer.decode("0x1e"), Integer.decode("0x67")} ;
 
 		//For testing the authentication
 //		ConnectAuth defaultAuth = new ConnectAuthDefault(); 
@@ -140,38 +141,39 @@ public class test {
      		//Choose one, they should have the exact same effect
 		    testNetwork = conn.networkLookupByName("deftest") ;
 		    System.out.println("networkLookupByName: " + testNetwork.getName()) ;
-		    
+            System.out.println(FIXME) ;
+            testNetwork=conn.networkLookupByUUID(UUID);
+//            System.out.println("networkLookupByUUID: " + testNetwork.getName()) ;     
             testNetwork = conn.networkLookupByUUIDString("004b96e1-2d78-c30f-5aa5-f03c87d21e67");
             System.out.println("networkLookupByUUIDString: " + testNetwork.getName()) ;            
-			testNetwork=conn.networkLookupByUUID(UUID);
-            System.out.println("networkLookupByUUID: " + testNetwork.getName()) ;                     
-//			
-//			//Exercise the getter methods on the default network
-//			System.out.println("virNetworkGetXMLDesc:" + testNetwork.getXMLDesc(0));
-//			System.out.println("virNetworkLookupByName:" + testNetwork);
-//			System.out.println("virNetworkGetAutostart:" + testNetwork.getAutostart());
-//			System.out.println("virNetworkGetBridgeName:" + testNetwork.getBridgeName());
-//			System.out.println("virNetworkGetName:" + testNetwork.getName());
-//			System.out.println("virNetworkGetUUID:" + testNetwork.getUUID() + " ");
-//			for(int c: testNetwork.getUUID())
-//				System.out.print(Integer.toHexString(c));
-//			System.out.println();
-//			System.out.println("virNetworkGetName:" + testNetwork.getUUIDString());
-//			
-//			//Destroy and create the network
-//			System.out.println("virNetworkDestroy:"); testNetwork.destroy();
-//			System.out.println("virNetworkCreate:"); testNetwork.create();
+                
+			//Exercise the getter methods on the default network
+			System.out.println("virNetworkGetXMLDesc:" + testNetwork.getXMLDesc(0));
+			System.out.println("virNetworkGetAutostart:" + testNetwork.getAutostart());
+			System.out.println("virNetworkGetBridgeName:" + testNetwork.getBridgeName());
+			System.out.println("virNetworkGetName:" + testNetwork.getName());
+			System.out.println("virNetworkGetUUID:" + testNetwork.getUUID() + " ");
+            System.out.println(FIXME) ;			
+			for(int c: testNetwork.getUUID())
+				System.out.print(String.format("%02x", c));
+			System.out.println();
+			System.out.println("virNetworkGetName:" + testNetwork.getUUIDString());
+			
+			//Destroy and create the network
+			System.out.println("virNetworkDestroy:"); testNetwork.destroy();
+			System.out.println("virNetworkCreate:"); testNetwork.create();
+		} catch (LibvirtException e){
+			System.out.println("exception caught:"+e);
+			System.out.println(e.getError());
+		}
+		//This should raise an excpetion
+        System.out.println(FIXME) ;     		
+		try{
+			System.out.println("virNetworkCreate:");  testNetwork.create();
 		} catch (LibvirtException e){
 			System.out.println("exception caught:"+e);
 			System.out.println(e.getError());
 		}
-//		//This should raise an excpetion
-//		try{
-//			System.out.println("virNetworkCreate:");  testNetwork.create();
-//		} catch (LibvirtException e){
-//			System.out.println("exception caught:"+e);
-//			System.out.println(e.getError());
-//		}
 		
 		//Domain stuff
 		
-- 
1.6.0.6

--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]