Beispiel #1
0
func (l *buildLoader) Load() error {
	list, err := l.lister.Builds(l.namespace).List(kapi.ListOptions{})
	if err != nil {
		return errors.TolerateNotFoundError(err)
	}

	l.items = list.Items
	return nil
}
Beispiel #2
0
func (l *buildLoader) Load() error {
	list, err := l.lister.Builds(l.namespace).List(labels.Everything(), fields.Everything())
	if err != nil {
		return errors.TolerateNotFoundError(err)
	}

	l.items = list.Items
	return nil
}
Beispiel #3
0
func waitForEndpointsAvailable(oc *exutil.CLI, serviceName string) error {
	return wait.Poll(200*time.Millisecond, 2*time.Minute, func() (bool, error) {
		ep, err := oc.KubeClient().Core().Endpoints(oc.Namespace()).Get(serviceName)
		// Tolerate NotFound b/c it could take a moment for the endpoints to be created
		if errors.TolerateNotFoundError(err) != nil {
			return false, err
		}

		return (len(ep.Subsets) > 0) && (len(ep.Subsets[0].Addresses) > 0), nil
	})
}
Beispiel #4
0
// findScalableResourcesForEndpoints takes an Endpoints object and looks for the associated
// scalable objects by checking each address in each subset to see if it has a pod
// reference, and the following that pod reference to find the owning controller,
// and returning the unique set of controllers found this way.
func findScalableResourcesForEndpoints(endpoints *kapi.Endpoints, decoder runtime.Decoder, getPod func(kapi.ObjectReference) (*kapi.Pod, error), getController func(kapi.ObjectReference) (runtime.Object, error)) (map[unidlingapi.CrossGroupObjectReference]struct{}, error) {
	// To find all RCs and DCs for an endpoint, we first figure out which pods are pointed to by that endpoint...
	podRefs := map[kapi.ObjectReference]*kapi.Pod{}
	for _, subset := range endpoints.Subsets {
		for _, addr := range subset.Addresses {
			if addr.TargetRef != nil && addr.TargetRef.Kind == "Pod" {
				pod, err := getPod(*addr.TargetRef)
				if utilerrors.TolerateNotFoundError(err) != nil {
					return nil, fmt.Errorf("unable to find controller for pod %s/%s: %v", addr.TargetRef.Namespace, addr.TargetRef.Name, err)
				}

				if pod != nil {
					podRefs[*addr.TargetRef] = pod
				}
			}
		}
	}

	// ... then, for each pod, we check the controller, and find the set of unique controllers...
	immediateControllerRefs := make(map[kapi.ObjectReference]struct{})
	for _, pod := range podRefs {
		controllerRef, err := getControllerRef(pod, decoder)
		if err != nil {
			return nil, fmt.Errorf("unable to find controller for pod %s/%s: %v", pod.Namespace, pod.Name, err)
		} else if controllerRef == nil {
			return nil, fmt.Errorf("unable to find controller for pod %s/%s: no creator reference listed", pod.Namespace, pod.Name)
		}

		immediateControllerRefs[*controllerRef] = struct{}{}
	}

	// ... finally, for each controller, we load it, and see if there is a corresponding owner (to cover cases like DCs, Deployments, etc)
	controllerRefs := make(map[unidlingapi.CrossGroupObjectReference]struct{})
	for controllerRef := range immediateControllerRefs {
		controller, err := getController(controllerRef)
		if utilerrors.TolerateNotFoundError(err) != nil {
			return nil, fmt.Errorf("unable to load %s %q: %v", controllerRef.Kind, controllerRef.Name, err)
		}

		if controller != nil {
			var parentControllerRef *kapi.ObjectReference
			parentControllerRef, err = getControllerRef(controller, decoder)
			if err != nil {
				return nil, fmt.Errorf("unable to load the creator of %s %q: %v", controllerRef.Kind, controllerRef.Name, err)
			}

			var crossGroupObjRef unidlingapi.CrossGroupObjectReference
			if parentControllerRef == nil {
				// if this is just a plain RC, use it
				crossGroupObjRef, err = makeCrossGroupObjRef(&controllerRef)
			} else {
				crossGroupObjRef, err = makeCrossGroupObjRef(parentControllerRef)
			}

			if err != nil {
				return nil, fmt.Errorf("unable to load the creator of %s %q: %v", controllerRef.Kind, controllerRef.Name, err)
			}
			controllerRefs[crossGroupObjRef] = struct{}{}
		}
	}

	return controllerRefs, nil
}
Beispiel #5
0
// Complete the options for prune images
func (o *PruneImagesOptions) Complete(f *clientcmd.Factory, args []string, out io.Writer) error {
	if len(args) > 0 {
		return errors.New("no arguments are allowed to this command")
	}

	o.Out = out

	osClient, kClient, registryClient, err := getClients(f, o.CABundle)
	if err != nil {
		return err
	}
	o.Client = osClient

	allImages, err := osClient.Images().List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allStreams, err := osClient.ImageStreams(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allPods, err := kClient.Pods(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allRCs, err := kClient.ReplicationControllers(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allBCs, err := osClient.BuildConfigs(kapi.NamespaceAll).List(kapi.ListOptions{})
	// We need to tolerate 'not found' errors for buildConfigs since they may be disabled in Atomic
	err = oserrors.TolerateNotFoundError(err)
	if err != nil {
		return err
	}

	allBuilds, err := osClient.Builds(kapi.NamespaceAll).List(kapi.ListOptions{})
	// We need to tolerate 'not found' errors for builds since they may be disabled in Atomic
	err = oserrors.TolerateNotFoundError(err)
	if err != nil {
		return err
	}

	allDCs, err := osClient.DeploymentConfigs(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	options := prune.ImageRegistryPrunerOptions{
		KeepYoungerThan:  o.KeepYoungerThan,
		KeepTagRevisions: o.KeepTagRevisions,
		Images:           allImages,
		Streams:          allStreams,
		Pods:             allPods,
		RCs:              allRCs,
		BCs:              allBCs,
		Builds:           allBuilds,
		DCs:              allDCs,
		DryRun:           o.Confirm == false,
		RegistryClient:   registryClient,
		RegistryURL:      o.RegistryUrlOverride,
	}

	o.Pruner = prune.NewImageRegistryPruner(options)

	return nil
}
Beispiel #6
0
// Run contains all the necessary functionality for the OpenShift cli prune images command.
func (o PruneImagesOptions) Run() error {
	allImages, err := o.OSClient.Images().List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allStreams, err := o.OSClient.ImageStreams(o.Namespace).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allPods, err := o.KClient.Core().Pods(o.Namespace).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allRCs, err := o.KClient.Core().ReplicationControllers(o.Namespace).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allBCs, err := o.OSClient.BuildConfigs(o.Namespace).List(kapi.ListOptions{})
	// We need to tolerate 'not found' errors for buildConfigs since they may be disabled in Atomic
	err = oserrors.TolerateNotFoundError(err)
	if err != nil {
		return err
	}

	allBuilds, err := o.OSClient.Builds(o.Namespace).List(kapi.ListOptions{})
	// We need to tolerate 'not found' errors for builds since they may be disabled in Atomic
	err = oserrors.TolerateNotFoundError(err)
	if err != nil {
		return err
	}

	allDCs, err := o.OSClient.DeploymentConfigs(o.Namespace).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	limitRangesList, err := o.KClient.Core().LimitRanges(o.Namespace).List(kapi.ListOptions{})
	if err != nil {
		return err
	}
	limitRangesMap := make(map[string][]*kapi.LimitRange)
	for i := range limitRangesList.Items {
		limit := limitRangesList.Items[i]
		limits, ok := limitRangesMap[limit.Namespace]
		if !ok {
			limits = []*kapi.LimitRange{}
		}
		limits = append(limits, &limit)
		limitRangesMap[limit.Namespace] = limits
	}

	options := prune.PrunerOptions{
		KeepYoungerThan:    o.KeepYoungerThan,
		KeepTagRevisions:   o.KeepTagRevisions,
		PruneOverSizeLimit: o.PruneOverSizeLimit,
		AllImages:          o.AllImages,
		Images:             allImages,
		Streams:            allStreams,
		Pods:               allPods,
		RCs:                allRCs,
		BCs:                allBCs,
		Builds:             allBuilds,
		DCs:                allDCs,
		LimitRanges:        limitRangesMap,
		DryRun:             o.Confirm == false,
		RegistryClient:     o.RegistryClient,
		RegistryURL:        o.RegistryUrlOverride,
	}
	if o.Namespace != kapi.NamespaceAll {
		options.Namespace = o.Namespace
	}
	pruner := prune.NewPruner(options)

	w := tabwriter.NewWriter(o.Out, 10, 4, 3, ' ', 0)
	defer w.Flush()

	imageDeleter := &describingImageDeleter{w: w}
	imageStreamDeleter := &describingImageStreamDeleter{w: w}
	layerLinkDeleter := &describingLayerLinkDeleter{w: w}
	blobDeleter := &describingBlobDeleter{w: w}
	manifestDeleter := &describingManifestDeleter{w: w}

	if o.Confirm {
		imageDeleter.delegate = prune.NewImageDeleter(o.OSClient.Images())
		imageStreamDeleter.delegate = prune.NewImageStreamDeleter(o.OSClient)
		layerLinkDeleter.delegate = prune.NewLayerLinkDeleter()
		blobDeleter.delegate = prune.NewBlobDeleter()
		manifestDeleter.delegate = prune.NewManifestDeleter()
	} else {
		fmt.Fprintln(os.Stderr, "Dry run enabled - no modifications will be made. Add --confirm to remove images")
	}

	return pruner.Prune(imageDeleter, imageStreamDeleter, layerLinkDeleter, blobDeleter, manifestDeleter)
}
Beispiel #7
0
func NewCmdPruneImages(f *clientcmd.Factory, parentName, name string, out io.Writer) *cobra.Command {
	cfg := &pruneImagesConfig{
		Confirm:          false,
		KeepYoungerThan:  60 * time.Minute,
		KeepTagRevisions: 3,
	}

	cmd := &cobra.Command{
		Use:   name,
		Short: "Remove unreferenced images",
		Long:  fmt.Sprintf(imagesLongDesc, parentName, name),

		Run: func(cmd *cobra.Command, args []string) {
			if len(args) > 0 {
				glog.Fatal("No arguments are allowed to this command")
			}

			osClient, kClient, registryClient, err := getClients(f, cfg)
			cmdutil.CheckErr(err)

			allImages, err := osClient.Images().List(labels.Everything(), fields.Everything())
			cmdutil.CheckErr(err)

			allStreams, err := osClient.ImageStreams(kapi.NamespaceAll).List(labels.Everything(), fields.Everything())
			cmdutil.CheckErr(err)

			allPods, err := kClient.Pods(kapi.NamespaceAll).List(labels.Everything(), fields.Everything())
			cmdutil.CheckErr(err)

			allRCs, err := kClient.ReplicationControllers(kapi.NamespaceAll).List(labels.Everything())
			cmdutil.CheckErr(err)

			allBCs, err := osClient.BuildConfigs(kapi.NamespaceAll).List(labels.Everything(), fields.Everything())
			// We need to tolerate 'not found' errors for buildConfigs since they may be disabled in Atomic
			err = oserrors.TolerateNotFoundError(err)
			cmdutil.CheckErr(err)

			allBuilds, err := osClient.Builds(kapi.NamespaceAll).List(labels.Everything(), fields.Everything())
			// We need to tolerate 'not found' errors for builds since they may be disabled in Atomic
			err = oserrors.TolerateNotFoundError(err)
			cmdutil.CheckErr(err)

			allDCs, err := osClient.DeploymentConfigs(kapi.NamespaceAll).List(labels.Everything(), fields.Everything())
			cmdutil.CheckErr(err)

			dryRun := cfg.Confirm == false

			options := prune.ImageRegistryPrunerOptions{
				KeepYoungerThan:  cfg.KeepYoungerThan,
				KeepTagRevisions: cfg.KeepTagRevisions,
				Images:           allImages,
				Streams:          allStreams,
				Pods:             allPods,
				RCs:              allRCs,
				BCs:              allBCs,
				Builds:           allBuilds,
				DCs:              allDCs,
				DryRun:           dryRun,
				RegistryClient:   registryClient,
				RegistryURL:      cfg.RegistryUrlOverride,
			}
			pruner := prune.NewImageRegistryPruner(options)

			// this tabwriter is used by the describing*Pruners below for their output
			w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0)
			defer w.Flush()

			imagePruner := &describingImagePruner{w: w}
			imageStreamPruner := &describingImageStreamPruner{w: w}
			layerPruner := &describingLayerPruner{w: w}
			blobPruner := &describingBlobPruner{w: w}
			manifestPruner := &describingManifestPruner{w: w}

			switch cfg.Confirm {
			case true:
				imagePruner.delegate = prune.NewDeletingImagePruner(osClient.Images())
				imageStreamPruner.delegate = prune.NewDeletingImageStreamPruner(osClient)
				layerPruner.delegate = prune.NewDeletingLayerPruner()
				blobPruner.delegate = prune.NewDeletingBlobPruner()
				manifestPruner.delegate = prune.NewDeletingManifestPruner()
			default:
				fmt.Fprintln(os.Stderr, "Dry run enabled - no modifications will be made. Add --confirm to remove images")
			}

			err = pruner.Prune(imagePruner, imageStreamPruner, layerPruner, blobPruner, manifestPruner)
			cmdutil.CheckErr(err)
		},
	}

	cmd.Flags().BoolVar(&cfg.Confirm, "confirm", cfg.Confirm, "Specify that image pruning should proceed. Defaults to false, displaying what would be deleted but not actually deleting anything.")
	cmd.Flags().DurationVar(&cfg.KeepYoungerThan, "keep-younger-than", cfg.KeepYoungerThan, "Specify the minimum age of a build for it to be considered a candidate for pruning.")
	cmd.Flags().IntVar(&cfg.KeepTagRevisions, "keep-tag-revisions", cfg.KeepTagRevisions, "Specify the number of image revisions for a tag in an image stream that will be preserved.")
	cmd.Flags().StringVar(&cfg.CABundle, "certificate-authority", cfg.CABundle, "The path to a certificate authority bundle to use when communicating with the managed Docker registries. Defaults to the certificate authority data from the current user's config file.")
	cmd.Flags().StringVar(&cfg.RegistryUrlOverride, "registry-url", cfg.RegistryUrlOverride, "The address to use when contacting the registry, instead of using the default value. This is useful if you can't resolve or reach the registry (e.g.; the default is a cluster-internal URL) but you do have an alternative route that works.")

	return cmd
}
Beispiel #8
0
// Complete turns a partially defined PruneImagesOptions into a solvent structure
// which can be validated and used for pruning images.
func (o *PruneImagesOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
	if len(args) > 0 {
		return kcmdutil.UsageError(cmd, "no arguments are allowed to this command")
	}

	if !cmd.Flags().Lookup("keep-younger-than").Changed {
		o.KeepYoungerThan = nil
	}
	if !cmd.Flags().Lookup("keep-tag-revisions").Changed {
		o.KeepTagRevisions = nil
	}
	if !cmd.Flags().Lookup("prune-over-size-limit").Changed {
		o.PruneOverSizeLimit = nil
	}

	o.Out = out

	osClient, kClient, registryClient, err := getClients(f, o.CABundle)
	if err != nil {
		return err
	}
	o.Client = osClient

	allImages, err := osClient.Images().List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allStreams, err := osClient.ImageStreams(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allPods, err := kClient.Pods(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allRCs, err := kClient.ReplicationControllers(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	allBCs, err := osClient.BuildConfigs(kapi.NamespaceAll).List(kapi.ListOptions{})
	// We need to tolerate 'not found' errors for buildConfigs since they may be disabled in Atomic
	err = oserrors.TolerateNotFoundError(err)
	if err != nil {
		return err
	}

	allBuilds, err := osClient.Builds(kapi.NamespaceAll).List(kapi.ListOptions{})
	// We need to tolerate 'not found' errors for builds since they may be disabled in Atomic
	err = oserrors.TolerateNotFoundError(err)
	if err != nil {
		return err
	}

	allDCs, err := osClient.DeploymentConfigs(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	limitRangesList, err := kClient.LimitRanges(kapi.NamespaceAll).List(kapi.ListOptions{})
	if err != nil {
		return err
	}
	limitRangesMap := make(map[string][]*kapi.LimitRange)
	for i := range limitRangesList.Items {
		limit := limitRangesList.Items[i]
		limits, ok := limitRangesMap[limit.Namespace]
		if !ok {
			limits = []*kapi.LimitRange{}
		}
		limits = append(limits, &limit)
		limitRangesMap[limit.Namespace] = limits
	}

	options := prune.PrunerOptions{
		KeepYoungerThan:    o.KeepYoungerThan,
		KeepTagRevisions:   o.KeepTagRevisions,
		PruneOverSizeLimit: o.PruneOverSizeLimit,
		Images:             allImages,
		Streams:            allStreams,
		Pods:               allPods,
		RCs:                allRCs,
		BCs:                allBCs,
		Builds:             allBuilds,
		DCs:                allDCs,
		LimitRanges:        limitRangesMap,
		DryRun:             o.Confirm == false,
		RegistryClient:     registryClient,
		RegistryURL:        o.RegistryUrlOverride,
	}

	o.Pruner = prune.NewPruner(options)

	return nil
}