// ReplaceImage Create a duplicate deployment instead of replacing image
ReplaceImage Create a duplicate deployment instead of replacing image
// ReplaceImage Create a duplicate deployment instead of replacing image
func (d *DuplicateDeploymentController) ReplaceImage(ctx context.Context, ops *model.DevStartOptions) error {
	var err error
	d.Client.Context(ctx)
	dep, err := d.Client.GetDeployment(d.Name)
	if err != nil {
		return err
	}
	if d.IsInReplaceDevMode() {
		osj, ok := dep.Annotations[OriginSpecJson]
		if ok {
			log.Info("Annotation nocalhost.origin.spec.json found, use it")
			dep.Spec = appsv1.DeploymentSpec{}
			if err = json.Unmarshal([]byte(osj), &dep.Spec); err != nil {
				return errors.Wrap(err, "")
			}
		} else {
			return errors.New("Annotation nocalhost.origin.spec.json not found?")
		}
	} else {
		osj, ok := dep.Annotations[OriginSpecJson]
		if ok {
			log.Info("Annotation nocalhost.origin.spec.json found, use it")
			oSpec := appsv1.DeploymentSpec{}
			if err = json.Unmarshal([]byte(osj), &oSpec); err == nil {
				dep.Spec = oSpec
			}
		}
	}
	var rs int32 = 1
	dep.Spec.Replicas = &rs
	labelsMap, err := d.getDuplicateLabelsMap()
	if err != nil {
		return err
	}
	dep.Name = d.getDuplicateResourceName()
	dep.Labels = labelsMap
	dep.Status = appsv1.DeploymentStatus{}
	dep.Spec.Selector = &metav1.LabelSelector{MatchLabels: labelsMap}
	dep.Spec.Template.Labels = labelsMap
	dep.ResourceVersion = ""
	devContainer, sideCarContainer, devModeVolumes, err :=
		d.genContainersAndVolumes(&dep.Spec.Template.Spec, ops.Container, ops.DevImage, ops.StorageClass, true)
	if err != nil {
		return err
	}
	if ops.Container != "" {
		for index, c := range dep.Spec.Template.Spec.Containers {
			if c.Name == ops.Container {
				dep.Spec.Template.Spec.Containers[index] = *devContainer
				break
			}
		}
	} else {
		dep.Spec.Template.Spec.Containers[0] = *devContainer
	}
	if dep.Spec.Template.Spec.Volumes == nil {
		log.Debugf("Service %s has no volume", dep.Name)
		dep.Spec.Template.Spec.Volumes = make([]corev1.Volume, 0)
	}
	dep.Spec.Template.Spec.Volumes = append(dep.Spec.Template.Spec.Volumes, devModeVolumes...)
	dep.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{}
	for i := 0; i < len(dep.Spec.Template.Spec.Containers); i++ {
		dep.Spec.Template.Spec.Containers[i].LivenessProbe = nil
		dep.Spec.Template.Spec.Containers[i].ReadinessProbe = nil
		dep.Spec.Template.Spec.Containers[i].StartupProbe = nil
		dep.Spec.Template.Spec.Containers[i].SecurityContext = nil
	}
	dep.Spec.Template.Spec.Containers = append(dep.Spec.Template.Spec.Containers, *sideCarContainer)
	priorityClass := ops.PriorityClass
	if priorityClass == "" {
		svcProfile := d.Config()
		priorityClass = svcProfile.PriorityClass
	}
	if priorityClass != "" {
		log.Infof("Using priorityClass: %s...", priorityClass)
		dep.Spec.Template.Spec.PriorityClassName = priorityClass
	}
	log.Info("Create development container...")
	_, err = d.Client.CreateDeployment(dep)
	if err != nil {
		for i := 0; i < 10; i++ {
			if strings.Contains(err.Error(), "no PriorityClass") {
				log.Warnf("PriorityClass %s not found, disable it...", priorityClass)
				dep, err = d.Client.GetDeployment(d.GetName())
				if err != nil {
					return err
				}
				dep.Spec.Template.Spec.PriorityClassName = ""
				_, err = d.Client.UpdateDeployment(dep, true)
				if err != nil {
					if strings.Contains(err.Error(), "Operation cannot be fulfilled on") {
						log.Warn("Deployment has been modified, retrying...")
						continue
					}
					return err
				}
				break
			} else if strings.Contains(err.Error(), "Operation cannot be fulfilled on") {
				log.Warn("Deployment has been modified, retrying...")
				continue
			}
			return err
		}
	}
	d.patchAfterDevContainerReplaced(ops.Container, dep.Kind, dep.Name)
	return waitingPodToBeReady(d.GetNocalhostDevContainerPod)
}
func ( d * DuplicateDeploymentController ) ReplaceImage ( ctx context . Context , ops * model . DevStartOptions ) error { var err error d . Client . Context ( ctx ) dep , err := d . Client . GetDeployment ( d . Name ) if err != nil { return err } if d . IsInReplaceDevMode ( ) { osj , ok := dep . Annotations [ OriginSpecJson ] if ok { log . Info ( " " ) dep . Spec = appsv1 . DeploymentSpec { } if err = json . Unmarshal ( [ ] byte ( osj ) , & dep . Spec ) ; err != nil { return errors . Wrap ( err , " " ) } } else { return errors . New ( " " ) } } else { osj , ok := dep . Annotations [ OriginSpecJson ] if ok { log . Info ( " " ) oSpec := appsv1 . DeploymentSpec { } if err = json . Unmarshal ( [ ] byte ( osj ) , & oSpec ) ; err == nil { dep . Spec = oSpec } } } var rs int32 = 1 dep . Spec . Replicas = & rs labelsMap , err := d . getDuplicateLabelsMap ( ) if err != nil { return err } dep . Name = d . getDuplicateResourceName ( ) dep . Labels = labelsMap dep . Status = appsv1 . DeploymentStatus { } dep . Spec . Selector = & metav1 . LabelSelector { MatchLabels : labelsMap } dep . Spec . Template . Labels = labelsMap dep . ResourceVersion = " " devContainer , sideCarContainer , devModeVolumes , err := d . genContainersAndVolumes ( & dep . Spec . Template . Spec , ops . Container , ops . DevImage , ops . StorageClass , true ) if err != nil { return err } if ops . Container != " " { for index , c := range dep . Spec . Template . Spec . Containers { if c . Name == ops . Container { dep . Spec . Template . Spec . Containers [ index ] = * devContainer break } } } else { dep . Spec . Template . Spec . Containers [ 0 ] = * devContainer } if dep . Spec . Template . Spec . Volumes == nil { log . Debugf ( " " , dep . Name ) dep . Spec . Template . Spec . Volumes = make ( [ ] corev1 . Volume , 0 ) } dep . Spec . Template . Spec . Volumes = append ( dep . Spec . Template . Spec . Volumes , devModeVolumes ... ) dep . Spec . Template . Spec . SecurityContext = & corev1 . PodSecurityContext { } for i := 0 ; i < len ( dep . Spec . Template . Spec . Containers ) ; i ++ { dep . Spec . Template . Spec . Containers [ i ] . LivenessProbe = nil dep . Spec . Template . Spec . Containers [ i ] . ReadinessProbe = nil dep . Spec . Template . Spec . Containers [ i ] . StartupProbe = nil dep . Spec . Template . Spec . Containers [ i ] . SecurityContext = nil } dep . Spec . Template . Spec . Containers = append ( dep . Spec . Template . Spec . Containers , * sideCarContainer ) priorityClass := ops . PriorityClass if priorityClass == " " { svcProfile := d . Config ( ) priorityClass = svcProfile . PriorityClass } if priorityClass != " " { log . Infof ( " " , priorityClass ) dep . Spec . Template . Spec . PriorityClassName = priorityClass } log . Info ( " " ) _ , err = d . Client . CreateDeployment ( dep ) if err != nil { for i := 0 ; i < 10 ; i ++ { if strings . Contains ( err . Error ( ) , " " ) { log . Warnf ( " " , priorityClass ) dep , err = d . Client . GetDeployment ( d . GetName ( ) ) if err != nil { return err } dep . Spec . Template . Spec . PriorityClassName = " " _ , err = d . Client . UpdateDeployment ( dep , true ) if err != nil { if strings . Contains ( err . Error ( ) , " " ) { log . Warn ( " " ) continue } return err } break } else if strings . Contains ( err . Error ( ) , " " ) { log . Warn ( " " ) continue } return err } } d . patchAfterDevContainerReplaced ( ops . Container , dep . Kind , dep . Name ) return waitingPodToBeReady ( d . GetNocalhostDevContainerPod ) }
ReplaceImage Create a duplicate deployment instead of replacing image
ReplaceImage Create a duplicate deployment instead of replacing image
// Add volumes to deployment spec // delete user's SecurityContext // disable readiness probes // PriorityClass