Linked clone fails in the API

Discussion about using the VirtualBox API, Tutorials, Samples.
Post Reply
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Linked clone fails in the API

Post by JJon »

Hi,

I'm trying to make a linked clone using the Java webservice API. I'm passing the CloneOptions.Link to the IMachine.cloneTo method, but it fails with the following error:

org.virtualbox_5_1.VBoxException: VirtualBox error: rc=0x80070057 Linked clone can only be created from a snapshot (0x80070057)

The thing is, the method only accepts a IMachine object and not ISnapshot.
Maybe I'm missing something, but how do I make the linked clone from a snapshot?

The full code is:

Code: Select all

IMachine m = vbox.getMachines().get(0);
        
        String name = m.getName();
        System.out.println("\nAttempting to clone VM '" + name + "'");
    	
        IMachine createdMachine = vbox.createMachine(
        		null, 
        		"Cloned_machine", 
        		null, 
        		m.getOSTypeId(), 
        		null);
        
        List<CloneOptions> options = new ArrayList<>();
        options.add(CloneOptions.Link);
		IProgress cloneProgress = m.cloneTo(createdMachine, CloneMode.MachineState, options);
		
		boolean success = progressBar(mgr, cloneProgress, 10000);
		
		if (success) {
			
			vbox.registerMachine(createdMachine);
		}
It is done on Ubuntu 6.04, with VirtualBox 5.1.

Thanks,
Jonathan
mpack
Site Moderator
Posts: 39134
Joined: 4. Sep 2008, 17:09
Primary OS: MS Windows 10
VBox Version: PUEL
Guest OSses: Mostly XP

Re: Linked clone fails in the API

Post by mpack »

Has a snapshot been created in the base VM? If you create a linked clone then the base image has to be frozen, meaning that both the original VM and the clone should be using a difference state.
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Re: Linked clone fails in the API

Post by JJon »

mpack wrote:Has a snapshot been created in the base VM? If you create a linked clone then the base image has to be frozen, meaning that both the original VM and the clone should be using a difference state.
Yes. A snapshot has been taken. But the API doesn't allow passing the snapshot object. Only the base machine.

Has anyone been able to accomplish this?

Thanks
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Linked clone fails in the API

Post by noteirak »

Can you produce a standalone piece of code that reproduces the issue? Right now, only part of your code is visible which doesn't allow to really see where a possible mistake is.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Re: Linked clone fails in the API

Post by JJon »

noteirak wrote:Can you produce a standalone piece of code that reproduces the issue? Right now, only part of your code is visible which doesn't allow to really see where a possible mistake is.
Sure. Following is a complete test code.
Note that the machine expected to be cloned has snapshots and is powered off.

Run with following arguments: "-w -server h t t p : / /<ip>:<port>"

Code: Select all

import java.util.ArrayList;
import java.util.List;

import org.virtualbox_5_1.CloneMode;
import org.virtualbox_5_1.CloneOptions;
import org.virtualbox_5_1.IMachine;
import org.virtualbox_5_1.IProgress;
import org.virtualbox_5_1.IVirtualBox;
import org.virtualbox_5_1.IVirtualBoxErrorInfo;
import org.virtualbox_5_1.VBoxException;
import org.virtualbox_5_1.VirtualBoxManager;


public class TestLinkedClone
{
        
    static void testLinkedClone(VirtualBoxManager mgr, IVirtualBox vbox)
    {
        IMachine m = vbox.getMachines().get(0);
        
        String name = m.getName();
        System.out.println("\nAttempting to clone VM '" + name + "'");
    	
        IMachine createdMachine = vbox.createMachine(
        		null, 
        		"Cloned_machine", 
        		null, 
        		m.getOSTypeId(), 
        		null);
        
        List<CloneOptions> options = new ArrayList<>();
        options.add(CloneOptions.Link);
		IProgress cloneProgress = m.cloneTo(createdMachine, CloneMode.MachineState, options);
		
		boolean success = progressBar(mgr, cloneProgress, 10000);
		
		if (success) {
			
			vbox.registerMachine(createdMachine);
		}
		
        // process system event queue
        mgr.waitForEvents(0);
    }
    
    

    static boolean progressBar(VirtualBoxManager mgr, IProgress p, long waitMillis)
    {
        long end = System.currentTimeMillis() + waitMillis;
        while (!p.getCompleted())
        {
            // process system event queue
            mgr.waitForEvents(0);
            // wait for completion of the task, but at most 200 msecs
            p.waitForCompletion(200);
            if (System.currentTimeMillis() >= end)
                return false;
        }
        return true;
    }

    

    static void printErrorInfo(VBoxException e)
    {
        System.out.println("VBox error: " + e.getMessage());
        System.out.println("Error cause message: " + e.getCause());
        System.out.println("Overall result code: " + Integer.toHexString(e.getResultCode()));
        int i = 1;
        for (IVirtualBoxErrorInfo ei = e.getVirtualBoxErrorInfo(); ei != null; ei = ei.getNext(), i++)
        {
            System.out.println("Detail information #" + i);
            System.out.println("Error mesage: " + ei.getText());
            System.out.println("Result code:  " + Integer.toHexString(ei.getResultCode()));
            // optional, usually provides little additional information:
            System.out.println("Component:    " + ei.getComponent());
            System.out.println("Interface ID: " + ei.getInterfaceID());
        }
    }


    public static void main(String[] args)
    {
        VirtualBoxManager mgr = VirtualBoxManager.createInstance(null);

        boolean ws = false;
        String  server = null;
        String  user = null;
        String  passwd = null;

        for (int i = 0; i < args.length; i++)
        {
            if (args[i].equals("-w"))
                ws = true;
            else if (args[i].equals("-server"))
                server = args[++i];
            else if (args[i].equals("-user"))
                user = args[++i];
            else if (args[i].equals("-passwd"))
                passwd = args[++i];
        }

        if (ws)
        {
            try {
                mgr.connect(server, user, passwd);
            } catch (VBoxException e) {
                e.printStackTrace();
                System.out.println("Cannot connect, start webserver first!");
            }
        }

        try
        {
            IVirtualBox vbox = mgr.getVBox();
            if (vbox != null)
            {
                System.out.println("VirtualBox version: " + vbox.getVersion() + "\n");
                
                testLinkedClone(mgr, vbox);

                System.out.println("done, press Enter...");
                int ch = System.in.read();
            }
        }
        catch (VBoxException e)
        {
            printErrorInfo(e);
            System.out.println("Java stack trace:");
            e.printStackTrace();
        }
        catch (RuntimeException e)
        {
            System.out.println("Runtime error: " + e.getMessage());
            e.printStackTrace();
        }
        catch (java.io.IOException e)
        {
            e.printStackTrace();
        }

        // process system event queue
        mgr.waitForEvents(0);
        if (ws)
        {
            try {
                mgr.disconnect();
            } catch (VBoxException e) {
                e.printStackTrace();
            }
        }

        mgr.cleanup();

    }

}
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Re: Linked clone fails in the API

Post by JJon »

So do I have any mistake? Do I need to use the API differently?

Appreciate any help on this. I couldn't get this to work.

Thanks,
Jonathan
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Linked clone fails in the API

Post by noteirak »

Hi Jonathan,
I wanted to get back to you before the weekend but had too many things on my plate. I'll get back to you on this on monday afternoon (CET) latest.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Re: Linked clone fails in the API

Post by JJon »

Thanks! Appreciate it...
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Re: Linked clone fails in the API

Post by JJon »

Hi,

Did you have the chance to take a look at this?

Thanks,
Jonathan
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: Linked clone fails in the API

Post by noteirak »

I managed to make it work.
So the issue is that you need to retrieve the IMachine object from the snapshot you want to do the linked clone from if you use CloneMode.MachineState

So let's say you have a machine called MachineA and the snapshot you want the linked clone from called SnapshotBase, here is the right code for the testLinkedClone method:

Code: Select all

    static void testLinkedClone(VirtualBoxManager mgr, IVirtualBox vbox)
    {
        IMachine m = vbox.findMachine("MachineA").findSnapshot("SnapshotBase").getMachine();

        String name = m.getName();
        System.out.println("\nAttempting to clone VM '" + name + "'");

        IMachine createdMachine = vbox.createMachine(
                null,
                "Cloned_machine",
                null,
                m.getOSTypeId(),
                null);

        List<CloneOptions> options = new ArrayList<>();
        options.add(CloneOptions.Link);
        IProgress cloneProgress = m.cloneTo(createdMachine, CloneMode.MachineState, options);

        boolean success = progressBar(mgr, cloneProgress, 10000);

        if (success) {
            vbox.registerMachine(createdMachine);
        }

        // process system event queue
        mgr.waitForEvents(0);
    }
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
JJon
Posts: 18
Joined: 3. Nov 2016, 11:54

Re: Linked clone fails in the API

Post by JJon »

Wow...not so intuitive...
Thank you very much. I'll try it out!
Post Reply