// GenerateMounts maps MountPoint paths to volumes, returning a list of mounts,
// each with a parameter indicating if it's an implicit empty volume from a
// Docker image.
7193
func GenerateMounts(ra *schema.RuntimeApp, podVolumes []types.Volume, convertedFromDocker bool) ([]Mount, error) {
	app := ra.App

	var genMnts []Mount

	vols := make(map[types.ACName]types.Volume)
	for _, v := range podVolumes {
		vols[v.Name] = v
	}

	// RuntimeApps have mounts, whereas Apps have mountPoints. mountPoints are partially for
	// Docker compat; since apps can declare mountpoints. However, if we just run with rkt run,
	// then we'll only have a Mount and no corresponding MountPoint.
	// Furthermore, Mounts can have embedded volumes in the case of the CRI.
	// So, we generate a pile of Mounts and their corresponding Volume

	// Map of hostpath -> Mount
	mnts := make(map[string]schema.Mount)

	// Check runtimeApp's Mounts
	for _, m := range ra.Mounts {
		mnts[m.Path] = m

		vol := m.AppVolume // Mounts can supply a volume
		if vol == nil {
			vv, ok := vols[m.Volume]
			if !ok {
				return nil, fmt.Errorf("could not find volume %s", m.Volume)
			}
			vol = &vv
		}

		// Find a corresponding MountPoint, which is optional
		ro := false
		for _, mp := range ra.App.MountPoints {
			if mp.Name == m.Volume {
				ro = mp.ReadOnly
				break
			}
		}
		if vol.ReadOnly != nil {
			ro = *vol.ReadOnly
		}

		switch vol.Kind {
		case "host":
		case "empty":
		default:
			return nil, fmt.Errorf("Volume %s has invalid kind %s", vol.Name, vol.Kind)
		}
		genMnts = append(genMnts,
			Mount{
				Mount:          m,
				DockerImplicit: false,
				ReadOnly:       ro,
				Volume:         *vol,
			})
	}

	// Now, match up MountPoints with Mounts or Volumes
	// If there's no Mount and no Volume, generate an empty volume
	for _, mp := range app.MountPoints {
		// there's already a Mount for this MountPoint, stop
		if _, ok := mnts[mp.Path]; ok {
			continue
		}

		// No Mount, try to match based on volume name
		vol, ok := vols[mp.Name]
		// there is no volume for this mount point, creating an "empty" volume
		// implicitly
		if !ok {
			defaultMode := "0755"
			defaultUID := 0
			defaultGID := 0
			uniqName := ra.Name + "-" + mp.Name
			emptyVol := types.Volume{
				Name: uniqName,
				Kind: "empty",
				Mode: &defaultMode,
				UID:  &defaultUID,
				GID:  &defaultGID,
			}

			log.Printf("warning: no volume specified for mount point %q, implicitly creating an \"empty\" volume. This volume will be removed when the pod is garbage-collected.", mp.Name)
			if convertedFromDocker {
				log.Printf("Docker converted image, initializing implicit volume with data contained at the mount point %q.", mp.Name)
			}

			vols[uniqName] = emptyVol
			genMnts = append(genMnts,
				Mount{
					Mount: schema.Mount{
						Volume: uniqName,
						Path:   mp.Path,
					},
					Volume:         emptyVol,
					ReadOnly:       mp.ReadOnly,
					DockerImplicit: convertedFromDocker,
				})
		} else {
			ro := mp.ReadOnly
			if vol.ReadOnly != nil {
				ro = *vol.ReadOnly
			}
			genMnts = append(genMnts,
				Mount{
					Mount: schema.Mount{
						Volume: vol.Name,
						Path:   mp.Path,
					},
					Volume:         vol,
					ReadOnly:       ro,
					DockerImplicit: false,
				})
		}
	}

	return genMnts, nil
}
818149
func (container *Container) SecretMounts() ([]Mount, error) {
	var mounts []Mount
	for _, r := range container.SecretReferences {
		if r.File == nil {
			continue
		}
		src, err := container.SecretFilePath(*r)
		if err != nil {
			return nil, err
		}
		mounts = append(mounts, Mount{
			Source:      src,
			Destination: getSecretTargetPath(r),
			Writable:    false,
		})
	}
	for _, r := range container.ConfigReferences {
		fPath, err := container.ConfigFilePath(*r)
		if err != nil {
			return nil, err
		}
		mounts = append(mounts, Mount{
			Source:      fPath,
			Destination: r.File.Name,
			Writable:    false,
		})
	}

	return mounts, nil
}
450434
func (m *Mounter) Mounts(sourcePath string) []string {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[sourcePath]
	if !ok {
		return nil
	}

	mounts := make([]string, len(v.Mountpoint))
	for i, v := range v.Mountpoint {
		mounts[i] = v.Path
	}

	return mounts
}
916343
func (g *Generator) ClearMounts() {
	if g.Config == nil {
		return
	}
	g.Config.Mounts = []rspec.Mount{}
}
148563
func (s *nonRoot) Generate(pod *api.Pod, container *api.Container) (*int64, error) {
	return nil, nil
}
842583
func WithMounts(mounts []specs.Mount) SpecOpts {
	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
		s.Mounts = append(s.Mounts, mounts...)
		return nil
	}
}
473721
func (s *ContainerDetail) SetMountPoints(v []*MountPoint) *ContainerDetail {
	s.MountPoints = v
	return s
}
576621
func (s *ContainerProperties) SetMountPoints(v []*MountPoint) *ContainerProperties {
	s.MountPoints = v
	return s
}
1165809
func GenerateManifests(appPath string, q *ManifestRequest) (*ManifestResponse, error) {
	var targetObjs []*unstructured.Unstructured
	var dest *v1alpha1.ApplicationDestination

	appSourceType, err := GetAppSourceType(q.ApplicationSource, appPath)
	switch appSourceType {
	case v1alpha1.ApplicationSourceTypeKsonnet:
		targetObjs, dest, err = ksShow(q.AppLabelKey, appPath, q.ApplicationSource.Ksonnet)
	case v1alpha1.ApplicationSourceTypeHelm:
		h := helm.NewHelmApp(appPath, q.HelmRepos)
		err := h.Init()
		if err != nil {
			return nil, err
		}
		defer h.Dispose()
		targetObjs, err = h.Template(q.AppLabelValue, q.Namespace, q.ApplicationSource.Helm)
		if err != nil {
			if !helm.IsMissingDependencyErr(err) {
				return nil, err
			}
			err = h.DependencyBuild()
			if err != nil {
				return nil, err
			}
			targetObjs, err = h.Template(q.AppLabelValue, q.Namespace, q.ApplicationSource.Helm)
			if err != nil {
				return nil, err
			}
		}
	case v1alpha1.ApplicationSourceTypeKustomize:
		k := kustomize.NewKustomizeApp(appPath, kustomizeCredentials(q.Repo))
		targetObjs, _, _, err = k.Build(q.ApplicationSource.Kustomize)
	case v1alpha1.ApplicationSourceTypePlugin:
		targetObjs, err = runConfigManagementPlugin(appPath, q, q.Plugins)
	case v1alpha1.ApplicationSourceTypeDirectory:
		var directory *v1alpha1.ApplicationSourceDirectory
		if directory = q.ApplicationSource.Directory; directory == nil {
			directory = &v1alpha1.ApplicationSourceDirectory{}
		}
		targetObjs, err = findManifests(appPath, *directory)
	}
	if err != nil {
		return nil, err
	}

	manifests := make([]string, 0)
	for _, obj := range targetObjs {
		var targets []*unstructured.Unstructured
		if obj.IsList() {
			err = obj.EachListItem(func(object runtime.Object) error {
				unstructuredObj, ok := object.(*unstructured.Unstructured)
				if ok {
					targets = append(targets, unstructuredObj)
					return nil
				}
				return fmt.Errorf("resource list item has unexpected type")
			})
			if err != nil {
				return nil, err
			}
		} else if isNullList(obj) {
			// noop
		} else {
			targets = []*unstructured.Unstructured{obj}
		}

		for _, target := range targets {
			if q.AppLabelKey != "" && q.AppLabelValue != "" && !kube.IsCRD(target) {
				err = kube.SetAppInstanceLabel(target, q.AppLabelKey, q.AppLabelValue)
				if err != nil {
					return nil, err
				}
			}
			manifestStr, err := json.Marshal(target.Object)
			if err != nil {
				return nil, err
			}
			manifests = append(manifests, string(manifestStr))
		}
	}

	res := ManifestResponse{
		Manifests:  manifests,
		SourceType: string(appSourceType),
	}
	if dest != nil {
		res.Namespace = dest.Namespace
		res.Server = dest.Server
	}
	return &res, nil
}
428496
func (n *NsenterMounter) Mount(source string, target string, fstype string, options []string) error {
	bind, bindRemountOpts := isBind(options)

	if bind {
		err := n.doNsenterMount(source, target, fstype, []string{"bind"})
		if err != nil {
			return err
		}
		return n.doNsenterMount(source, target, fstype, bindRemountOpts)
	}

	return n.doNsenterMount(source, target, fstype, options)
}
882729
func (p *pluginManager) GenerateArgs(logLevel int) plugin.Arg {
	return plugin.NewArg(logLevel, p.pprof)
}
344038
func Create(rootFS vfs.Filesystem) *MountFS {
	return &MountFS{
		rootFS:  rootFS,
		mounts:  make(map[string]vfs.Filesystem),
		parents: make(map[string][]string),
	}
}
817473
func generateKeys(d direction, algs directionAlgorithms, kex *kexResult) (iv, key, macKey []byte) {
	cipherMode := cipherModes[algs.Cipher]
	macMode := macModes[algs.MAC]

	iv = make([]byte, cipherMode.ivSize)
	key = make([]byte, cipherMode.keySize)
	macKey = make([]byte, macMode.keySize)

	generateKeyMaterial(iv, d.ivTag, kex)
	generateKeyMaterial(key, d.keyTag, kex)
	generateKeyMaterial(macKey, d.macKeyTag, kex)
	return
}
266496
func (m *Mounter) HasMounts(sourcePath string) int {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[sourcePath]
	if !ok {
		return 0
	}
	return len(v.Mountpoint)
}
1149926
func All(mounts []Mount, target string) error {
	for _, m := range mounts {
		if err := m.Mount(target); err != nil {
			return err
		}
	}
	return nil
}
965363
func flattenEcsVolumes(list []*ecs.Volume) []map[string]interface{} {
	result := make([]map[string]interface{}, 0, len(list))
	for _, volume := range list {
		l := map[string]interface{}{
			"name": *volume.Name,
		}

		if volume.Host != nil && volume.Host.SourcePath != nil {
			l["host_path"] = *volume.Host.SourcePath
		}

		if volume.DockerVolumeConfiguration != nil {
			l["docker_volume_configuration"] = flattenDockerVolumeConfiguration(volume.DockerVolumeConfiguration)
		}

		result = append(result, l)
	}
	return result
}
1020251
func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, error) {
	var mounts []container.Mount
	// TODO: tmpfs mounts should be part of Mountpoints
	tmpfsMounts := make(map[string]bool)
	tmpfsMountInfo, err := c.TmpfsMounts()
	if err != nil {
		return nil, err
	}
	for _, m := range tmpfsMountInfo {
		tmpfsMounts[m.Destination] = true
	}
	for _, m := range c.MountPoints {
		if tmpfsMounts[m.Destination] {
			continue
		}
		if err := daemon.lazyInitializeVolume(c.ID, m); err != nil {
			return nil, err
		}
		// If the daemon is being shutdown, we should not let a container start if it is trying to
		// mount the socket the daemon is listening on. During daemon shutdown, the socket
		// (/var/run/docker.sock by default) doesn't exist anymore causing the call to m.Setup to
		// create at directory instead. This in turn will prevent the daemon to restart.
		checkfunc := func(m *volumemounts.MountPoint) error {
			if _, exist := daemon.hosts[m.Source]; exist && daemon.IsShuttingDown() {
				return fmt.Errorf("Could not mount %q to container while the daemon is shutting down", m.Source)
			}
			return nil
		}

		path, err := m.Setup(c.MountLabel, daemon.idMapping.RootPair(), checkfunc)
		if err != nil {
			return nil, err
		}
		if !c.TrySetNetworkMount(m.Destination, path) {
			mnt := container.Mount{
				Source:      path,
				Destination: m.Destination,
				Writable:    m.RW,
				Propagation: string(m.Propagation),
			}
			if m.Spec.Type == mounttypes.TypeBind && m.Spec.BindOptions != nil {
				mnt.NonRecursive = m.Spec.BindOptions.NonRecursive
			}
			if m.Volume != nil {
				attributes := map[string]string{
					"driver":      m.Volume.DriverName(),
					"container":   c.ID,
					"destination": m.Destination,
					"read/write":  strconv.FormatBool(m.RW),
					"propagation": string(m.Propagation),
				}
				daemon.LogVolumeEvent(m.Volume.Name(), "mount", attributes)
			}
			mounts = append(mounts, mnt)
		}
	}

	mounts = sortMounts(mounts)
	netMounts := c.NetworkMounts()
	// if we are going to mount any of the network files from container
	// metadata, the ownership must be set properly for potential container
	// remapped root (user namespaces)
	rootIDs := daemon.idMapping.RootPair()
	for _, mount := range netMounts {
		// we should only modify ownership of network files within our own container
		// metadata repository. If the user specifies a mount path external, it is
		// up to the user to make sure the file has proper ownership for userns
		if strings.Index(mount.Source, daemon.repository) == 0 {
			if err := os.Chown(mount.Source, rootIDs.UID, rootIDs.GID); err != nil {
				return nil, err
			}
		}
	}
	return append(mounts, netMounts...), nil
}