Apply commit label on resources created/updated when '--commitlabel' flag is passed (#2279)
This commit is contained in:
@@ -128,7 +128,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
|
||||
if toSpec {
|
||||
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
@@ -169,7 +169,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
|
||||
if toSpec {
|
||||
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func (opts *CreateSubCommand) run(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specDir = util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
@@ -186,7 +186,7 @@ func CreatePackage(input cli.Input, client client.Interface, pkgName string, pkg
|
||||
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
// if a package with the same spec exists, don't create a new spec file
|
||||
fr, err := spec.ReadSpecs(util.GetSpecDir(input), util.GetSpecIgnore(input))
|
||||
fr, err := spec.ReadSpecs(util.GetSpecDir(input), util.GetSpecIgnore(input), false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ func CreateArchive(client client.Interface, input cli.Input, includeFiles []stri
|
||||
} else if input.Bool(flagkey.SpecSave) {
|
||||
// check if this AUS exists in the specs; if so, don't create a new one
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func (opts *ApplySubCommand) do(input cli.Input) error {
|
||||
func (opts *ApplySubCommand) run(input cli.Input) error {
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
|
||||
applyCommitLabel := input.Bool(flagkey.SpecApplyCommitLabel)
|
||||
deleteResources := input.Bool(flagkey.SpecDelete)
|
||||
watchResources := input.Bool(flagkey.SpecWatch)
|
||||
waitForBuild := input.Bool(flagkey.SpecWait)
|
||||
@@ -112,7 +112,7 @@ func (opts *ApplySubCommand) run(input cli.Input) error {
|
||||
|
||||
for {
|
||||
// read all specs
|
||||
fr, err := ReadSpecs(specDir, specIgnore)
|
||||
fr, err := ReadSpecs(specDir, specIgnore, applyCommitLabel)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
@@ -626,7 +626,7 @@ func applyPackages(fclient client.Interface, fr *FissionResources, delete bool)
|
||||
keep = true
|
||||
}
|
||||
|
||||
if keep && existingObj.Status.BuildStatus == fv1.BuildStatusSucceeded {
|
||||
if keep && isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && existingObj.Status.BuildStatus == fv1.BuildStatusSucceeded {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -726,7 +726,7 @@ func applyFunctions(fclient client.Interface, fr *FissionResources, delete bool)
|
||||
existingObj, ok := existent[mapKey(&o.ObjectMeta)]
|
||||
if ok {
|
||||
// ok, a resource with the same name exists, is it the same?
|
||||
if reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
if isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -809,7 +809,7 @@ func applyEnvironments(fclient client.Interface, fr *FissionResources, delete bo
|
||||
existingObj, ok := existent[mapKey(&o.ObjectMeta)]
|
||||
if ok {
|
||||
// ok, a resource with the same name exists, is it the same?
|
||||
if reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
if isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -892,7 +892,7 @@ func applyHTTPTriggers(fclient client.Interface, fr *FissionResources, delete bo
|
||||
existingObj, ok := existent[mapKey(&o.ObjectMeta)]
|
||||
if ok {
|
||||
// ok, a resource with the same name exists, is it the same?
|
||||
if reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
if isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -975,7 +975,7 @@ func applyKubernetesWatchTriggers(fclient client.Interface, fr *FissionResources
|
||||
existingObj, ok := existent[mapKey(&o.ObjectMeta)]
|
||||
if ok {
|
||||
// ok, a resource with the same name exists, is it the same?
|
||||
if reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
if isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -1058,7 +1058,7 @@ func applyTimeTriggers(fclient client.Interface, fr *FissionResources, delete bo
|
||||
existingObj, ok := existent[mapKey(&o.ObjectMeta)]
|
||||
if ok {
|
||||
// ok, a resource with the same name exists, is it the same?
|
||||
if reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
if isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -1141,7 +1141,7 @@ func applyMessageQueueTriggers(fclient client.Interface, fr *FissionResources, d
|
||||
existingObj, ok := existent[mapKey(&o.ObjectMeta)]
|
||||
if ok {
|
||||
// ok, a resource with the same name exists, is it the same?
|
||||
if reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
if isObjectMetaEqual(existingObj.ObjectMeta, o.ObjectMeta) && reflect.DeepEqual(existingObj.Spec, o.Spec) {
|
||||
// nothing to do on the server
|
||||
metadataMap[mapKey(&o.ObjectMeta)] = existingObj.ObjectMeta
|
||||
} else {
|
||||
@@ -1184,3 +1184,27 @@ func applyMessageQueueTriggers(fclient client.Interface, fr *FissionResources, d
|
||||
|
||||
return metadataMap, &ras, nil
|
||||
}
|
||||
|
||||
func isObjectMetaEqual(existingObj, newObj metav1.ObjectMeta) bool {
|
||||
|
||||
if !reflect.DeepEqual(existingObj.Labels, newObj.Labels) {
|
||||
return false
|
||||
}
|
||||
|
||||
existingAnnotations := make(map[string]string)
|
||||
newAnnotations := make(map[string]string)
|
||||
|
||||
for existingObjKey, existingObjVal := range existingObj.Annotations {
|
||||
if existingObjKey != FISSION_DEPLOYMENT_NAME_KEY && existingObjKey != FISSION_DEPLOYMENT_UID_KEY {
|
||||
existingAnnotations[existingObjKey] = existingObjVal
|
||||
}
|
||||
}
|
||||
|
||||
for newObjKey, newObjVal := range newObj.Annotations {
|
||||
if newObjKey != FISSION_DEPLOYMENT_NAME_KEY && newObjKey != FISSION_DEPLOYMENT_UID_KEY {
|
||||
newAnnotations[newObjKey] = newObjVal
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.DeepEqual(existingAnnotations, newAnnotations)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func Commands() *cobra.Command {
|
||||
RunE: wrapper.Wrapper(Apply),
|
||||
}
|
||||
wrapper.SetFlags(applyCmd, flag.FlagSet{
|
||||
Optional: []flag.Flag{flag.SpecDir, flag.SpecIgnore, flag.SpecDelete, flag.SpecWait, flag.SpecWatch, flag.SpecValidation},
|
||||
Optional: []flag.Flag{flag.SpecDir, flag.SpecIgnore, flag.SpecDelete, flag.SpecWait, flag.SpecWatch, flag.SpecValidation, flag.SpecApplyCommitLabel},
|
||||
})
|
||||
|
||||
destroyCmd := &cobra.Command{
|
||||
|
||||
@@ -43,7 +43,7 @@ func (opts *DestroySubCommand) run(input cli.Input) error {
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
|
||||
// read everything
|
||||
fr, err := ReadSpecs(specDir, specIgnore)
|
||||
fr, err := ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (opts *ListSubCommand) run(input cli.Input) error {
|
||||
// get specdir, specignore and read the deployID
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := ReadSpecs(specDir, specIgnore)
|
||||
fr, err := ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func SpecSave(resource interface{}, specFile string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fr, err := ReadSpecs(specDir, util.SPEC_IGNORE_FILE)
|
||||
fr, err := ReadSpecs(specDir, util.SPEC_IGNORE_FILE, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
@@ -526,9 +526,19 @@ func (fr *FissionResources) trackSourceMap(kind string, newobj *metav1.ObjectMet
|
||||
return nil
|
||||
}
|
||||
|
||||
// Apply commit label to the object metadata
|
||||
func applyCommitLabel(commitLabelVal string, m *metav1.ObjectMeta) {
|
||||
if len(commitLabelVal) != 0 {
|
||||
if m.Labels == nil {
|
||||
m.Labels = make(map[string]string)
|
||||
}
|
||||
m.Labels[util.COMMIT_LABEL] = commitLabelVal
|
||||
}
|
||||
}
|
||||
|
||||
// ParseYaml takes one yaml document, figures out its type, parses it, and puts it in
|
||||
// the right list in the given fission resources set.
|
||||
func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
func (fr *FissionResources) ParseYaml(b []byte, loc *Location, commitLabelVal string) error {
|
||||
var m *metav1.ObjectMeta
|
||||
|
||||
// Figure out the object type by unmarshaling into the TypeMeta struct; then
|
||||
@@ -547,6 +557,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.Packages = append(fr.Packages, v)
|
||||
case "Function":
|
||||
var v fv1.Function
|
||||
@@ -555,6 +566,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.Functions = append(fr.Functions, v)
|
||||
case "Environment":
|
||||
var v fv1.Environment
|
||||
@@ -563,6 +575,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.Environments = append(fr.Environments, v)
|
||||
case "HTTPTrigger":
|
||||
var v fv1.HTTPTrigger
|
||||
@@ -570,8 +583,8 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.HttpTriggers = append(fr.HttpTriggers, v)
|
||||
case "KubernetesWatchTrigger":
|
||||
var v fv1.KubernetesWatchTrigger
|
||||
@@ -580,6 +593,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.KubernetesWatchTriggers = append(fr.KubernetesWatchTriggers, v)
|
||||
case "TimeTrigger":
|
||||
var v fv1.TimeTrigger
|
||||
@@ -588,6 +602,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.TimeTriggers = append(fr.TimeTriggers, v)
|
||||
case "MessageQueueTrigger":
|
||||
var v fv1.MessageQueueTrigger
|
||||
@@ -596,6 +611,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
m = &v.ObjectMeta
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.MessageQueueTriggers = append(fr.MessageQueueTriggers, v)
|
||||
|
||||
// The following are not CRDs
|
||||
@@ -606,6 +622,7 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
|
||||
fr.DeploymentConfig = v
|
||||
case "ArchiveUploadSpec":
|
||||
var v types.ArchiveUploadSpec
|
||||
@@ -613,10 +630,12 @@ func (fr *FissionResources) ParseYaml(b []byte, loc *Location) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to parse %v in %v", tm.Kind, loc))
|
||||
}
|
||||
|
||||
m = &metav1.ObjectMeta{
|
||||
Name: v.Name,
|
||||
Namespace: "",
|
||||
}
|
||||
applyCommitLabel(commitLabelVal, m)
|
||||
fr.ArchiveUploadSpecs = append(fr.ArchiveUploadSpecs, v)
|
||||
default:
|
||||
// no need to error out just because there's some extra files around;
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/fission/fission/pkg/fission-cli/console"
|
||||
"github.com/fission/fission/pkg/fission-cli/util"
|
||||
"github.com/fission/fission/pkg/utils"
|
||||
"github.com/fission/fission/pkg/utils/gitrepo"
|
||||
)
|
||||
|
||||
type ValidateSubCommand struct {
|
||||
@@ -54,7 +55,7 @@ func (opts *ValidateSubCommand) run(input cli.Input) error {
|
||||
// this will error on parse errors and on duplicates
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := ReadSpecs(specDir, specIgnore)
|
||||
fr, err := ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error reading specs")
|
||||
}
|
||||
@@ -198,7 +199,7 @@ func isResourceConflicts(deployUID string, specObj fv1.MetadataAccessor, cluster
|
||||
|
||||
// ReadSpecs reads all specs in the specified directory and returns a parsed set of
|
||||
// fission resources.
|
||||
func ReadSpecs(specDir, specIgnore string) (*FissionResources, error) {
|
||||
func ReadSpecs(specDir, specIgnore string, applyCommitLabel bool) (*FissionResources, error) {
|
||||
|
||||
// make sure spec directory exists before continue
|
||||
if _, err := os.Stat(specDir); os.IsNotExist(err) {
|
||||
@@ -225,6 +226,21 @@ func ReadSpecs(specDir, specIgnore string) (*FissionResources, error) {
|
||||
},
|
||||
}
|
||||
|
||||
// get absolute path of specdir
|
||||
if !filepath.IsAbs(specDir) {
|
||||
cwd, err := filepath.Abs("./")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
specDir = filepath.Join(cwd, specDir)
|
||||
}
|
||||
|
||||
var gr *gitrepo.GitRepo
|
||||
// check if applyCommitLabel flag is true
|
||||
if applyCommitLabel {
|
||||
gr = gitrepo.NewGitRepo(specDir)
|
||||
}
|
||||
|
||||
var result *multierror.Error
|
||||
|
||||
// Users can organize the specdir into subdirs if they want to.
|
||||
@@ -239,16 +255,24 @@ func ReadSpecs(specDir, specIgnore string) (*FissionResources, error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// check if file matches any path in .specignore file
|
||||
if ignoreParser.MatchesPath(path) {
|
||||
return nil
|
||||
}
|
||||
|
||||
var fileCommitLabelVal string
|
||||
// check if applyCommitLabel is true and specdir is tracked by git repo
|
||||
if applyCommitLabel {
|
||||
fileCommitLabelVal, _ = gr.GetFileCommitLabel(path)
|
||||
}
|
||||
|
||||
// read
|
||||
b, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
result = multierror.Append(result, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// handle the case where there are multiple YAML docs per file. go-yaml
|
||||
// doesn't support this directly, yet.
|
||||
docs := bytes.Split(b, []byte("\n---"))
|
||||
@@ -260,7 +284,7 @@ func ReadSpecs(specDir, specIgnore string) (*FissionResources, error) {
|
||||
err = fr.ParseYaml(d, &Location{
|
||||
Path: path,
|
||||
Line: lines,
|
||||
})
|
||||
}, fileCommitLabelVal)
|
||||
if err != nil {
|
||||
// collect all errors so user can fix them all
|
||||
result = multierror.Append(result, err)
|
||||
|
||||
@@ -78,7 +78,7 @@ func (opts *CreateSubCommand) complete(input cli.Input) error {
|
||||
if input.Bool(flagkey.SpecSave) {
|
||||
specDir := util.GetSpecDir(input)
|
||||
specIgnore := util.GetSpecIgnore(input)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore)
|
||||
fr, err := spec.ReadSpecs(specDir, specIgnore, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("error reading spec in '%v'", specDir))
|
||||
}
|
||||
|
||||
@@ -193,16 +193,17 @@ var (
|
||||
PkgSrcChecksum = Flag{Type: String, Name: flagkey.PkgSrcChecksum, Usage: "SHA256 checksum of source archive when providing URL"}
|
||||
PkgInsecure = Flag{Type: Bool, Name: flagkey.PkgInsecure, Usage: "Skip generating SHA256 checksum for file integrity validation"}
|
||||
|
||||
SpecSave = Flag{Type: Bool, Name: flagkey.SpecSave, Usage: "Save to the spec directory instead of creating on cluster"}
|
||||
SpecDir = Flag{Type: String, Name: flagkey.SpecDir, Usage: "Directory to store specs, defaults to ./specs"}
|
||||
SpecName = Flag{Type: String, Name: flagkey.SpecName, Usage: "Name for the app, applied to resources as a Kubernetes annotation"}
|
||||
SpecDeployID = Flag{Type: String, Name: flagkey.SpecDeployID, Aliases: []string{"id"}, Usage: "Deployment ID for the spec deployment config"}
|
||||
SpecWait = Flag{Type: Bool, Name: flagkey.SpecWait, Usage: "Wait for package builds"}
|
||||
SpecWatch = Flag{Type: Bool, Name: flagkey.SpecWatch, Usage: "Watch local files for change, and re-apply specs as necessary"}
|
||||
SpecDelete = Flag{Type: Bool, Name: flagkey.SpecDelete, Usage: "Allow apply to delete resources that no longer exist in the specification"}
|
||||
SpecDry = Flag{Type: Bool, Name: flagkey.SpecDry, Usage: "View the generated specs"}
|
||||
SpecValidation = Flag{Type: String, Name: flagkey.SpecValidate, Usage: "Turns server side validations of Fission objects on/off"}
|
||||
SpecIgnore = Flag{Type: String, Name: flagkey.SpecIgnore, Usage: fmt.Sprintf("File containing specs to be ignored inside --specdir, defaults to %v", util.SPEC_IGNORE_FILE)}
|
||||
SpecSave = Flag{Type: Bool, Name: flagkey.SpecSave, Usage: "Save to the spec directory instead of creating on cluster"}
|
||||
SpecDir = Flag{Type: String, Name: flagkey.SpecDir, Usage: "Directory to store specs, defaults to ./specs"}
|
||||
SpecName = Flag{Type: String, Name: flagkey.SpecName, Usage: "Name for the app, applied to resources as a Kubernetes annotation"}
|
||||
SpecDeployID = Flag{Type: String, Name: flagkey.SpecDeployID, Aliases: []string{"id"}, Usage: "Deployment ID for the spec deployment config"}
|
||||
SpecWait = Flag{Type: Bool, Name: flagkey.SpecWait, Usage: "Wait for package builds"}
|
||||
SpecWatch = Flag{Type: Bool, Name: flagkey.SpecWatch, Usage: "Watch local files for change, and re-apply specs as necessary"}
|
||||
SpecDelete = Flag{Type: Bool, Name: flagkey.SpecDelete, Usage: "Allow apply to delete resources that no longer exist in the specification"}
|
||||
SpecDry = Flag{Type: Bool, Name: flagkey.SpecDry, Usage: "View the generated specs"}
|
||||
SpecValidation = Flag{Type: String, Name: flagkey.SpecValidate, Usage: "Turns server side validations of Fission objects on/off"}
|
||||
SpecIgnore = Flag{Type: String, Name: flagkey.SpecIgnore, Usage: fmt.Sprintf("File containing specs to be ingored inside --specdir, defaults to %v", util.SPEC_IGNORE_FILE)}
|
||||
SpecApplyCommitLabel = Flag{Type: Bool, Name: flagkey.SpecApplyCommitLabel, Usage: "Apply commit label to the resources"}
|
||||
|
||||
SupportOutput = Flag{Type: String, Name: flagkey.SupportOutput, Short: "o", Usage: "Output directory to save dump archive/files", DefaultValue: flagkey.DefaultSpecOutputDir}
|
||||
SupportNoZip = Flag{Type: Bool, Name: flagkey.SupportNoZip, Usage: "Save dump information into multiple files instead of single zip file"}
|
||||
|
||||
@@ -144,16 +144,17 @@ const (
|
||||
PkgStatus = "status"
|
||||
PkgOrphan = "orphan"
|
||||
|
||||
SpecSave = "spec"
|
||||
SpecDir = "specdir"
|
||||
SpecName = resourceName
|
||||
SpecDeployID = "deployid"
|
||||
SpecWait = "wait"
|
||||
SpecWatch = "watch"
|
||||
SpecDelete = "delete"
|
||||
SpecDry = "dry"
|
||||
SpecValidate = "validation"
|
||||
SpecIgnore = "specignore"
|
||||
SpecSave = "spec"
|
||||
SpecDir = "specdir"
|
||||
SpecName = resourceName
|
||||
SpecDeployID = "deployid"
|
||||
SpecWait = "wait"
|
||||
SpecWatch = "watch"
|
||||
SpecDelete = "delete"
|
||||
SpecDry = "dry"
|
||||
SpecValidate = "validation"
|
||||
SpecIgnore = "specignore"
|
||||
SpecApplyCommitLabel = "commitlabel"
|
||||
|
||||
SupportOutput = Output
|
||||
SupportNoZip = "nozip"
|
||||
|
||||
@@ -19,4 +19,5 @@ package util
|
||||
// fission-cli options
|
||||
const (
|
||||
SPEC_IGNORE_FILE = ".specignore"
|
||||
COMMIT_LABEL = "commit"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
Copyright 2022 The Fission Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package gitrepo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type GitRepo struct {
|
||||
setupDone bool
|
||||
isGitRepo bool
|
||||
repo *git.Repository
|
||||
status git.Status
|
||||
dirPath string
|
||||
gitRepoRootPath string // absolute path of the root of the git repository
|
||||
commitID string // commit ID the HEAD of the repository is poitning to
|
||||
}
|
||||
|
||||
// NewGitRepo creates new GitRepo struct
|
||||
// checks if the given directory path is part of git repository
|
||||
// accordingly updates the fields of GitRepo struct and returns it
|
||||
func NewGitRepo(dirPath string) *GitRepo {
|
||||
|
||||
var g *GitRepo = &GitRepo{}
|
||||
var err error
|
||||
|
||||
g.dirPath = dirPath
|
||||
g.setupDone = true
|
||||
|
||||
// check if directory is tracked by git repo
|
||||
g.repo, err = git.PlainOpenWithOptions(dirPath, &git.PlainOpenOptions{DetectDotGit: true})
|
||||
if err != nil {
|
||||
return g
|
||||
}
|
||||
|
||||
workTree, err := g.repo.Worktree()
|
||||
if err != nil {
|
||||
return g
|
||||
}
|
||||
|
||||
g.status, err = workTree.Status()
|
||||
if err != nil {
|
||||
return g
|
||||
}
|
||||
|
||||
if g.status == nil {
|
||||
return g
|
||||
}
|
||||
|
||||
plumbRef, err := g.repo.Head()
|
||||
if err != nil {
|
||||
return g
|
||||
}
|
||||
|
||||
// extract short commit ID
|
||||
g.commitID = plumbRef.Hash().String()[:7]
|
||||
|
||||
// get the root path of git repository
|
||||
g.gitRepoRootPath = workTree.Filesystem.Root()
|
||||
|
||||
g.isGitRepo = true
|
||||
return g
|
||||
}
|
||||
|
||||
// IsGitRepo returns if the initialized directory path is tracked by git repo
|
||||
func (g *GitRepo) IsGitRepo() bool {
|
||||
return g.setupDone && g.isGitRepo
|
||||
}
|
||||
|
||||
// getFileCommitLabel returns the value of 'commit' label
|
||||
// for the resources present in the file
|
||||
/*
|
||||
The value of the `commit` label for different status of the file is as follows:
|
||||
| Git File Status | Label Value |
|
||||
|---------------------------------------|----------------------|
|
||||
| New untracked file | untracked |
|
||||
| New staged file | staged |
|
||||
| Tracked file with changes in worktree | <commitID>-unstaged |
|
||||
| Tracked file with changes staged | <commitID>-staged |
|
||||
| Tracked file with clean commit | <commitID> |
|
||||
*/
|
||||
func (g *GitRepo) GetFileCommitLabel(filePath string) (string, error) {
|
||||
|
||||
if !g.setupDone {
|
||||
return "", errors.New(`GitRepo is not setup. It has to be created by calling 'NewGitRepo' function,
|
||||
then this function has to be called.`)
|
||||
}
|
||||
|
||||
if !g.isGitRepo {
|
||||
return "", errors.Errorf(`directory: %s doesn't belong to git repository.`, g.dirPath)
|
||||
}
|
||||
|
||||
// filepath in the git repository
|
||||
splitPathList := strings.Split(filePath, g.gitRepoRootPath+string(os.PathSeparator))
|
||||
if len(splitPathList) != 2 {
|
||||
return "", errors.Errorf("error finding the git repository path of %s", filePath)
|
||||
}
|
||||
gitFilePath := splitPathList[1]
|
||||
gitFileStatus := g.status.File(gitFilePath)
|
||||
|
||||
// check if file is tracked
|
||||
if !g.status.IsUntracked(gitFilePath) {
|
||||
|
||||
// unstaged file
|
||||
if gitFileStatus.Worktree == git.Modified {
|
||||
return fmt.Sprintf("%s-unstaged", g.commitID), nil
|
||||
}
|
||||
|
||||
// newly staged file
|
||||
if gitFileStatus.Staging == git.Added {
|
||||
return "staged", nil
|
||||
}
|
||||
|
||||
// staged file
|
||||
if gitFileStatus.Staging == git.Modified {
|
||||
return fmt.Sprintf("%s-staged", g.commitID), nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check if file is committed already
|
||||
oc, err := g.repo.Log(&git.LogOptions{FileName: &gitFilePath})
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
_, err = oc.Next()
|
||||
defer oc.Close()
|
||||
|
||||
if err != nil {
|
||||
// File not tracked by git and/or not committed
|
||||
return "untracked", nil
|
||||
|
||||
}
|
||||
|
||||
// File tracked by git and has been committed
|
||||
return g.commitID, nil
|
||||
}
|
||||
Reference in New Issue
Block a user