From 440543f42712d3ecb53d2504475e581b0c4ac090 Mon Sep 17 00:00:00 2001 From: Alisdair McDiarmid Date: Thu, 23 Jul 2020 11:32:18 -0400 Subject: [PATCH] internal/providercache: Fix bug when symlink fails When installing a provider which is already cached, we attempt to create a symlink from the install directory targeting the cache. If symlinking fails due to missing OS/filesystem support, we instead want to copy the cached provider. The fallback code to do this would always fail, due to a missing target directory. This commit fixes that. I was unable to find a way to add automated tests around this, but I have manually verified the fix on Windows 8.1. --- internal/providercache/package_install.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/providercache/package_install.go b/internal/providercache/package_install.go index 62c3b8508..a070637e6 100644 --- a/internal/providercache/package_install.go +++ b/internal/providercache/package_install.go @@ -157,7 +157,7 @@ func installFromLocalDir(ctx context.Context, meta getproviders.PackageMeta, tar parentDir := filepath.Dir(absNew) err = os.MkdirAll(parentDir, 0755) - if err != nil && os.IsExist(err) { + if err != nil { return nil, fmt.Errorf("failed to create parent directories leading to %s: %s", targetDir, err) } @@ -168,7 +168,12 @@ func installFromLocalDir(ctx context.Context, meta getproviders.PackageMeta, tar } // If we get down here then symlinking failed and we need a deep copy - // instead. + // instead. To make a copy, we first need to create the target directory, + // which would otherwise be a symlink. + err = os.Mkdir(absNew, 0755) + if err != nil && os.IsExist(err) { + return nil, fmt.Errorf("failed to create directory %s: %s", absNew, err) + } err = copydir.CopyDir(absNew, absCurrent) if err != nil { return nil, fmt.Errorf("failed to either symlink or copy %s to %s: %s", absCurrent, absNew, err)