2023-03-02 15:07:50 +00:00
|
|
|
package update
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
|
|
|
|
portainer "github.com/portainer/portainer/api"
|
|
|
|
"github.com/portainer/portainer/api/git"
|
|
|
|
gittypes "github.com/portainer/portainer/api/git/types"
|
|
|
|
"github.com/rs/zerolog/log"
|
|
|
|
)
|
|
|
|
|
|
|
|
// UpdateGitObject updates a git object based on its config
|
2023-04-03 06:19:17 +00:00
|
|
|
func UpdateGitObject(gitService portainer.GitService, objId string, gitConfig *gittypes.RepoConfig, forceUpdate bool, projectPath string) (bool, string, error) {
|
2023-03-02 15:07:50 +00:00
|
|
|
if gitConfig == nil {
|
|
|
|
return false, "", nil
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Debug().
|
|
|
|
Str("url", gitConfig.URL).
|
|
|
|
Str("ref", gitConfig.ReferenceName).
|
|
|
|
Str("object", objId).
|
|
|
|
Msg("the object has a git config, try to poll from git repository")
|
|
|
|
|
|
|
|
username, password, err := git.GetCredentials(gitConfig.Authentication)
|
|
|
|
if err != nil {
|
|
|
|
return false, "", errors.WithMessagef(err, "failed to get credentials for %v", objId)
|
|
|
|
}
|
|
|
|
|
2023-04-03 06:19:17 +00:00
|
|
|
newHash, err := gitService.LatestCommitID(gitConfig.URL, gitConfig.ReferenceName, username, password, gitConfig.TLSSkipVerify)
|
2023-03-02 15:07:50 +00:00
|
|
|
if err != nil {
|
|
|
|
return false, "", errors.WithMessagef(err, "failed to fetch latest commit id of %v", objId)
|
|
|
|
}
|
|
|
|
|
2023-03-13 16:18:28 +00:00
|
|
|
hashChanged := !strings.EqualFold(newHash, gitConfig.ConfigHash)
|
2023-04-03 06:19:17 +00:00
|
|
|
|
2023-03-02 15:07:50 +00:00
|
|
|
if !hashChanged && !forceUpdate {
|
|
|
|
log.Debug().
|
|
|
|
Str("hash", newHash).
|
|
|
|
Str("url", gitConfig.URL).
|
|
|
|
Str("ref", gitConfig.ReferenceName).
|
|
|
|
Str("object", objId).
|
|
|
|
Msg("git repo is up to date")
|
|
|
|
|
|
|
|
return false, newHash, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
cloneParams := &cloneRepositoryParameters{
|
2023-04-03 06:19:17 +00:00
|
|
|
url: gitConfig.URL,
|
|
|
|
ref: gitConfig.ReferenceName,
|
|
|
|
toDir: projectPath,
|
|
|
|
tlsSkipVerify: gitConfig.TLSSkipVerify,
|
2023-03-02 15:07:50 +00:00
|
|
|
}
|
|
|
|
if gitConfig.Authentication != nil {
|
|
|
|
cloneParams.auth = &gitAuth{
|
|
|
|
username: username,
|
|
|
|
password: password,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cloneGitRepository(gitService, cloneParams); err != nil {
|
|
|
|
return false, "", errors.WithMessagef(err, "failed to do a fresh clone of %v", objId)
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Debug().
|
|
|
|
Str("hash", newHash).
|
|
|
|
Str("url", gitConfig.URL).
|
|
|
|
Str("ref", gitConfig.ReferenceName).
|
|
|
|
Str("object", objId).
|
|
|
|
Msg("git repo cloned updated")
|
|
|
|
|
|
|
|
return true, newHash, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type cloneRepositoryParameters struct {
|
|
|
|
url string
|
|
|
|
ref string
|
|
|
|
toDir string
|
|
|
|
auth *gitAuth
|
2023-04-03 06:19:17 +00:00
|
|
|
// tlsSkipVerify skips SSL verification when cloning the Git repository
|
|
|
|
tlsSkipVerify bool `example:"false"`
|
2023-03-02 15:07:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type gitAuth struct {
|
|
|
|
username string
|
|
|
|
password string
|
|
|
|
}
|
|
|
|
|
|
|
|
func cloneGitRepository(gitService portainer.GitService, cloneParams *cloneRepositoryParameters) error {
|
|
|
|
if cloneParams.auth != nil {
|
2023-04-03 06:19:17 +00:00
|
|
|
return gitService.CloneRepository(cloneParams.toDir, cloneParams.url, cloneParams.ref, cloneParams.auth.username, cloneParams.auth.password, cloneParams.tlsSkipVerify)
|
2023-03-02 15:07:50 +00:00
|
|
|
}
|
|
|
|
|
2023-04-03 06:19:17 +00:00
|
|
|
return gitService.CloneRepository(cloneParams.toDir, cloneParams.url, cloneParams.ref, "", "", cloneParams.tlsSkipVerify)
|
2023-03-02 15:07:50 +00:00
|
|
|
}
|