Skip to content

Commit

Permalink
Adds dev.odo.push.file attribute support for pushing only mentioned f…
Browse files Browse the repository at this point in the history
…iles
  • Loading branch information
mik-dass committed Apr 14, 2021
1 parent 6040118 commit 89d4226
Show file tree
Hide file tree
Showing 9 changed files with 1,739 additions and 12 deletions.
1 change: 1 addition & 0 deletions pkg/devfile/adapters/common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type SyncParameters struct {
CompInfo ComponentInfo
PodChanged bool
ComponentExists bool
Files map[string]string
}

// ComponentInfo is a struct that holds information about a component i.e.; pod name, container name, and source mount (if applicable)
Expand Down
14 changes: 14 additions & 0 deletions pkg/devfile/adapters/common/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package common

import (
"os"
"path/filepath"
"strings"

"k8s.io/klog"
Expand Down Expand Up @@ -241,3 +242,16 @@ func GetCommandsMap(commands []devfilev1.Command) map[string]devfilev1.Command {
}
return commandMap
}

func GetSyncFilesFromAttributes(commandsMap PushCommandsMap) map[string]string {
syncMap := make(map[string]string)
if value, ok := commandsMap[devfilev1.RunCommandGroupKind]; ok {
for key, value := range value.Attributes.Strings(nil) {
if strings.HasPrefix(key, "dev.odo.push.file:") {
localValue := strings.ReplaceAll(key, "dev.odo.push.file:", "")
syncMap[filepath.Clean(localValue)] = filepath.Clean(value)
}
}
}
return syncMap
}
2 changes: 2 additions & 0 deletions pkg/devfile/adapters/kubernetes/component/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,9 @@ func (a Adapter) Push(parameters common.PushParameters) (err error) {
CompInfo: compInfo,
ComponentExists: componentExists,
PodChanged: podChanged,
Files: common.GetSyncFilesFromAttributes(pushDevfileCommands),
}

execRequired, err := syncAdapter.SyncFiles(syncParams)
if err != nil {
return errors.Wrapf(err, "Failed to sync to component with name %s", a.ComponentName)
Expand Down
103 changes: 95 additions & 8 deletions pkg/sync/adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (a Adapter) SyncFiles(syncParameters common.SyncParameters) (isPushRequired
}

// Run the indexer and find the modified/added/deleted/renamed files
ret, err = util.RunIndexer(pushParameters.Path, absIgnoreRules)
ret, err = util.RunIndexWithRemote(pushParameters.Path, absIgnoreRules, map[string]string{})
s.End(true)

if err != nil {
Expand All @@ -138,12 +138,8 @@ func (a Adapter) SyncFiles(syncParameters common.SyncParameters) (isPushRequired
// and ignore the files on which the rules apply and filter them out
filesChangedFiltered, filesDeletedFiltered := util.FilterIgnores(ret.FilesChanged, ret.FilesDeleted, absIgnoreRules)

// Remove the relative file directory from the list of deleted files
// in order to make the changes correctly within the Kubernetes pod
deletedFiles, err = util.RemoveRelativePathFromFiles(filesDeletedFiltered, pushParameters.Path)
if err != nil {
return false, errors.Wrap(err, "unable to remove relative path from list of changed/deleted files")
}
deletedFiles = append(filesDeletedFiltered, ret.RemoteDeleted...)
deletedFiles = append(deletedFiles, ret.RemoteDeleted...)
klog.V(4).Infof("List of files to be deleted: +%v", deletedFiles)
changedFiles = filesChangedFiltered
klog.V(4).Infof("List of files changed: +%v", changedFiles)
Expand All @@ -153,12 +149,13 @@ func (a Adapter) SyncFiles(syncParameters common.SyncParameters) (isPushRequired
}
}

err = a.pushLocal(pushParameters.Path,
err = a.pushLocalWithRemote(pushParameters.Path,
changedFiles,
deletedFiles,
isForcePush,
util.GetAbsGlobExps(pushParameters.Path, pushParameters.IgnoredFiles),
syncParameters.CompInfo,
ret,
)
if err != nil {
return false, errors.Wrapf(err, "failed to sync to component with name %s", a.ComponentName)
Expand All @@ -173,6 +170,37 @@ func (a Adapter) SyncFiles(syncParameters common.SyncParameters) (isPushRequired
return true, nil
}

// TODO remove later if not required
func (a Adapter) SyncFileWithRemote(syncParameters common.SyncParameters) (isPushRequired bool, err error) {
ret, err := util.RunIndexWithRemote(syncParameters.PushParams.Path, syncParameters.PushParams.IgnoredFiles, syncParameters.Files)
if err != nil {
return false, err
}

if len(ret.FilesChanged) == 0 && len(ret.FilesDeleted) == 0 {
return false, nil
}

ret.FilesDeleted = append(ret.FilesDeleted, ret.RemoteDeleted...)

err = a.pushLocalWithRemote(syncParameters.PushParams.Path,
ret.FilesChanged,
ret.FilesDeleted,
false,
util.GetAbsGlobExps(syncParameters.PushParams.Path, syncParameters.PushParams.IgnoredFiles),
syncParameters.CompInfo,
ret,
)
if err != nil {
return false, errors.Wrapf(err, "failed to sync to component with name %s", a.ComponentName)
}
err = util.WriteFile(ret.NewFileMap, ret.ResolvedPath)
if err != nil {
return false, errors.Wrapf(err, "Failed to write file")
}
return true, nil
}

// pushLocal syncs source code from the user's disk to the component
func (a Adapter) pushLocal(path string, files []string, delFiles []string, isForcePush bool, globExps []string, compInfo common.ComponentInfo) error {
klog.V(4).Infof("Push: componentName: %s, path: %s, files: %s, delFiles: %s, isForcePush: %+v", a.ComponentName, path, files, delFiles, isForcePush)
Expand Down Expand Up @@ -232,6 +260,65 @@ func (a Adapter) pushLocal(path string, files []string, delFiles []string, isFor
return nil
}

// pushLocal syncs source code from the user's disk to the component
func (a Adapter) pushLocalWithRemote(path string, files []string, delFiles []string, isForcePush bool, globExps []string, compInfo common.ComponentInfo, ret util.IndexerRet) error {
klog.V(4).Infof("Push: componentName: %s, path: %s, files: %s, delFiles: %s, isForcePush: %+v", a.ComponentName, path, files, delFiles, isForcePush)

// Edge case: check to see that the path is NOT empty.
emptyDir, err := util.IsEmpty(path)
if err != nil {
return errors.Wrapf(err, "unable to check directory: %s", path)
} else if emptyDir {
return errors.New(fmt.Sprintf("directory/file %s is empty", path))
}

// Sync the files to the pod
s := log.Spinner("Syncing files to the component")
defer s.End(false)

syncFolder := compInfo.SyncFolder

if syncFolder != generator.DevfileSourceVolumeMount {
// Need to make sure the folder already exists on the component or else sync will fail
klog.V(4).Infof("Creating %s on the remote container if it doesn't already exist", syncFolder)
cmdArr := getCmdToCreateSyncFolder(syncFolder)

err = common.ExecuteCommand(a.Client, compInfo, cmdArr, false, nil, nil)
if err != nil {
return err
}
}
// If there were any files deleted locally, delete them remotely too.
if len(delFiles) > 0 {
cmdArr := getCmdToDeleteFiles(delFiles, syncFolder)

err = common.ExecuteCommand(a.Client, compInfo, cmdArr, false, nil, nil)
if err != nil {
return err
}
}

if !isForcePush {
if len(files) == 0 && len(delFiles) == 0 {
// nothing to push
s.End(true)
return nil
}
}

if isForcePush || len(files) > 0 {
klog.V(4).Infof("Copying files %s to pod", strings.Join(files, " "))
err = CopyFileWithRemote(a.Client, path, compInfo, syncFolder, files, globExps, ret)
if err != nil {
s.End(false)
return errors.Wrap(err, "unable push files to pod")
}
}
s.End(true)

return nil
}

// updateIndexWithWatchChanges uses the pushParameters.WatchDeletedFiles and pushParamters.WatchFiles to update
// the existing index file; the index file is required to exist when this function is called.
func updateIndexWithWatchChanges(pushParameters common.PushParameters) error {
Expand Down
5 changes: 5 additions & 0 deletions pkg/sync/adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ func TestSyncFiles(t *testing.T) {
t.Errorf("TestSyncFiles error: error creating temporary directory for the indexer: %v", err)
}

_, err = os.Create(filepath.Join(directory, "red.js"))
if err != nil {
t.Errorf("TestSyncFiles error: error creating temporary file for the indexer: %v", err)
}

ctrl := gomock.NewController(t)

// Assert that Bar() is invoked.
Expand Down
Loading

0 comments on commit 89d4226

Please sign in to comment.