Ejemplo n.º 1
0
func getPodDefaultIP(workDir string) (string, error) {
	// get pod lock
	l, err := lock.NewLock(workDir, lock.Dir)
	if err != nil {
		return "", err
	}

	// get file descriptor for lock
	fd, err := l.Fd()
	if err != nil {
		return "", err
	}

	// use this descriptor as method of reading pod network configuration
	nets, err := netinfo.LoadAt(fd)
	if err != nil {
		return "", err
	}
	// kvm flavored container must have at first position default vm<->host network
	if len(nets) == 0 {
		return "", fmt.Errorf("pod has no configured networks")
	}

	for _, net := range nets {
		if net.NetName == "default" || net.NetName == "default-restricted" {
			return net.IP.String(), nil
		}
	}

	return "", fmt.Errorf("pod has no default network!")
}
Ejemplo n.º 2
0
/*
 * NewNetPreserveNetNameTest checks if netName is set if network is configured via flannel
 */
func NewNetPreserveNetNameTest() testutils.Test {
	return testutils.TestFunc(func(t *testing.T) {
		ctx := testutils.NewRktRunCtx()
		defer ctx.Cleanup()

		netdir, ntFlannel, err := mockFlannelNetwork(t, ctx)
		if err != nil {
			t.Errorf("Can't mock flannel network: %v", err)
		}

		defer os.RemoveAll(netdir)
		defer os.Remove(ntFlannel.SubnetFile)

		podUUIDFile := filepath.Join(ctx.DataDir(), "pod_uuid")
		defer os.Remove(podUUIDFile)

		// start container with 'flannel' network
		testImageArgs := []string{"--exec=/inspect"}
		testImage := patchTestACI("rkt-inspect-networking.aci", testImageArgs...)
		defer os.Remove(testImage)

		cmd := fmt.Sprintf("%s --debug --insecure-options=image run --uuid-file-save=%s --net=%s --mds-register=false %s", ctx.Cmd(), podUUIDFile, ntFlannel.Name, testImage)
		spawnAndWaitOrFail(t, cmd, 0)

		podUUID, err := ioutil.ReadFile(podUUIDFile)
		if err != nil {
			t.Fatalf("Can't read pod UUID: %v", err)
		}

		// read net-info.json created for pod
		podDir := filepath.Join(ctx.DataDir(), "pods", "run", string(podUUID))
		podDirfd, err := syscall.Open(podDir, syscall.O_RDONLY|syscall.O_DIRECTORY, 0)
		if err != nil {
			t.Fatalf("Can't open pod directory for reading! %v", err)
		}

		info, err := netinfo.LoadAt(podDirfd)
		if err != nil {
			t.Fatalf("Can't open net-info.json for reading: %v", err)
		}

		if len(info) != 2 {
			t.Fatalf("Incorrect number of networks: %v", len(info))
		}

		found := false
		for _, net := range info {
			if net.NetName == ntFlannel.Name {
				found = true
				break
			}
		}

		if !found {
			t.Fatalf("Network '%s' not found!\nnetInfo[0]: %v\nnetInfo[1]: %v", ntFlannel.Name, info[0], info[1])
		}
	})
}
Ejemplo n.º 3
0
// Load creates the Networking object from saved state.
// Assumes the current netns is that of the host.
func Load(podRoot string, podID *types.UUID) (*Networking, error) {
	// the current directory is pod root
	pdirfd, err := syscall.Open(podRoot, syscall.O_RDONLY|syscall.O_DIRECTORY, 0)
	if err != nil {
		return nil, errwrap.Wrap(fmt.Errorf("failed to open pod root directory (%v)", podRoot), err)
	}
	defer syscall.Close(pdirfd)

	nis, err := netinfo.LoadAt(pdirfd)
	if err != nil {
		return nil, err
	}

	var nets []activeNet
	for _, ni := range nis {
		n, err := loadNet(ni.ConfPath)
		if err != nil {
			if !os.IsNotExist(err) {
				stderr.PrintE(fmt.Sprintf("error loading %q; ignoring", ni.ConfPath), err)
			}
			continue
		}

		// make a copy of ni to make it a unique object as it's saved via ptr
		rti := ni
		n.runtime = &rti
		nets = append(nets, *n)
	}

	p := podEnv{
		podRoot: podRoot,
		podID:   *podID,
	}

	podNS, err := p.podNSLoad()
	if err != nil {
		return nil, err
	}
	p.podNS = podNS

	return &Networking{
		podEnv: p,
		nets:   nets,
	}, nil
}
Ejemplo n.º 4
0
// Load creates the Networking object from saved state.
// Assumes the current netns is that of the host.
func Load(podRoot string, podID *types.UUID) (*Networking, error) {
	// the current directory is pod root
	pdirfd, err := syscall.Open(podRoot, syscall.O_RDONLY|syscall.O_DIRECTORY, 0)
	if err != nil {
		return nil, fmt.Errorf("Failed to open pod root directory (%v): %v", podRoot, err)
	}
	defer syscall.Close(pdirfd)

	nis, err := netinfo.LoadAt(pdirfd)
	if err != nil {
		return nil, err
	}

	hostNS, err := os.Open(selfNetNS)
	if err != nil {
		return nil, err
	}

	nets := []activeNet{}
	for _, ni := range nis {
		n, err := loadNet(ni.ConfPath)
		if err != nil {
			if !os.IsNotExist(err) {
				log.Printf("Error loading %q: %v; ignoring", ni.ConfPath, err)
			}
			continue
		}

		// make a copy of ni to make it a unique object as it's saved via ptr
		rti := ni
		nets = append(nets, activeNet{
			conf:    n.conf,
			runtime: &rti,
		})
	}

	return &Networking{
		podEnv: podEnv{
			podRoot: podRoot,
			podID:   *podID,
		},
		hostNS: hostNS,
		nets:   nets,
	}, nil
}
Ejemplo n.º 5
0
// getPod returns a pod struct representing the given pod.
// The returned lock is always left in an open but unlocked state.
// The pod must be closed using pod.Close()
func getPod(uuid *types.UUID) (*pod, error) {
	if err := initPods(); err != nil {
		return nil, err
	}

	p := &pod{uuid: uuid}

	// we try open the pod in all possible directories, in the same order the states occur
	l, err := lock.NewLock(p.embryoPath(), lock.Dir)
	if err == nil {
		p.isEmbryo = true
	} else if err == lock.ErrNotExist {
		l, err = lock.NewLock(p.preparePath(), lock.Dir)
		if err == nil {
			// treat as aborted prepare until lock is tested
			p.isAbortedPrepare = true
		} else if err == lock.ErrNotExist {
			l, err = lock.NewLock(p.preparedPath(), lock.Dir)
			if err == nil {
				p.isPrepared = true
			} else if err == lock.ErrNotExist {
				l, err = lock.NewLock(p.runPath(), lock.Dir)
				if err == nil {
					// treat as exited until lock is tested
					p.isExited = true
				} else if err == lock.ErrNotExist {
					l, err = lock.NewLock(p.exitedGarbagePath(), lock.Dir)
					if err == lock.ErrNotExist {
						l, err = lock.NewLock(p.garbagePath(), lock.Dir)
						if err == nil {
							p.isGarbage = true
						} else {
							return nil, fmt.Errorf("pod %q not found", uuid)
						}
					} else if err == nil {
						p.isExitedGarbage = true
						p.isExited = true // ExitedGarbage is _always_ implicitly exited
					}
				}
			}
		}
	}

	if err != nil && err != lock.ErrNotExist {
		return nil, errwrap.Wrap(fmt.Errorf("error opening pod %q", uuid), err)
	}

	if !p.isPrepared && !p.isEmbryo {
		// preparing, run, exitedGarbage, and garbage dirs use exclusive locks to indicate preparing/aborted, running/exited, and deleting/marked
		if err = l.TrySharedLock(); err != nil {
			if err != lock.ErrLocked {
				l.Close()
				return nil, errwrap.Wrap(errors.New("unexpected lock error"), err)
			}
			if p.isExitedGarbage {
				// locked exitedGarbage is also being deleted
				p.isExitedDeleting = true
			} else if p.isExited {
				// locked exited and !exitedGarbage is not exited (default in the run dir)
				p.isExited = false
			} else if p.isAbortedPrepare {
				// locked in preparing is preparing, not aborted (default in the preparing dir)
				p.isAbortedPrepare = false
				p.isPreparing = true
			} else if p.isGarbage {
				// locked in non-exited garbage is deleting
				p.isDeleting = true
			}
			err = nil
		} else {
			l.Unlock()
		}
	}

	p.FileLock = l

	if p.isRunning() {
		cfd, err := p.Fd()
		if err != nil {
			return nil, errwrap.Wrap(fmt.Errorf("error acquiring pod %v dir fd", uuid), err)
		}
		p.nets, err = netinfo.LoadAt(cfd)
		// ENOENT is ok -- assume running with --net=host
		if err != nil && !os.IsNotExist(err) {
			return nil, errwrap.Wrap(fmt.Errorf("error opening pod %v netinfo", uuid), err)
		}
	}

	return p, nil
}
Ejemplo n.º 6
0
Archivo: pods.go Proyecto: joshix/rkt
// getPod returns a pod struct representing the given pod.
// The returned lock is always left in an open but unlocked state.
// The pod must be closed using pod.Close()
func getPod(dataDir string, uuid *types.UUID) (*Pod, error) {
	if err := initPods(dataDir); err != nil {
		return nil, err
	}

	p := &Pod{UUID: uuid, dataDir: dataDir}

	// dirStates is a list of directories -> state that directory existing
	// implies.
	// Its order matches the order states occur.
	dirStates := []struct {
		dir           string
		impliedStates []*bool
	}{
		{dir: p.embryoPath(), impliedStates: []*bool{&p.isEmbryo}},
		// For prepare, assume it's aborted prepare until it gets updated below
		{dir: p.preparePath(), impliedStates: []*bool{&p.isAbortedPrepare}},
		{dir: p.preparedPath(), impliedStates: []*bool{&p.isPrepared}},
		// For run, assume exited until the lock is tested
		{dir: p.runPath(), impliedStates: []*bool{&p.isExited}},
		// Exited garbage implies exited
		{dir: p.exitedGarbagePath(), impliedStates: []*bool{&p.isExitedGarbage, &p.isExited}},
		{dir: p.garbagePath(), impliedStates: []*bool{&p.isGarbage}},
	}

	var l *lock.FileLock
	var err error
	for _, dirState := range dirStates {
		l, err = lock.NewLock(dirState.dir, lock.Dir)
		if err == nil {
			for _, s := range dirState.impliedStates {
				*s = true
			}
			break
		}
		if err == lock.ErrNotExist {
			continue
		}
		// unexpected lock error
		return nil, errwrap.Wrap(fmt.Errorf("error opening pod %q", uuid), err)
	}

	if !p.isPrepared && !p.isEmbryo {
		// preparing, run, exitedGarbage, and garbage dirs use exclusive locks to indicate preparing/aborted, running/exited, and deleting/marked
		if err = l.TrySharedLock(); err != nil {
			if err != lock.ErrLocked {
				l.Close()
				return nil, errwrap.Wrap(errors.New("unexpected lock error"), err)
			}
			if p.isExitedGarbage {
				// locked exitedGarbage is also being deleted
				p.isExitedDeleting = true
			} else if p.isExited {
				// locked exited and !exitedGarbage is not exited (default in the run dir)
				p.isExited = false
			} else if p.isAbortedPrepare {
				// locked in preparing is preparing, not aborted (default in the preparing dir)
				p.isAbortedPrepare = false
				p.isPreparing = true
			} else if p.isGarbage {
				// locked in non-exited garbage is deleting
				p.isDeleting = true
			}
			err = nil
		} else {
			l.Unlock()
		}
	}

	p.FileLock = l

	if p.isRunning() {
		cfd, err := p.Fd()
		if err != nil {
			return nil, errwrap.Wrap(fmt.Errorf("error acquiring pod %v dir fd", uuid), err)
		}
		p.Nets, err = netinfo.LoadAt(cfd)
		// ENOENT is ok -- assume running with --net=host
		if err != nil && !os.IsNotExist(err) {
			return nil, errwrap.Wrap(fmt.Errorf("error opening pod %v netinfo", uuid), err)
		}
	}

	return p, nil
}