#!/usr/bin/python3
#
# api_test.py: Test/demo of the python3-lxc API
#
# (C) Copyright Canonical Ltd. 2012
#
# Authors:
# Stéphane Graber <stgraber@ubuntu.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#

import warnings
warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable")

import lxc
import uuid
import sys

# Some constants
LXC_PATH_LIB = "/var/lib/lxc"
LXC_TEMPLATE = "ubuntu"

# Let's pick a random name, avoiding clashes
CONTAINER_NAME = str(uuid.uuid1())
CLONE_NAME = str(uuid.uuid1())

## Instantiate the container instance
print("Getting instance for '%s'" % CONTAINER_NAME)
container = lxc.Container(CONTAINER_NAME)

# A few basic checks of the current state
assert(container.config_file_name == "%s/%s/config" %
            (LXC_PATH_LIB, CONTAINER_NAME))
assert(container.defined == False)
assert(container.init_pid == -1)
assert(container.name == CONTAINER_NAME)
assert(container.running == False)
assert(container.state == "STOPPED")

## Create a rootfs
print("Creating rootfs using '%s'" % LXC_TEMPLATE)
container.create(LXC_TEMPLATE)
container.load_config()  # FIXME: workaround for get_config_item segfault

assert(container.defined == True)
assert(container.name == CONTAINER_NAME
        == container.get_config_item("lxc.utsname"))
assert(container.name in lxc.list_containers())

## Test the config
print("Testing the configuration")
capdrop = container.get_config_item("lxc.cap.drop")
container.clear_config_item("lxc.cap.drop")
container.set_config_item("lxc.cap.drop", capdrop[:-1])
container.append_config_item("lxc.cap.drop", capdrop[-1])
container.save_config()

# A few basic checks of the current state
assert(isinstance(capdrop, list))
assert(capdrop == container.get_config_item("lxc.cap.drop"))

## Test the networking
print("Testing the networking")
container.network.remove(0)  # FIXME: workaround for get_config_item segfault

# A few basic checks of the current state
assert("name" in container.get_keys("lxc.network.0"))
assert(len(container.network) == 1)
assert(container.network[0].hwaddr.startswith("00:16:3e"))

## Starting the container
print("Starting the container")
container.start()
container.wait("RUNNING", 3)

# A few basic checks of the current state
assert(container.init_pid > 1)
assert(container.running == True)
assert(container.state == "RUNNING")

## Checking IP address
print("Getting the IP addresses")
ips = container.get_ips(timeout=10)
container.attach("NETWORK|UTSNAME", "/sbin/ifconfig", "eth0")

# A few basic checks of the current state
assert(len(ips) > 0)

## Freezing the container
print("Freezing the container")
container.freeze()
container.wait("FROZEN", 3)

# A few basic checks of the current state
assert(container.init_pid > 1)
assert(container.running == True)
assert(container.state == "FROZEN")

## Unfreezing the container
print("Unfreezing the container")
container.unfreeze()
container.wait("RUNNING", 3)

# A few basic checks of the current state
assert(container.init_pid > 1)
assert(container.running == True)
assert(container.state == "RUNNING")

if len(sys.argv) > 1 and sys.argv[1] == "--with-console":
    ## Attaching to tty1
    print("Attaching to tty1")
    container.console(tty=1)

## Shutting down the container
print("Shutting down the container")
container.shutdown(3)

if container.running:
    print("Stopping the container")
    container.stop()
    container.wait("STOPPED", 3)

# A few basic checks of the current state
assert(container.init_pid == -1)
assert(container.running == False)
assert(container.state == "STOPPED")

## Cloning the container
print("Cloning the container")
clone = lxc.Container(CLONE_NAME)
clone.clone(container)
clone.load_config()  # FIXME: workaround for get_config_item segfault
clone.network.remove(0)  # FIXME: workaround for get_config_item segfault
clone.start()
clone.stop()
clone.destroy()

## Destroy the container
print("Destroying the container")
container.destroy()

assert(container.defined == False)

@@ -1747,82 +1747,8 @@
 ATE)
-%0Acontainer.load_config()  # FIXME: workaround for get_config_item segfault
 %0A%0Aas
@@ -2406,86 +2406,8 @@
 ng%22)
-%0Acontainer.network.remove(0)  # FIXME: workaround for get_config_item segfault
 %0A%0A# 
@@ -4188,152 +4188,8 @@
 er)%0A
-clone.load_config()  # FIXME: workaround for get_config_item segfault%0Aclone.network.remove(0)  # FIXME: workaround for get_config_item segfault%0A
 clon

Remove workarounds for API bugs