func NewConfigDrive(cfg *config.CloudConfig) (*ConfigDrive, error) { drivePath, err := ioutil.TempDir("", "mantle-config-drive") if err != nil { return nil, err } userPath := path.Join(drivePath, "openstack/latest/user_data") err = os.MkdirAll(path.Dir(userPath), 0777) if err != nil { os.RemoveAll(drivePath) return nil, err } userData, err := os.OpenFile(userPath, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { os.RemoveAll(drivePath) return nil, err } defer userData.Close() _, err = userData.WriteString(cfg.String()) if err != nil { os.RemoveAll(drivePath) return nil, err } return &ConfigDrive{Directory: drivePath}, nil }
// Test that the kernel NFS server and client work within CoreOS. func NFS(c platform.TestCluster) error { /* server machine */ c1 := config.CloudConfig{ CoreOS: config.CoreOS{ Units: []config.Unit{ config.Unit{ Name: "rpcbind.service", Command: "start", }, config.Unit{ Name: "rpc-statd.service", Command: "start", }, config.Unit{ Name: "rpc-mountd.service", Command: "start", }, config.Unit{ Name: "nfsd.service", Command: "start", }, }, }, WriteFiles: []config.File{ config.File{ Content: "/tmp *(ro,insecure,all_squash,no_subtree_check,fsid=0)", Path: "/etc/exports", }, }, Hostname: "nfs1", } m1, err := c.NewMachine(c1.String()) if err != nil { return fmt.Errorf("Cluster.NewMachine: %s", err) } defer m1.Destroy() plog.Info("NFS server booted.") /* poke a file in /tmp */ tmp, err := m1.SSH("mktemp") if err != nil { return fmt.Errorf("Machine.SSH: %s", err) } plog.Infof("Test file %q created on server.", tmp) /* client machine */ nfstmpl := `[Unit] Description=NFS Client After=network-online.target Requires=network-online.target After=rpc-statd.service Requires=rpc-statd.service [Mount] What=%s:/tmp Where=/mnt Type=nfs Options=defaults,noexec ` c2 := config.CloudConfig{ CoreOS: config.CoreOS{ Units: []config.Unit{ config.Unit{ Name: "rpc-statd.service", Command: "start", }, config.Unit{ Name: "mnt.mount", Command: "start", Content: fmt.Sprintf(nfstmpl, m1.IP()), }, }, }, Hostname: "nfs2", } m2, err := c.NewMachine(c2.String()) if err != nil { return fmt.Errorf("Cluster.NewMachine: %s", err) } defer m2.Destroy() plog.Info("NFS client booted.") var lsmnt []byte plog.Info("Waiting for NFS mount on client...") /* there's probably a better wait to check the mount */ for i := 0; i < 5; i++ { lsmnt, _ = m2.SSH("ls /mnt") if len(lsmnt) != 0 { plog.Info("Got NFS mount.") break } time.Sleep(1 * time.Second) } if len(lsmnt) == 0 { return fmt.Errorf("Client /mnt is empty.") } if bytes.Contains(lsmnt, []byte(path.Base(string(tmp)))) != true { return fmt.Errorf("Client /mnt did not contain file %q from server /tmp -- /mnt: %s", tmp, lsmnt) } return nil }
func testNFS(c platform.TestCluster, nfsversion int) error { m1, err := c.NewMachine(nfsserverconf.String()) if err != nil { return fmt.Errorf("Cluster.NewMachine: %s", err) } defer m1.Destroy() plog.Info("NFS server booted.") /* poke a file in /tmp */ tmp, err := m1.SSH("mktemp") if err != nil { return fmt.Errorf("Machine.SSH: %s", err) } plog.Infof("Test file %q created on server.", tmp) c2 := config.CloudConfig{ CoreOS: config.CoreOS{ Units: []config.Unit{ config.Unit{ Name: "mnt.mount", Command: "start", Content: fmt.Sprintf(mounttmpl, m1.PrivateIP(), nfsversion), }, }, }, Hostname: "nfs2", } m2, err := c.NewMachine(c2.String()) if err != nil { return fmt.Errorf("Cluster.NewMachine: %s", err) } defer m2.Destroy() plog.Info("NFS client booted.") plog.Info("Waiting for NFS mount on client...") checkmount := func() error { status, err := m2.SSH("systemctl is-active mnt.mount") if err != nil || string(status) != "active" { return fmt.Errorf("mnt.mount status is %q: %v", status, err) } plog.Info("Got NFS mount.") return nil } if err = util.Retry(10, 3*time.Second, checkmount); err != nil { return err } _, err = m2.SSH(fmt.Sprintf("stat /mnt/%s", path.Base(string(tmp)))) if err != nil { return fmt.Errorf("file %q does not exist", tmp) } return nil }