in cli/azd/pkg/containerregistry/pack_source.go [33:166]
func PackRemoteBuildSource(ctx context.Context, root string, dockerfile string) (string, string, error) {
var ignores []string
// Like docker, we allow the use of a .dockerignore file to control what is included in the build context.
candidates := []string{dockerfile + ".dockerignore", filepath.Join(root, ".dockerignore")}
for _, candidate := range candidates {
f, err := os.Open(candidate)
if err == nil {
defer f.Close()
i, err := ignorefile.ReadAll(f)
if err != nil {
return "", "", err
}
ignores = i
break
} else if !errors.Is(err, os.ErrNotExist) {
return "", "", err
}
}
contextArchive, err := os.CreateTemp("", "azd-docker-context*.tar.gz")
if err != nil {
return "", "", err
}
defer contextArchive.Close()
gw := gzip.NewWriter(contextArchive)
defer gw.Close()
tw := tar.NewWriter(gw)
defer tw.Close()
var dockerfileArchivePath string
err = filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() {
if filepath.Base(path) == ".git" {
return filepath.SkipDir
}
return nil
}
archivePath := filepath.ToSlash(path[len(root)+1:])
ignore, err := patternmatcher.MatchesOrParentMatches(archivePath, ignores)
if err != nil {
return err
}
if !ignore {
info, err := d.Info()
if err != nil {
return err
}
hdr, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return err
}
hdr.Name = archivePath
if err := tw.WriteHeader(hdr); err != nil {
return err
}
err = func() error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(tw, f)
if err != nil {
return err
}
return nil
}()
if err != nil {
return err
}
if path == dockerfile {
dockerfileArchivePath = archivePath
}
}
return nil
})
if err != nil {
return contextArchive.Name(), dockerfileArchivePath, err
}
// If we didn't see the dockerfile in the context, add it to the archive at the root with a unique name.
if dockerfileArchivePath == "" {
f, err := os.Open(dockerfile)
if err != nil {
return contextArchive.Name(), dockerfileArchivePath, err
}
defer f.Close()
info, err := f.Stat()
if err != nil {
return contextArchive.Name(), dockerfileArchivePath, err
}
hdr, err := tar.FileInfoHeader(info, info.Name())
if err != nil {
return contextArchive.Name(), dockerfileArchivePath, err
}
uniqueName := uuid.NewString() + "_" + filepath.Base(dockerfile)
hdr.Name = uniqueName
if err := tw.WriteHeader(hdr); err != nil {
return contextArchive.Name(), dockerfileArchivePath, err
}
_, err = io.Copy(tw, f)
if err != nil {
return contextArchive.Name(), dockerfileArchivePath, err
}
dockerfileArchivePath = uniqueName
}
return contextArchive.Name(), dockerfileArchivePath, err
}