本文整理汇总了Golang中github.com/docker/docker/pkg/system.IsAbs函数的典型用法代码示例。如果您正苦于以下问题:Golang IsAbs函数的具体用法?Golang IsAbs怎么用?Golang IsAbs使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IsAbs函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: copyFromContainer
func copyFromContainer(ctx context.Context, dockerCli *client.DockerCli, srcContainer, srcPath, dstPath string, cpParam *cpConfig) (err error) {
if dstPath != "-" {
// Get an absolute destination path.
dstPath, err = resolveLocalPath(dstPath)
if err != nil {
return err
}
}
// if client requests to follow symbol link, then must decide target file to be copied
var rebaseName string
if cpParam.followLink {
srcStat, err := statContainerPath(ctx, dockerCli, srcContainer, srcPath)
// If the destination is a symbolic link, we should follow it.
if err == nil && srcStat.Mode&os.ModeSymlink != 0 {
linkTarget := srcStat.LinkTarget
if !system.IsAbs(linkTarget) {
// Join with the parent directory.
srcParent, _ := archive.SplitPathDirEntry(srcPath)
linkTarget = filepath.Join(srcParent, linkTarget)
}
linkTarget, rebaseName = archive.GetRebaseName(srcPath, linkTarget)
srcPath = linkTarget
}
}
content, stat, err := dockerCli.Client().CopyFromContainer(ctx, srcContainer, srcPath)
if err != nil {
return err
}
defer content.Close()
if dstPath == "-" {
// Send the response to STDOUT.
_, err = io.Copy(os.Stdout, content)
return err
}
// Prepare source copy info.
srcInfo := archive.CopyInfo{
Path: srcPath,
Exists: true,
IsDir: stat.Mode.IsDir(),
RebaseName: rebaseName,
}
preArchive := content
if len(srcInfo.RebaseName) != 0 {
_, srcBase := archive.SplitPathDirEntry(srcInfo.Path)
preArchive = archive.RebaseArchiveEntries(content, srcBase, srcInfo.RebaseName)
}
// See comments in the implementation of `archive.CopyTo` for exactly what
// goes into deciding how and whether the source archive needs to be
// altered for the correct copy behavior.
return archive.CopyTo(preArchive, srcInfo, dstPath)
}
开发者ID:Raphaeljunior,项目名称:docker,代码行数:60,代码来源:cp.go
示例2: normaliseWorkdir
// normaliseWorkdir normalises a user requested working directory in a
// platform sematically consistent way.
func normaliseWorkdir(current string, requested string) (string, error) {
if requested == "" {
return "", fmt.Errorf("cannot normalise nothing")
}
current = filepath.FromSlash(current)
requested = filepath.FromSlash(requested)
// Target semantics is C:\somefolder, specifically in the format:
// UPPERCASEDriveLetter-Colon-Backslash-FolderName. We are already
// guaranteed that `current`, if set, is consistent. This allows us to
// cope correctly with any of the following in a Dockerfile:
// WORKDIR a --> C:\a
// WORKDIR c:\\foo --> C:\foo
// WORKDIR \\foo --> C:\foo
// WORKDIR /foo --> C:\foo
// WORKDIR c:\\foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
// WORKDIR C:/foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
// WORKDIR C:/foo \ WORKDIR \\bar --> C:\foo --> C:\bar
// WORKDIR /foo \ WORKDIR c:/bar --> C:\foo --> C:\bar
if len(current) == 0 || system.IsAbs(requested) {
if (requested[0] == os.PathSeparator) ||
(len(requested) > 1 && string(requested[1]) != ":") ||
(len(requested) == 1) {
requested = filepath.Join(`C:\`, requested)
}
} else {
requested = filepath.Join(current, requested)
}
// Upper-case drive letter
return (strings.ToUpper(string(requested[0])) + requested[1:]), nil
}
开发者ID:RAMESHBABUK,项目名称:docker,代码行数:34,代码来源:dispatchers_windows.go
示例3: verifyContainerSettings
// verifyContainerSettings performs validation of the hostconfig and config
// structures.
func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
// First perform verification of settings common across all platforms.
if config != nil {
if config.WorkingDir != "" {
config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
if !system.IsAbs(config.WorkingDir) {
return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path.", config.WorkingDir)
}
}
}
if hostConfig == nil {
return nil, nil
}
for port := range hostConfig.PortBindings {
_, portStr := nat.SplitProtoPort(string(port))
if _, err := nat.ParsePort(portStr); err != nil {
return nil, fmt.Errorf("Invalid port specification: %q", portStr)
}
for _, pb := range hostConfig.PortBindings[port] {
_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
if err != nil {
return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
}
}
}
// Now do platform-specific verification
return verifyPlatformContainerSettings(daemon, hostConfig, config)
}
开发者ID:rzzdy,项目名称:docker,代码行数:34,代码来源:daemon.go
示例4: normaliseDest
// normaliseDest normalises the destination of a COPY/ADD command in a
// platform semantically consistent way.
func normaliseDest(cmdName, workingDir, requested string) (string, error) {
dest := filepath.FromSlash(requested)
endsInSlash := strings.HasSuffix(dest, string(os.PathSeparator))
// We are guaranteed that the working directory is already consistent,
// However, Windows also has, for now, the limitation that ADD/COPY can
// only be done to the system drive, not any drives that might be present
// as a result of a bind mount.
//
// So... if the path requested is Linux-style absolute (/foo or \\foo),
// we assume it is the system drive. If it is a Windows-style absolute
// (DRIVE:\\foo), error if DRIVE is not C. And finally, ensure we
// strip any configured working directories drive letter so that it
// can be subsequently legitimately converted to a Windows volume-style
// pathname.
// Not a typo - filepath.IsAbs, not system.IsAbs on this next check as
// we only want to validate where the DriveColon part has been supplied.
if filepath.IsAbs(dest) {
if strings.ToUpper(string(dest[0])) != "C" {
return "", fmt.Errorf("Windows does not support %s with a destinations not on the system drive (C:)", cmdName)
}
dest = dest[2:] // Strip the drive letter
}
// Cannot handle relative where WorkingDir is not the system drive.
if len(workingDir) > 0 {
if ((len(workingDir) > 1) && !system.IsAbs(workingDir[2:])) || (len(workingDir) == 1) {
return "", fmt.Errorf("Current WorkingDir %s is not platform consistent", workingDir)
}
if !system.IsAbs(dest) {
if string(workingDir[0]) != "C" {
return "", fmt.Errorf("Windows does not support %s with relative paths when WORKDIR is not the system drive", cmdName)
}
dest = filepath.Join(string(os.PathSeparator), workingDir[2:], dest)
// Make sure we preserve any trailing slash
if endsInSlash {
dest += string(os.PathSeparator)
}
}
}
return dest, nil
}
开发者ID:SUSE,项目名称:docker.mirror,代码行数:45,代码来源:internals_windows.go
示例5: verifyContainerSettings
// verifyContainerSettings performs validation of the hostconfig and config
// structures.
func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool, validateHostname bool) ([]string, error) {
// First perform verification of settings common across all platforms.
if config != nil {
if config.WorkingDir != "" {
config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
if !system.IsAbs(config.WorkingDir) {
return nil, fmt.Errorf("the working directory '%s' is invalid, it needs to be an absolute path", config.WorkingDir)
}
}
if len(config.StopSignal) > 0 {
_, err := signal.ParseSignal(config.StopSignal)
if err != nil {
return nil, err
}
}
// Validate if the given hostname is RFC 1123 (https://tools.ietf.org/html/rfc1123) compliant.
if validateHostname && len(config.Hostname) > 0 {
// RFC1123 specifies that 63 bytes is the maximium length
// Windows has the limitation of 63 bytes in length
// Linux hostname is limited to HOST_NAME_MAX=64, not including the terminating null byte.
// We limit the length to 63 bytes here to match RFC1035 and RFC1123.
matched, _ := regexp.MatchString("^(([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])\\.)*([[:alnum:]]|[[:alnum:]][[:alnum:]\\-]*[[:alnum:]])$", config.Hostname)
if len(config.Hostname) > 63 || !matched {
return nil, fmt.Errorf("invalid hostname format: %s", config.Hostname)
}
}
}
if hostConfig == nil {
return nil, nil
}
if hostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
return nil, fmt.Errorf("can't create 'AutoRemove' container with restart policy")
}
for port := range hostConfig.PortBindings {
_, portStr := nat.SplitProtoPort(string(port))
if _, err := nat.ParsePort(portStr); err != nil {
return nil, fmt.Errorf("invalid port specification: %q", portStr)
}
for _, pb := range hostConfig.PortBindings[port] {
_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
if err != nil {
return nil, fmt.Errorf("invalid port specification: %q", pb.HostPort)
}
}
}
// Now do platform-specific verification
return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
}
开发者ID:maxim28,项目名称:docker,代码行数:57,代码来源:container.go
示例6: normaliseDest
// normaliseDest normalises the destination of a COPY/ADD command in a
// platform semantically consistent way.
func normaliseDest(cmdName, workingDir, requested string) (string, error) {
dest := filepath.FromSlash(requested)
endsInSlash := strings.HasSuffix(requested, string(os.PathSeparator))
if !system.IsAbs(requested) {
dest = filepath.Join(string(os.PathSeparator), filepath.FromSlash(workingDir), dest)
// Make sure we preserve any trailing slash
if endsInSlash {
dest += string(os.PathSeparator)
}
}
return dest, nil
}
开发者ID:SUSE,项目名称:docker.mirror,代码行数:14,代码来源:internals_unix.go
示例7: normaliseWorkdir
// normaliseWorkdir normalises a user requested working directory in a
// platform sematically consistent way.
func normaliseWorkdir(current string, requested string) (string, error) {
if requested == "" {
return "", fmt.Errorf("cannot normalise nothing")
}
// `filepath.Clean` will replace "" with "." so skip in that case
if current != "" {
current = filepath.Clean(current)
}
if requested != "" {
requested = filepath.Clean(requested)
}
// If either current or requested in Windows is:
// C:
// C:.
// then an error will be thrown as the definition for the above
// refers to `current directory on drive C:`
// Since filepath.Clean() will automatically normalize the above
// to `C:.`, we only need to check the last format
if pattern.MatchString(current) {
return "", fmt.Errorf("%s is not a directory. If you are specifying a drive letter, please add a trailing '\\'", current)
}
if pattern.MatchString(requested) {
return "", fmt.Errorf("%s is not a directory. If you are specifying a drive letter, please add a trailing '\\'", requested)
}
// Target semantics is C:\somefolder, specifically in the format:
// UPPERCASEDriveLetter-Colon-Backslash-FolderName. We are already
// guaranteed that `current`, if set, is consistent. This allows us to
// cope correctly with any of the following in a Dockerfile:
// WORKDIR a --> C:\a
// WORKDIR c:\\foo --> C:\foo
// WORKDIR \\foo --> C:\foo
// WORKDIR /foo --> C:\foo
// WORKDIR c:\\foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
// WORKDIR C:/foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
// WORKDIR C:/foo \ WORKDIR \\bar --> C:\foo --> C:\bar
// WORKDIR /foo \ WORKDIR c:/bar --> C:\foo --> C:\bar
if len(current) == 0 || system.IsAbs(requested) {
if (requested[0] == os.PathSeparator) ||
(len(requested) > 1 && string(requested[1]) != ":") ||
(len(requested) == 1) {
requested = filepath.Join(`C:\`, requested)
}
} else {
requested = filepath.Join(current, requested)
}
// Upper-case drive letter
return (strings.ToUpper(string(requested[0])) + requested[1:]), nil
}
开发者ID:msabansal,项目名称:docker,代码行数:53,代码来源:dispatchers_windows.go
示例8: splitCpArg
// We use `:` as a delimiter between CONTAINER and PATH, but `:` could also be
// in a valid LOCALPATH, like `file:name.txt`. We can resolve this ambiguity by
// requiring a LOCALPATH with a `:` to be made explicit with a relative or
// absolute path:
// `/path/to/file:name.txt` or `./file:name.txt`
//
// This is apparently how `scp` handles this as well:
// http://www.cyberciti.biz/faq/rsync-scp-file-name-with-colon-punctuation-in-it/
//
// We can't simply check for a filepath separator because container names may
// have a separator, e.g., "host0/cname1" if container is in a Docker cluster,
// so we have to check for a `/` or `.` prefix. Also, in the case of a Windows
// client, a `:` could be part of an absolute Windows path, in which case it
// is immediately proceeded by a backslash.
func splitCpArg(arg string) (container, path string) {
if system.IsAbs(arg) {
// Explicit local absolute path, e.g., `C:\foo` or `/foo`.
return "", arg
}
parts := strings.SplitN(arg, ":", 2)
if len(parts) == 1 || strings.HasPrefix(parts[0], ".") {
// Either there's no `:` in the arg
// OR it's an explicit local relative path like `./file:name.txt`.
return "", arg
}
return parts[0], parts[1]
}
开发者ID:Raphaeljunior,项目名称:docker,代码行数:30,代码来源:cp.go
示例9: workdir
// WORKDIR /tmp
//
// Set the working directory for future RUN/CMD/etc statements.
//
func workdir(b *Builder, args []string, attributes map[string]bool, original string) error {
if len(args) != 1 {
return errExactlyOneArgument("WORKDIR")
}
if err := b.flags.Parse(); err != nil {
return err
}
// This is from the Dockerfile and will not necessarily be in platform
// specific semantics, hence ensure it is converted.
workdir := filepath.FromSlash(args[0])
current := filepath.FromSlash(b.runConfig.WorkingDir)
if runtime.GOOS == "windows" {
// Windows is a little more complicated than Linux. This code ensures
// we end up with a workdir which is consistent in terms of platform
// semantics. This means C:\somefolder, specifically in the format:
// UPPERCASEDriveLetter-Colon-Backslash-FolderName. We are already
// guaranteed that `current`, if set, is consistent. This allows us to
// cope correctly with any of the following in a Dockerfile:
// WORKDIR a --> C:\a
// WORKDIR c:\\foo --> C:\foo
// WORKDIR \\foo --> C:\foo
// WORKDIR /foo --> C:\foo
// WORKDIR c:\\foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
// WORKDIR C:/foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
// WORKDIR C:/foo \ WORKDIR \\bar --> C:\foo --> C:\bar
// WORKDIR /foo \ WORKDIR c:/bar --> C:\foo --> C:\bar
if len(current) == 0 || system.IsAbs(workdir) {
if (workdir[0] == os.PathSeparator) ||
(len(workdir) > 1 && string(workdir[1]) != ":") ||
(len(workdir) == 1) {
workdir = filepath.Join(`C:\`, workdir)
}
} else {
workdir = filepath.Join(current, workdir)
}
workdir = strings.ToUpper(string(workdir[0])) + workdir[1:] // Upper-case drive letter
} else {
if !filepath.IsAbs(workdir) {
workdir = filepath.Join(string(os.PathSeparator), current, workdir)
}
}
b.runConfig.WorkingDir = workdir
return b.commit("", b.runConfig.Cmd, fmt.Sprintf("WORKDIR %v", workdir))
}
开发者ID:beerbubble,项目名称:docker,代码行数:51,代码来源:dispatchers.go
示例10: verifyContainerSettings
// verifyContainerSettings performs validation of the hostconfig and config
// structures.
func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
// First perform verification of settings common across all platforms.
if config != nil {
if config.WorkingDir != "" {
config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
if !system.IsAbs(config.WorkingDir) {
return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path", config.WorkingDir)
}
}
if len(config.StopSignal) > 0 {
_, err := signal.ParseSignal(config.StopSignal)
if err != nil {
return nil, err
}
}
}
if hostConfig == nil {
return nil, nil
}
logCfg := daemon.getLogConfig(hostConfig.LogConfig)
if err := logger.ValidateLogOpts(logCfg.Type, logCfg.Config); err != nil {
return nil, err
}
for port := range hostConfig.PortBindings {
_, portStr := nat.SplitProtoPort(string(port))
if _, err := nat.ParsePort(portStr); err != nil {
return nil, fmt.Errorf("Invalid port specification: %q", portStr)
}
for _, pb := range hostConfig.PortBindings[port] {
_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
if err != nil {
return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
}
}
}
// Now do platform-specific verification
return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
}
开发者ID:fntlnz,项目名称:docker,代码行数:46,代码来源:daemon.go
示例11: workdir
// WORKDIR /tmp
//
// Set the working directory for future RUN/CMD/etc statements.
//
func workdir(b *Builder, args []string, attributes map[string]bool, original string) error {
if len(args) != 1 {
return derr.ErrorCodeExactlyOneArg.WithArgs("WORKDIR")
}
if err := b.flags.Parse(); err != nil {
return err
}
// This is from the Dockerfile and will not necessarily be in platform
// specific semantics, hence ensure it is converted.
workdir := filepath.FromSlash(args[0])
if !system.IsAbs(workdir) {
current := filepath.FromSlash(b.runConfig.WorkingDir)
workdir = filepath.Join(string(os.PathSeparator), current, workdir)
}
b.runConfig.WorkingDir = workdir
return b.commit("", b.runConfig.Cmd, fmt.Sprintf("WORKDIR %v", workdir))
}
开发者ID:hallyn,项目名称:docker,代码行数:26,代码来源:dispatchers.go
示例12: copyToContainer
func copyToContainer(ctx context.Context, dockerCli *client.DockerCli, srcPath, dstContainer, dstPath string, cpParam *cpConfig) (err error) {
if srcPath != "-" {
// Get an absolute source path.
srcPath, err = resolveLocalPath(srcPath)
if err != nil {
return err
}
}
// In order to get the copy behavior right, we need to know information
// about both the source and destination. The API is a simple tar
// archive/extract API but we can use the stat info header about the
// destination to be more informed about exactly what the destination is.
// Prepare destination copy info by stat-ing the container path.
dstInfo := archive.CopyInfo{Path: dstPath}
dstStat, err := statContainerPath(ctx, dockerCli, dstContainer, dstPath)
// If the destination is a symbolic link, we should evaluate it.
if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
linkTarget := dstStat.LinkTarget
if !system.IsAbs(linkTarget) {
// Join with the parent directory.
dstParent, _ := archive.SplitPathDirEntry(dstPath)
linkTarget = filepath.Join(dstParent, linkTarget)
}
dstInfo.Path = linkTarget
dstStat, err = statContainerPath(ctx, dockerCli, dstContainer, linkTarget)
}
// Ignore any error and assume that the parent directory of the destination
// path exists, in which case the copy may still succeed. If there is any
// type of conflict (e.g., non-directory overwriting an existing directory
// or vice versa) the extraction will fail. If the destination simply did
// not exist, but the parent directory does, the extraction will still
// succeed.
if err == nil {
dstInfo.Exists, dstInfo.IsDir = true, dstStat.Mode.IsDir()
}
var (
content io.Reader
resolvedDstPath string
)
if srcPath == "-" {
// Use STDIN.
content = os.Stdin
resolvedDstPath = dstInfo.Path
if !dstInfo.IsDir {
return fmt.Errorf("destination %q must be a directory", fmt.Sprintf("%s:%s", dstContainer, dstPath))
}
} else {
// Prepare source copy info.
srcInfo, err := archive.CopyInfoSourcePath(srcPath, cpParam.followLink)
if err != nil {
return err
}
srcArchive, err := archive.TarResource(srcInfo)
if err != nil {
return err
}
defer srcArchive.Close()
// With the stat info about the local source as well as the
// destination, we have enough information to know whether we need to
// alter the archive that we upload so that when the server extracts
// it to the specified directory in the container we get the desired
// copy behavior.
// See comments in the implementation of `archive.PrepareArchiveCopy`
// for exactly what goes into deciding how and whether the source
// archive needs to be altered for the correct copy behavior when it is
// extracted. This function also infers from the source and destination
// info which directory to extract to, which may be the parent of the
// destination that the user specified.
dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo)
if err != nil {
return err
}
defer preparedArchive.Close()
resolvedDstPath = dstDir
content = preparedArchive
}
options := types.CopyToContainerOptions{
AllowOverwriteDirWithFile: false,
}
return dockerCli.Client().CopyToContainer(ctx, dstContainer, resolvedDstPath, content, options)
}
开发者ID:Raphaeljunior,项目名称:docker,代码行数:94,代码来源:cp.go
示例13: verifyContainerSettings
// verifyContainerSettings performs validation of the hostconfig and config
// structures.
func (daemon *Daemon) verifyContainerSettings(hostConfig *containertypes.HostConfig, config *containertypes.Config, update bool) ([]string, error) {
// First perform verification of settings common across all platforms.
if config != nil {
if config.WorkingDir != "" {
config.WorkingDir = filepath.FromSlash(config.WorkingDir) // Ensure in platform semantics
if !system.IsAbs(config.WorkingDir) {
return nil, fmt.Errorf("the working directory '%s' is invalid, it needs to be an absolute path", config.WorkingDir)
}
}
if len(config.StopSignal) > 0 {
_, err := signal.ParseSignal(config.StopSignal)
if err != nil {
return nil, err
}
}
// Validate if Env contains empty variable or not (e.g., ``, `=foo`)
for _, env := range config.Env {
if _, err := opts.ValidateEnv(env); err != nil {
return nil, err
}
}
}
if hostConfig == nil {
return nil, nil
}
if hostConfig.AutoRemove && !hostConfig.RestartPolicy.IsNone() {
return nil, fmt.Errorf("can't create 'AutoRemove' container with restart policy")
}
for port := range hostConfig.PortBindings {
_, portStr := nat.SplitProtoPort(string(port))
if _, err := nat.ParsePort(portStr); err != nil {
return nil, fmt.Errorf("invalid port specification: %q", portStr)
}
for _, pb := range hostConfig.PortBindings[port] {
_, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
if err != nil {
return nil, fmt.Errorf("invalid port specification: %q", pb.HostPort)
}
}
}
p := hostConfig.RestartPolicy
switch p.Name {
case "always", "unless-stopped", "no":
if p.MaximumRetryCount != 0 {
return nil, fmt.Errorf("maximum retry count cannot be used with restart policy '%s'", p.Name)
}
case "on-failure":
if p.MaximumRetryCount < 0 {
return nil, fmt.Errorf("maximum retry count cannot be negative")
}
case "":
// do nothing
default:
return nil, fmt.Errorf("invalid restart policy '%s'", p.Name)
}
// Now do platform-specific verification
return verifyPlatformContainerSettings(daemon, hostConfig, config, update)
}
开发者ID:haoshuwei,项目名称:docker,代码行数:69,代码来源:container.go
示例14: calcCopyInfo
func calcCopyInfo(b *builder, cmdName string, cInfos *[]*copyInfo, origPath string, destPath string, allowRemote bool, allowDecompression bool, allowWildcards bool) error {
// Work in daemon-specific OS filepath semantics. However, we save
// the the origPath passed in here, as it might also be a URL which
// we need to check for in this function.
passedInOrigPath := origPath
origPath = filepath.FromSlash(origPath)
destPath = filepath.FromSlash(destPath)
if origPath != "" && origPath[0] == os.PathSeparator && len(origPath) > 1 {
origPath = origPath[1:]
}
origPath = strings.TrimPrefix(origPath, "."+string(os.PathSeparator))
// Twiddle the destPath when its a relative path - meaning, make it
// relative to the WORKINGDIR
if !system.IsAbs(destPath) {
hasSlash := strings.HasSuffix(destPath, string(os.PathSeparator))
destPath = filepath.Join(string(os.PathSeparator), filepath.FromSlash(b.Config.WorkingDir), destPath)
// Make sure we preserve any trailing slash
if hasSlash {
destPath += string(os.PathSeparator)
}
}
// In the remote/URL case, download it and gen its hashcode
if urlutil.IsURL(passedInOrigPath) {
// As it's a URL, we go back to processing on what was passed in
// to this function
origPath = passedInOrigPath
if !allowRemote {
return fmt.Errorf("Source can't be a URL for %s", cmdName)
}
ci := copyInfo{}
ci.origPath = origPath
ci.hash = origPath // default to this but can change
ci.destPath = destPath
ci.decompress = false
*cInfos = append(*cInfos, &ci)
// Initiate the download
resp, err := httputils.Download(ci.origPath)
if err != nil {
return err
}
// Create a tmp dir
tmpDirName, err := ioutil.TempDir(b.contextPath, "docker-remote")
if err != nil {
return err
}
ci.tmpDir = tmpDirName
// Create a tmp file within our tmp dir
tmpFileName := filepath.Join(tmpDirName, "tmp")
tmpFile, err := os.OpenFile(tmpFileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if err != nil {
return err
}
// Download and dump result to tmp file
if _, err := io.Copy(tmpFile, progressreader.New(progressreader.Config{
In: resp.Body,
Out: b.OutOld,
Formatter: b.StreamFormatter,
Size: resp.ContentLength,
NewLines: true,
ID: "",
Action: "Downloading",
})); err != nil {
tmpFile.Close()
return err
}
fmt.Fprintf(b.OutStream, "\n")
tmpFile.Close()
// Set the mtime to the Last-Modified header value if present
// Otherwise just remove atime and mtime
times := make([]syscall.Timespec, 2)
lastMod := resp.Header.Get("Last-Modified")
if lastMod != "" {
mTime, err := http.ParseTime(lastMod)
// If we can't parse it then just let it default to 'zero'
// otherwise use the parsed time value
if err == nil {
times[1] = syscall.NsecToTimespec(mTime.UnixNano())
}
}
if err := system.UtimesNano(tmpFileName, times); err != nil {
return err
}
ci.origPath = filepath.Join(filepath.Base(tmpDirName), filepath.Base(tmpFileName))
//.........这里部分代码省略.........
开发者ID:JoeyZwicker,项目名称:docker,代码行数:101,代码来源:internals.go
示例15: runContextCommand
//.........这里部分代码省略.........
// Get the container
var (
containerId string = ""
container *daemon.Container
)
ps, ok := b.Hyperdaemon.PodList.GetStatus(podId)
if !ok {
return fmt.Errorf("Cannot find pod %s", podId)
}
for _, i := range ps.Containers {
containerId = i.Id
}
container, err = b.Daemon.Get(containerId)
if err != nil {
glog.Error(err.Error())
return err
}
/*
container, _, err := b.docker.Create(b.runConfig, nil)
if err != nil {
return err
}
defer b.docker.Unmount(container)
*/
b.tmpPods[podId] = struct{}{}
b.tmpContainers[container.ID] = struct{}{}
comment := fmt.Sprintf("%s %s in %s", cmdName, origPaths, dest)
// Twiddle the destination when its a relative path - meaning, make it
// relative to the WORKINGDIR
if !system.IsAbs(dest) {
hasSlash := strings.HasSuffix(dest, string(os.PathSeparator))
dest = filepath.Join(string(os.PathSeparator), filepath.FromSlash(b.runConfig.WorkingDir), dest)
// Make sure we preserve any trailing slash
if hasSlash {
dest += string(os.PathSeparator)
}
}
for _, info := range infos {
if err := b.docker.Copy(container, tempSrcDir, info.FileInfo, info.decompress); err != nil {
return err
}
if strings.HasSuffix(dest, string(os.PathSeparator)) == true {
fmt.Fprintf(copyshell, fmt.Sprintf("cp /tmp/src/%s %s\n", info.FileInfo.Name(), filepath.Join(dest, info.FileInfo.Name())))
} else {
fmt.Fprintf(copyshell, fmt.Sprintf("cp /tmp/src/%s %s\n", info.FileInfo.Name(), dest))
}
}
fmt.Fprintf(copyshell, "umount /tmp/src/\n")
fmt.Fprintf(copyshell, "umount /tmp/shell/\n")
fmt.Fprintf(copyshell, "rm -rf /tmp/shell/\n")
fmt.Fprintf(copyshell, "rm -rf /tmp/src/\n")
copyshell.Close()
// start or replace pod
vm, ok := b.Hyperdaemon.VmList[b.Name]
if !ok {
glog.Warningf("can not find VM(%s)", b.Name)
bo := &hypervisor.BootConfig{
CPU: 1,
开发者ID:m1911,项目名称:hyper,代码行数:67,代码来源:internals.go
示例16: evalSymlinksInScope
// evalSymlinksInScope will evaluate symlinks in `path` within a scope `root` and return
// a result guaranteed to be contained within the scope `root`, at the time of the call.
// Symlinks in `root` are not evaluated and left as-is.
// Errors encountered while attempting to evaluate symlinks in path will be returned.
// Non-existing paths are valid and do not constitute an error.
// `path` has to contain `root` as a prefix, or else an error will be returned.
// Trying to break out from `root` does not constitute an error.
//
// Example:
// If /foo/bar -> /outside,
// FollowSymlinkInScope("/foo/bar", "/foo") == "/foo/outside" instead of "/oustide"
//
// IMPORTANT: it is the caller's responsibility to call evalSymlinksInScope *after* relevant symlinks
// are created and not to create subsequently, additional symlinks that could potentially make a
// previously-safe path, unsafe. Example: if /foo/bar does not exist, evalSymlinksInScope("/foo/bar", "/foo")
// would return "/foo/bar". If one makes /foo/bar a symlink to /baz subsequently, then "/foo/bar" should
// no longer be considered safely contained in "/foo".
func evalSymlinksInScope(path, root string) (string, error) {
root = filepath.Clean(root)
if path == root {
return path, nil
}
if !strings.HasPrefix(path, root) {
return "", errors.New("evalSymlinksInScope: " + path + " is not in " + root)
}
const maxIter = 255
originalPath := path
// given root of "/a" and path of "/a/b/../../c" we want path to be "/b/../../c"
path = path[len(root):]
if root == string(filepath.Separator) {
path = string(filepath.Separator) + path
}
if !strings.HasPrefix(path, string(filepath.Separator)) {
return "", errors.New("evalSymlinksInScope: " + path + " is not in " + root)
}
path = filepath.Clean(path)
// consume path by taking each frontmost path element,
// expanding it if it's a symlink, and appending it to b
var b bytes.Buffer
// b here will always be considered to be the "current absolute path inside
// root" when we append paths to it, we also append a slash and use
// filepath.Clean after the loop to trim the trailing slash
for n := 0; path != ""; n++ {
if n > maxIter {
return "", errors.New("evalSymlinksInScope: too many links in " + originalPath)
}
// find next path component, p
i := strings.IndexRune(path, filepath.Separator)
var p string
if i == -1 {
p, path = path, ""
} else {
p, path = path[:i], path[i+1:]
}
if p == "" {
continue
}
// this takes a b.String() like "b/../" and a p like "c" and turns it
// into "/b/../c" which then gets filepath.Cleaned into "/c" and then
// root gets prepended and we Clean again (to remove any trailing slash
// if the first Clean gave us just "/")
cleanP := filepath.Clean(string(filepath.Separator) + b.String() + p)
if cleanP == string(filepath.Separator) {
// never Lstat "/" itself
b.Reset()
continue
}
fullP := filepath.Clean(root + cleanP)
fi, err := os.Lstat(fullP)
if os.IsNotExist(err) {
// if p does not exist, accept it
b.WriteString(p)
b.WriteRune(filepath.Separator)
continue
}
if err != nil {
return "", err
}
if fi.Mode()&os.ModeSymlink == 0 {
b.WriteString(p + string(filepath.Separator))
continue
}
// it's a symlink, put it at the front of path
dest, err := os.Readlink(fullP)
if err != nil {
return "", err
}
if system.IsAbs(dest) {
b.Reset()
}
path = dest + string(filepath.Separator) + path
}
// see note above on "fullP := ..." for why this is double-cleaned and
// what's happening here
//.........这里部分代码省略.........
开发者ID:francisbouvier,项目名称:docker,代码行数:101,代码来源:fs.go
示例17: runContextCommand
//.........这里部分代码省略.........
var fi builder.FileInfo
decompress := allowLocalDecompression
if urlutil.IsURL(orig) {
if !allowRemote {
return fmt.Errorf("Source can't be a URL for %s", cmdName)
}
fi, err = b.download(orig)
if err != nil {
return err
}
defer os.RemoveAll(filepath.Dir(fi.Path()))
decompress = false
infos = append(infos, copyInfo{fi, decompress})
continue
}
// not a URL
subInfos, err := b.calcCopyInfo(cmdName, orig, allowLocalDecompression, true)
if err != nil {
return err
}
infos = append(infos, subInfos...)
}
if len(infos) == 0 {
return fmt.Errorf("No source files were specified")
}
if len(infos) > 1 && !strings.HasSuffix(dest, string(os.PathSeparator)) {
return fmt.Errorf("When using %s with more than one source file, the destination must be a directory and end with a /", cmdName)
}
// For backwards compat, if there's just one info then use it as the
// cache look-up string, otherwise hash 'em all into one
var srcHash string
var origPaths string
if len(infos) == 1 {
fi := infos[0].FileInfo
origPaths = fi.Name()
if hfi, ok := fi.(builder.Hashed); ok {
srcHash = hfi.Hash()
}
} else {
var hashs []string
var origs []string
for _, info := range infos {
fi := info.FileInfo
origs = append(origs, fi.Name())
if hfi, ok := fi.(builder.Hashed); ok {
hashs = append(hashs, hfi.Hash())
}
}
hasher := sha256.New()
hasher.Write([]byte(strings.Join(hashs, ",")))
srcHash = "multi:" + hex.EncodeToString(hasher.Sum(nil))
origPaths = strings.Join(origs, " ")
}
cmd := b.runConfig.Cmd
if runtime.GOOS != "windows" {
b.runConfig.Cmd = strslice.New("/bin/sh", "-c", fmt.Sprintf("#(nop) %s %s in %s", cmdName, srcHash, dest))
} else {
b.runConfig.Cmd = strslice.New("cmd", "/S", "/C", fmt.Sprintf("REM (nop) %s %s in %s", cmdName, srcHash, dest))
}
defer func(cmd *strslice.StrSlice) { b.runConfig.Cmd = cmd }(cmd)
if hit, err := b.probeCache(); err != nil {
return err
} else if hit {
return nil
}
container, err := b.docker.ContainerCreate(types.ContainerCreateConfig{Config: b.runConfig})
if err != nil {
return err
}
b.tmpContainers[container.ID] = struct{}{}
comment := fmt.Sprintf("%s %s in %s", cmdName, origPaths, dest)
// Twiddle the destination when its a relative path - meaning, make it
// relative to the WORKINGDIR
if !system.IsAbs(dest) {
hasSlash := strings.HasSuffix(dest, string(os.PathSeparator))
dest = filepath.Join(string(os.PathSeparator), filepath.FromSlash(b.runConfig.WorkingDir), dest)
// Make sure we preserve any trailing slash
if hasSlash {
dest += string(os.PathSeparator)
}
}
for _, info := range infos {
if err := b.docker.BuilderCopy(container.ID, dest, info.FileInfo, info.decompress); err != nil {
return err
}
}
return b.commit(container.ID, cmd, comment)
}
开发者ID:Distrotech,项目名称:docker,代码行数:101,代码来源:internals.go
示例18: copyToContainer
func (cli *DockerCli) copyToContainer(srcPath, dstContainer, dstPath string) (err error) {
if srcPath != "-" {
// Get an absolute source path.
srcPath, err = resolveLocalPath(srcPath)
if err != nil {
return err
}
}
// In order to get the copy behavior right, we need to know information
// about both the source and destination. The API is a simple tar
// archive/extract API but we can use the stat info header about the
// destination to be more informed about exactly what the destination is.
// Prepare destination copy info by stat-ing the container path.
dstInfo := archive.CopyInfo{Path: dstPath}
dstStat, err := cli.statContainerPath(dstContainer, dstPath)
// If the destination is a symbolic link, we should evaluate it.
if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
linkTarget := dstStat.LinkTarget
if !system.IsAbs(linkTarget) {
// Join with the parent directory.
dstParent, _ := archive.SplitPathDirEntry(dstPath)
linkTarget = filepath.Join(dstParent, linkTarget)
}
dstInfo.Path = linkTarget
dstStat, err = cli.statContainerPath(dstContainer, linkTarget)
}
// Ignore any error and assume that the parent directory of the destination
// path exists, in which case the copy may still succeed. If there is any
// type of conflict (e.g., non-directory overwriting an existing directory
// or vice versia) the extraction will fail. If the destination simply did
// not exist, but the parent directory does, the extraction will still
// succeed.
if err == nil {
dstInfo.Exists, dstInfo.IsDir = true, dstStat.Mode.IsDir()
}
var (
content io.Reader
resolvedDstPath string
)
if srcPath == "-" {
// Use STDIN.
content = os.Stdin
resolvedDstPath = dstInfo.Path
if !dstInfo.IsDir {
return fmt.Errorf("destination %q must be a directory", fmt.Sprintf("%s:%s", dstContainer, dstPath))
}
} else {
// Prepare source copy info.
srcInfo, err := archive.CopyInfoSourcePath(srcPath)
if err != nil {
return err
}
srcArchive, err := archive.TarResource(srcInfo)
if err != nil {
return err
}
defer srcArchive.Close()
// With the stat info about the local source as well as the
// destination, we have enough information to know whether we need to
// alter the archive that we upload so that when the server extracts
// it to the specified directory in the container we get the disired
// copy behavior.
// See comments in the implementation of `archive.PrepareArchiveCopy`
// for exactly what goes into deciding how and whether the source
// archive needs to be altered for the correct copy behavior when it is
// extracted. This function also infers from the source and destination
// info which directory to extract to, which may be the parent of the
// destination that the user specified.
dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo)
if err != nil {
return err
}
defer preparedArchive.Close()
resolvedDstPath = dstDir
content = preparedArchive
}
query := make(url.Values, 2)
query.Set("path", filepath.ToSlash(resolvedDstPath)) // Normalize the paths used in the API.
// Do not allow for an existing directory to be overwritten by a non-directory and vice versa.
query.Set("noOverwriteDirNonDir", "true")
urlStr := fmt.Sprintf("/containers/%s/archive?%s", dstContainer, query.Encode())
response, err := cli.stream("PUT", urlStr, &streamOpts{in: content})
if err != nil {
return err
}
defer response.body.Close()
//.........这里部分代码省略.........
开发者ID:waterytowers,项目名称:global-hack-day-3,代码行数:101,代码来源:cp.go
示例19: runContextCommand
< |
请发表评论