github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/tools/lxdclient/client_test.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build go1.3,linux
     5  
     6  package lxdclient
     7  
     8  import (
     9  	"io/ioutil"
    10  	"os"
    11  
    12  	"github.com/juju/errors"
    13  	"github.com/juju/testing"
    14  	jc "github.com/juju/testing/checkers"
    15  	jujuos "github.com/juju/utils/os"
    16  	"github.com/lxc/lxd"
    17  	gc "gopkg.in/check.v1"
    18  )
    19  
    20  type ConnectSuite struct {
    21  	testing.IsolationSuite
    22  }
    23  
    24  var _ = gc.Suite(&ConnectSuite{})
    25  
    26  func (cs *ConnectSuite) SetUpSuite(c *gc.C) {
    27  	cs.IsolationSuite.SetUpSuite(c)
    28  	if jujuos.HostOS() != jujuos.Ubuntu {
    29  		c.Skip("lxd is only supported on Ubuntu at the moment")
    30  	}
    31  }
    32  
    33  func (cs *ConnectSuite) TestLocalConnectError(c *gc.C) {
    34  	f, err := ioutil.TempFile("", "juju-lxd-remote-test")
    35  	c.Assert(err, jc.ErrorIsNil)
    36  	defer os.RemoveAll(f.Name())
    37  
    38  	cfg, err := Config{
    39  		Remote: Remote{
    40  			Name: "local",
    41  			Host: "unix://" + f.Name(),
    42  		},
    43  	}.WithDefaults()
    44  	c.Assert(err, jc.ErrorIsNil)
    45  
    46  	/* ECONNREFUSED because it's not a socket (mimics behavior of a socket
    47  	 * with nobody listening)
    48  	 */
    49  	_, err = Connect(cfg)
    50  	c.Assert(err.Error(), gc.Equals, `can't connect to the local LXD server: LXD refused connections; is LXD running?
    51  
    52  Please configure LXD by running:
    53  	$ newgrp lxd
    54  	$ lxd init
    55  `)
    56  
    57  	/* EACCESS because we can't read/write */
    58  	c.Assert(f.Chmod(0400), jc.ErrorIsNil)
    59  	_, err = Connect(cfg)
    60  	c.Assert(err.Error(), gc.Equals, `can't connect to the local LXD server: Permisson denied, are you in the lxd group?
    61  
    62  Please configure LXD by running:
    63  	$ newgrp lxd
    64  	$ lxd init
    65  `)
    66  
    67  	/* ENOENT because it doesn't exist */
    68  	c.Assert(os.RemoveAll(f.Name()), jc.ErrorIsNil)
    69  	_, err = Connect(cfg)
    70  	c.Assert(err.Error(), gc.Equals, `can't connect to the local LXD server: LXD socket not found; is LXD installed & running?
    71  
    72  Please install LXD by running:
    73  	$ sudo apt-get install lxd
    74  and then configure it with:
    75  	$ newgrp lxd
    76  	$ lxd init
    77  `)
    78  
    79  	// Yes, the error message actually matters here... this is being displayed
    80  	// to the user.
    81  	cs.PatchValue(&lxdNewClientFromInfo, fakeNewClientFromInfo)
    82  	_, err = Connect(cfg)
    83  	c.Assert(err.Error(), gc.Equals, `can't connect to the local LXD server: boo!
    84  
    85  Please install LXD by running:
    86  	$ sudo apt-get install lxd
    87  and then configure it with:
    88  	$ newgrp lxd
    89  	$ lxd init
    90  `)
    91  }
    92  
    93  func (cs *ConnectSuite) TestCheckLXDBridgeConfiguration(c *gc.C) {
    94  	var err error
    95  
    96  	valid := `
    97  # Whether to setup a new bridge or use an existing one
    98  USE_LXD_BRIDGE="true"
    99  
   100  # Bridge name
   101  # This is still used even if USE_LXD_BRIDGE is set to false
   102  # set to an empty value to fully disable
   103  LXD_BRIDGE="lxdbr0"
   104  
   105  # Path to an extra dnsmasq configuration file
   106  LXD_CONFILE=""
   107  
   108  # DNS domain for the bridge
   109  LXD_DOMAIN="lxd"
   110  
   111  # IPv4
   112  ## IPv4 address (e.g. 10.0.4.1)
   113  LXD_IPV4_ADDR="10.0.4.1"
   114  
   115  ## IPv4 netmask (e.g. 255.255.255.0)
   116  LXD_IPV4_NETMASK="255.255.255.0"
   117  
   118  ## IPv4 network (e.g. 10.0.4.0/24)
   119  LXD_IPV4_NETWORK="10.0.4.1/24"
   120  
   121  ## IPv4 DHCP range (e.g. 10.0.4.2,10.0.4.254)
   122  LXD_IPV4_DHCP_RANGE="10.0.4.2,10.0.4.254"
   123  
   124  ## IPv4 DHCP number of hosts (e.g. 250)
   125  LXD_IPV4_DHCP_MAX="253"
   126  
   127  ## NAT IPv4 traffic
   128  LXD_IPV4_NAT="true"
   129  
   130  # IPv6
   131  ## IPv6 address (e.g. 2001:470:b368:4242::1)
   132  LXD_IPV6_ADDR=""
   133  
   134  ## IPv6 CIDR mask (e.g. 64)
   135  LXD_IPV6_MASK=""
   136  LXD_IPV6_NETWORK=""
   137  `
   138  
   139  	err = checkLXDBridgeConfiguration(valid)
   140  	c.Assert(err, jc.ErrorIsNil)
   141  
   142  	noBridge := `
   143  USE_LXD_BRIDGE="false"
   144  `
   145  	err = checkLXDBridgeConfiguration(noBridge)
   146  	c.Assert(err.Error(), gc.Equals, `lxdbr0 not enabled but required
   147  It looks like your lxdbr0 has not yet been configured. Please configure it via:
   148  
   149  	sudo dpkg-reconfigure -p medium lxd
   150  
   151  and then bootstrap again.`)
   152  
   153  	badName := `
   154  USE_LXD_BRIDGE="true"
   155  LXD_BRIDGE="meshuggahrocks"
   156  `
   157  	err = checkLXDBridgeConfiguration(badName)
   158  	c.Assert(err.Error(), gc.Equals, LXDBridgeFile+` has a bridge named meshuggahrocks, not lxdbr0
   159  It looks like your lxdbr0 has not yet been configured. Please configure it via:
   160  
   161  	sudo dpkg-reconfigure -p medium lxd
   162  
   163  and then bootstrap again.`)
   164  
   165  	noSubnets := `
   166  USE_LXD_BRIDGE="true"
   167  LXD_BRIDGE="lxdbr0"
   168  `
   169  	err = checkLXDBridgeConfiguration(noSubnets)
   170  	c.Assert(err.Error(), gc.Equals, `lxdbr0 has no ipv4 or ipv6 subnet enabled
   171  It looks like your lxdbr0 has not yet been configured. Please configure it via:
   172  
   173  	sudo dpkg-reconfigure -p medium lxd
   174  
   175  and then bootstrap again.`)
   176  
   177  }
   178  
   179  func (cs *ConnectSuite) TestRemoteConnectError(c *gc.C) {
   180  	cs.PatchValue(&lxdNewClientFromInfo, fakeNewClientFromInfo)
   181  
   182  	cfg, err := Config{
   183  		Remote: Remote{
   184  			Name: "foo",
   185  			Host: "a.b.c",
   186  			Cert: &Cert{
   187  				Name:    "really-valid",
   188  				CertPEM: []byte("kinda-public"),
   189  				KeyPEM:  []byte("super-secret"),
   190  			},
   191  		},
   192  	}.WithDefaults()
   193  	c.Assert(err, jc.ErrorIsNil)
   194  	_, err = Connect(cfg)
   195  
   196  	c.Assert(errors.Cause(err), gc.Equals, testerr)
   197  }
   198  
   199  func (*ConnectSuite) CheckLogContains(c *gc.C, suffix string) {
   200  	c.Check(c.GetTestLog(), gc.Matches, "(?s).*WARNING juju.tools.lxdclient "+suffix+".*")
   201  }
   202  
   203  func (*ConnectSuite) CheckVersionSupported(c *gc.C, version string, supported bool) {
   204  	c.Check(isSupportedAPIVersion(version), gc.Equals, supported)
   205  }
   206  
   207  func (cs *ConnectSuite) TestBadVersionChecks(c *gc.C) {
   208  	cs.CheckVersionSupported(c, "foo", false)
   209  	cs.CheckLogContains(c, `LXD API version "foo": expected format <major>\.<minor>`)
   210  
   211  	cs.CheckVersionSupported(c, "a.b", false)
   212  	cs.CheckLogContains(c, `LXD API version "a.b": unexpected major number: strconv.(ParseInt|Atoi): parsing "a": invalid syntax`)
   213  
   214  	cs.CheckVersionSupported(c, "0.9", false)
   215  	cs.CheckLogContains(c, `LXD API version "0.9": expected major version 1 or later`)
   216  }
   217  
   218  func (cs *ConnectSuite) TestGoodVersionChecks(c *gc.C) {
   219  	cs.CheckVersionSupported(c, "1.0", true)
   220  	cs.CheckVersionSupported(c, "2.0", true)
   221  	cs.CheckVersionSupported(c, "2.1", true)
   222  }
   223  
   224  var testerr = errors.Errorf("boo!")
   225  
   226  func fakeNewClientFromInfo(info lxd.ConnectInfo) (*lxd.Client, error) {
   227  	return nil, testerr
   228  }