Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support remote sync policy #146

Merged
merged 3 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Check the update of %s and its commands.
Timeout: updateFlags.Timeout,
EnableCI: enableCI,
PackageLockFile: packageLockFile,
SyncPolicy: "always", // TODO: use constant instead of string
}
cmdUpdater.CheckUpdateAsync()
err := cmdUpdater.Update()
Expand Down
3 changes: 2 additions & 1 deletion internal/backend/package-source.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func NewManagedSource(name, repoDir, remoteBaseURL string, syncPolicy string) *P
RemoteBaseURL: remoteBaseURL,
RemoteRegistryURL: fmt.Sprintf("%s/index.json", remoteBaseURL),
IsManaged: true,
SyncPolicy: SYNC_POLICY_ALWAYS,
SyncPolicy: syncPolicy,
}
}

Expand All @@ -71,6 +71,7 @@ func (src *PackageSource) InitUpdater(user *user.User, timeout time.Duration, en
PackageLockFile: lockFile,
VerifyChecksum: verifyChecksum,
VerifySignature: verifySignature,
SyncPolicy: src.SyncPolicy,
}
return src.Updater
}
Expand Down
80 changes: 80 additions & 0 deletions internal/updater/cmd-updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package updater

import (
"encoding/json"
"errors"
"fmt"
"os"
"path"
"sync"
"time"

Expand Down Expand Up @@ -34,6 +37,7 @@ type CmdUpdater struct {
PackageLockFile string
VerifyChecksum bool
VerifySignature bool
SyncPolicy string
}

func (u *CmdUpdater) CheckUpdateAsync() {
Expand All @@ -57,6 +61,16 @@ func (u *CmdUpdater) Update() error {

errPool := []error{}

// check if we are following the syncPolicy
// TODO: for now we check the sync policy to block update during the update phase,
// This is no optimal, as we still check remote repository in check update async.
// We should move the sync policy check to the check update async, which will save
// time to check the remote repo in order to make the check done in the timeout period.
if err := u.reachSyncSchedule(); err != nil {
log.Info(err.Error())
return err
}

remoteRepo, err := u.getRemoteRepository()
if err != nil {
// TODO: handle error here
Expand Down Expand Up @@ -138,6 +152,12 @@ func (u *CmdUpdater) Update() error {
}

if len(errPool) == 0 {
// update the sync timestamp
err := u.UpdateSyncTimestamp()
if err != nil {
log.Error(err)
}

fmt.Println("Update done! Enjoy coding!")
return nil
} else {
Expand Down Expand Up @@ -265,3 +285,63 @@ func (u *CmdUpdater) LoadLockedPackages(lockFile string) (map[string]string, err
}
return lockedPkgs, nil
}

// check sync policy
func (u *CmdUpdater) reachSyncSchedule() error {
// check if we are following the syncPolicy
if u.SyncPolicy == "never" {
return errors.New(fmt.Sprintf("Remote '%s': Sync policy is set to never, no update will be performed", u.LocalRepo.Name()))
}
if u.SyncPolicy == "always" {
return nil
}
// now load the sync timestamp
localRepoFolder, err := u.LocalRepo.RepositoryFolder()
if err != nil {
return err
}
data, err := os.ReadFile(path.Join(localRepoFolder, "sync.timestamp"))
if err != nil {
// error read the file, we assume the sync time is passed
return nil
}
syncTime, err := time.Parse(time.RFC3339, string(data))
if err != nil {
return err
}

// now check if we passed the sync time
if time.Now().Before(syncTime) {
return errors.New(fmt.Sprintf("Remote '%s': Not yet reach the sync time", u.LocalRepo.Name()))
}

return nil
}

func (u *CmdUpdater) UpdateSyncTimestamp() error {
localRepoFolder, err := u.LocalRepo.RepositoryFolder()
if err != nil {
return err
}

var delay time.Duration = 24
switch u.SyncPolicy {
case "always":
return errors.New(fmt.Sprintf("Remote '%s': Sync policy is set to always, no need to update the sync timestamp", u.LocalRepo.Name()))
case "never":
return errors.New(fmt.Sprintf("Remote '%s': Sync policy is set to never, no need to update the sync timestamp", u.LocalRepo.Name()))
case "hourly":
delay = 1
case "daily":
delay = 24
case "weekly":
delay = 24 * 7
case "monthly":
delay = 24 * 30
}

err = os.WriteFile(path.Join(localRepoFolder, "sync.timestamp"), []byte(time.Now().Add(time.Hour*delay).Format(time.RFC3339)), 0644)

log.Infof("Remote '%s': Sync timestamp updated to %s", u.LocalRepo.Name(), time.Now().Add(time.Hour*delay).Format(time.RFC3339))
return err
}
51 changes: 51 additions & 0 deletions test/integration/test-extra-remote-cmd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,57 @@ else
exit 1
fi

echo "> test sync policy"

echo "* should NOT have the sync.timestamp file"
RESULT=$(ls $CL_HOME/extra1 | grep -q "sync.timestamp")
if [ $? -eq 0 ]; then
echo "KO - should NOT have the sync.timestamp file"
exit 1
else
echo "OK"
fi
# change the extra remote's sync policy to 'weekly'
sed -i -e 's/always/weekly/g' $CL_HOME/config.json

# now remove one package from local repository and run command launcher to sync
$CL_PATH config command_update_enabled true
rm -rf $CL_HOME/extra1/command-launcher-demo

echo "* should install new package"
RESULT=$($CL_PATH)
echo "$RESULT" | grep -q "Update done! Enjoy coding!"
if [ $? -eq 0 ]; then
echo "OK"
else
echo "KO - should install new package"
exit 1
fi

echo "* should have the sync.timestamp file after sync"
RESULT=$(ls $CL_HOME/extra1 | grep -q "sync.timestamp")
if [ $? -eq 0 ]; then
echo "OK"
else
echo "KO - should NOT have the sync.timestamp file"
exit 1
fi

# now remove the package again, should not install the package again
rm -rf $CL_HOME/extra1/command-launcher-demo
echo "* should NOT install new package"
RESULT=$($CL_PATH)
echo "$RESULT" | grep -q "Update done! Enjoy coding!"
if [ $? -eq 0 ]; then
echo "KO - should NOT install new package"
exit 1
else
echo "OK"
fi

# reset the config
$CL_PATH config command_update_enabled false

echo "> test delete extra remote registry"
RESULT=$($CL_PATH remote delete extra1)
RESULT=$($CL_PATH remote list)
Expand Down
Loading