コード例 #1
0
func (daemon *Daemon) setupSecretDir(c *container.Container) (setupErr error) {
	if len(c.SecretReferences) == 0 {
		return nil
	}

	localMountPath := c.SecretMountPath()
	logrus.Debugf("secrets: setting up secret dir: %s", localMountPath)

	defer func() {
		if setupErr != nil {
			// cleanup
			_ = detachMounted(localMountPath)

			if err := os.RemoveAll(localMountPath); err != nil {
				log.Errorf("error cleaning up secret mount: %s", err)
			}
		}
	}()

	// retrieve possible remapped range start for root UID, GID
	rootUID, rootGID := daemon.GetRemappedUIDGID()
	// create tmpfs
	if err := idtools.MkdirAllAs(localMountPath, 0700, rootUID, rootGID); err != nil {
		return errors.Wrap(err, "error creating secret local mount path")
	}
	tmpfsOwnership := fmt.Sprintf("uid=%d,gid=%d", rootUID, rootGID)
	if err := mount.Mount("tmpfs", localMountPath, "tmpfs", "nodev,nosuid,noexec,"+tmpfsOwnership); err != nil {
		return errors.Wrap(err, "unable to setup secret mount")
	}

	for _, s := range c.SecretReferences {
		if c.SecretStore == nil {
			return fmt.Errorf("secret store is not initialized")
		}

		// TODO (ehazlett): use type switch when more are supported
		if s.File == nil {
			return fmt.Errorf("secret target type is not a file target")
		}

		targetPath := filepath.Clean(s.File.Name)
		// ensure that the target is a filename only; no paths allowed
		if targetPath != filepath.Base(targetPath) {
			return fmt.Errorf("error creating secret: secret must not be a path")
		}

		fPath := filepath.Join(localMountPath, targetPath)
		if err := idtools.MkdirAllAs(filepath.Dir(fPath), 0700, rootUID, rootGID); err != nil {
			return errors.Wrap(err, "error creating secret mount path")
		}

		logrus.WithFields(logrus.Fields{
			"name": s.File.Name,
			"path": fPath,
		}).Debug("injecting secret")
		secret := c.SecretStore.Get(s.SecretID)
		if secret == nil {
			return fmt.Errorf("unable to get secret from secret store")
		}
		if err := ioutil.WriteFile(fPath, secret.Spec.Data, s.File.Mode); err != nil {
			return errors.Wrap(err, "error injecting secret")
		}

		uid, err := strconv.Atoi(s.File.UID)
		if err != nil {
			return err
		}
		gid, err := strconv.Atoi(s.File.GID)
		if err != nil {
			return err
		}

		if err := os.Chown(fPath, rootUID+uid, rootGID+gid); err != nil {
			return errors.Wrap(err, "error setting ownership for secret")
		}
	}

	// remount secrets ro
	if err := mount.Mount("tmpfs", localMountPath, "tmpfs", "remount,ro,"+tmpfsOwnership); err != nil {
		return errors.Wrap(err, "unable to remount secret dir as readonly")
	}

	return nil
}