diff --git a/contrib/completions/bash/oc b/contrib/completions/bash/oc index 0902c2bbba3f..496a6b180665 100644 --- a/contrib/completions/bash/oc +++ b/contrib/completions/bash/oc @@ -2049,104 +2049,6 @@ _oc_adm_create-login-template() noun_aliases=() } -_oc_adm_create-node-config() -{ - last_command="oc_adm_create-node-config" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-disabled-docker") - local_nonpersistent_flags+=("--allow-disabled-docker") - flags+=("--dns-bind-address=") - local_nonpersistent_flags+=("--dns-bind-address=") - flags+=("--dns-domain=") - local_nonpersistent_flags+=("--dns-domain=") - flags+=("--dns-ip=") - local_nonpersistent_flags+=("--dns-ip=") - flags+=("--expire-days=") - local_nonpersistent_flags+=("--expire-days=") - flags+=("--hostnames=") - local_nonpersistent_flags+=("--hostnames=") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--listen=") - local_nonpersistent_flags+=("--listen=") - flags+=("--master=") - local_nonpersistent_flags+=("--master=") - flags+=("--network-plugin=") - local_nonpersistent_flags+=("--network-plugin=") - flags+=("--node=") - local_nonpersistent_flags+=("--node=") - flags+=("--node-client-certificate-authority=") - flags_with_completion+=("--node-client-certificate-authority") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--node-client-certificate-authority=") - flags+=("--node-dir=") - flags_with_completion+=("--node-dir") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--node-dir=") - flags+=("--server-certificate=") - flags_with_completion+=("--server-certificate") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--server-certificate=") - flags+=("--server-key=") - flags_with_completion+=("--server-key") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--server-key=") - flags+=("--signer-cert=") - flags_with_completion+=("--signer-cert") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--signer-cert=") - flags+=("--signer-key=") - flags_with_completion+=("--signer-key") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--signer-key=") - flags+=("--signer-serial=") - flags_with_completion+=("--signer-serial") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--signer-serial=") - flags+=("--volume-dir=") - flags_with_completion+=("--volume-dir") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--volume-dir=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_create-provider-selection-template() { last_command="oc_adm_create-provider-selection-template" @@ -2568,164 +2470,6 @@ _oc_adm_groups() noun_aliases=() } -_oc_adm_ipfailover() -{ - last_command="oc_adm_ipfailover" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--check-interval=") - local_nonpersistent_flags+=("--check-interval=") - flags+=("--check-script=") - local_nonpersistent_flags+=("--check-script=") - flags+=("--create") - local_nonpersistent_flags+=("--create") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--interface=") - two_word_flags+=("-i") - local_nonpersistent_flags+=("--interface=") - flags+=("--iptables-chain=") - local_nonpersistent_flags+=("--iptables-chain=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--notify-script=") - local_nonpersistent_flags+=("--notify-script=") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--preemption-strategy=") - local_nonpersistent_flags+=("--preemption-strategy=") - flags+=("--replicas=") - two_word_flags+=("-r") - local_nonpersistent_flags+=("--replicas=") - flags+=("--selector=") - two_word_flags+=("-l") - local_nonpersistent_flags+=("--selector=") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--type=") - local_nonpersistent_flags+=("--type=") - flags+=("--virtual-ip-groups=") - local_nonpersistent_flags+=("--virtual-ip-groups=") - flags+=("--virtual-ips=") - local_nonpersistent_flags+=("--virtual-ips=") - flags+=("--vrrp-id-offset=") - local_nonpersistent_flags+=("--vrrp-id-offset=") - flags+=("--watch-port=") - two_word_flags+=("-w") - local_nonpersistent_flags+=("--watch-port=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_oc_adm_manage-node() -{ - last_command="oc_adm_manage-node" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--force") - local_nonpersistent_flags+=("--force") - flags+=("--grace-period=") - local_nonpersistent_flags+=("--grace-period=") - flags+=("--list-pods") - local_nonpersistent_flags+=("--list-pods") - flags+=("--no-headers") - local_nonpersistent_flags+=("--no-headers") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--pod-selector=") - local_nonpersistent_flags+=("--pod-selector=") - flags+=("--schedulable") - local_nonpersistent_flags+=("--schedulable") - flags+=("--selector=") - local_nonpersistent_flags+=("--selector=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_migrate_etcd-ttl() { last_command="oc_adm_migrate_etcd-ttl" @@ -4836,104 +4580,6 @@ _oc_adm_prune() noun_aliases=() } -_oc_adm_registry() -{ - last_command="oc_adm_registry" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--cluster-ip=") - local_nonpersistent_flags+=("--cluster-ip=") - flags+=("--create") - local_nonpersistent_flags+=("--create") - flags+=("--daemonset") - local_nonpersistent_flags+=("--daemonset") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--enforce-quota") - local_nonpersistent_flags+=("--enforce-quota") - flags+=("--fs-group=") - local_nonpersistent_flags+=("--fs-group=") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--labels=") - local_nonpersistent_flags+=("--labels=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--local") - local_nonpersistent_flags+=("--local") - flags+=("--mount-host=") - local_nonpersistent_flags+=("--mount-host=") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--ports=") - local_nonpersistent_flags+=("--ports=") - flags+=("--replicas=") - local_nonpersistent_flags+=("--replicas=") - flags+=("--selector=") - local_nonpersistent_flags+=("--selector=") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--show-all") - flags+=("-a") - local_nonpersistent_flags+=("--show-all") - flags+=("--show-labels") - local_nonpersistent_flags+=("--show-labels") - flags+=("--sort-by=") - local_nonpersistent_flags+=("--sort-by=") - flags+=("--supplemental-groups=") - local_nonpersistent_flags+=("--supplemental-groups=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--tls-certificate=") - local_nonpersistent_flags+=("--tls-certificate=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--type=") - local_nonpersistent_flags+=("--type=") - flags+=("--volume=") - local_nonpersistent_flags+=("--volume=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_release_extract() { last_command="oc_adm_release_extract" @@ -5216,148 +4862,6 @@ _oc_adm_release() noun_aliases=() } -_oc_adm_router() -{ - last_command="oc_adm_router" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--ciphers=") - local_nonpersistent_flags+=("--ciphers=") - flags+=("--create") - local_nonpersistent_flags+=("--create") - flags+=("--default-cert=") - local_nonpersistent_flags+=("--default-cert=") - flags+=("--disable-namespace-ownership-check") - local_nonpersistent_flags+=("--disable-namespace-ownership-check") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--extended-logging") - local_nonpersistent_flags+=("--extended-logging") - flags+=("--external-host=") - local_nonpersistent_flags+=("--external-host=") - flags+=("--external-host-http-vserver=") - local_nonpersistent_flags+=("--external-host-http-vserver=") - flags+=("--external-host-https-vserver=") - local_nonpersistent_flags+=("--external-host-https-vserver=") - flags+=("--external-host-insecure") - local_nonpersistent_flags+=("--external-host-insecure") - flags+=("--external-host-internal-ip=") - local_nonpersistent_flags+=("--external-host-internal-ip=") - flags+=("--external-host-partition-path=") - local_nonpersistent_flags+=("--external-host-partition-path=") - flags+=("--external-host-password=") - local_nonpersistent_flags+=("--external-host-password=") - flags+=("--external-host-private-key=") - local_nonpersistent_flags+=("--external-host-private-key=") - flags+=("--external-host-username=") - local_nonpersistent_flags+=("--external-host-username=") - flags+=("--external-host-vxlan-gw=") - local_nonpersistent_flags+=("--external-host-vxlan-gw=") - flags+=("--force-subdomain=") - local_nonpersistent_flags+=("--force-subdomain=") - flags+=("--host-network") - local_nonpersistent_flags+=("--host-network") - flags+=("--host-ports") - local_nonpersistent_flags+=("--host-ports") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--labels=") - local_nonpersistent_flags+=("--labels=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--local") - local_nonpersistent_flags+=("--local") - flags+=("--max-connections=") - local_nonpersistent_flags+=("--max-connections=") - flags+=("--mutual-tls-auth=") - local_nonpersistent_flags+=("--mutual-tls-auth=") - flags+=("--mutual-tls-auth-ca=") - local_nonpersistent_flags+=("--mutual-tls-auth-ca=") - flags+=("--mutual-tls-auth-crl=") - local_nonpersistent_flags+=("--mutual-tls-auth-crl=") - flags+=("--mutual-tls-auth-filter=") - local_nonpersistent_flags+=("--mutual-tls-auth-filter=") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--output-version=") - local_nonpersistent_flags+=("--output-version=") - flags+=("--ports=") - local_nonpersistent_flags+=("--ports=") - flags+=("--replicas=") - local_nonpersistent_flags+=("--replicas=") - flags+=("--router-canonical-hostname=") - local_nonpersistent_flags+=("--router-canonical-hostname=") - flags+=("--secrets-as-env") - local_nonpersistent_flags+=("--secrets-as-env") - flags+=("--selector=") - local_nonpersistent_flags+=("--selector=") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--show-all") - flags+=("-a") - local_nonpersistent_flags+=("--show-all") - flags+=("--show-labels") - local_nonpersistent_flags+=("--show-labels") - flags+=("--sort-by=") - local_nonpersistent_flags+=("--sort-by=") - flags+=("--stats-password=") - local_nonpersistent_flags+=("--stats-password=") - flags+=("--stats-port=") - local_nonpersistent_flags+=("--stats-port=") - flags+=("--stats-user=") - local_nonpersistent_flags+=("--stats-user=") - flags+=("--strict-sni") - local_nonpersistent_flags+=("--strict-sni") - flags+=("--subdomain=") - local_nonpersistent_flags+=("--subdomain=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--threads=") - local_nonpersistent_flags+=("--threads=") - flags+=("--type=") - local_nonpersistent_flags+=("--type=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_taint() { last_command="oc_adm_taint" @@ -5706,6 +5210,54 @@ _oc_adm_uncordon() noun_aliases=() } +_oc_adm_upgrade() +{ + last_command="oc_adm_upgrade" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--force") + local_nonpersistent_flags+=("--force") + flags+=("--to=") + local_nonpersistent_flags+=("--to=") + flags+=("--to-image=") + local_nonpersistent_flags+=("--to-image=") + flags+=("--as=") + flags+=("--as-group=") + flags+=("--cache-dir=") + flags+=("--certificate-authority=") + flags+=("--client-certificate=") + flags+=("--client-key=") + flags+=("--cluster=") + flags+=("--config=") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--kubeconfig=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + flags_with_completion+=("--namespace") + flags_completion+=("__oc_get_namespaces") + two_word_flags+=("-n") + flags_with_completion+=("-n") + flags_completion+=("__oc_get_namespaces") + flags+=("--request-timeout=") + flags+=("--server=") + two_word_flags+=("-s") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oc_adm_verify-image-signature() { last_command="oc_adm_verify-image-signature" @@ -5776,24 +5328,20 @@ _oc_adm() commands+=("create-error-template") commands+=("create-kubeconfig") commands+=("create-login-template") - commands+=("create-node-config") commands+=("create-provider-selection-template") commands+=("drain") commands+=("groups") - commands+=("ipfailover") - commands+=("manage-node") commands+=("migrate") commands+=("new-project") commands+=("options") commands+=("pod-network") commands+=("policy") commands+=("prune") - commands+=("registry") commands+=("release") - commands+=("router") commands+=("taint") commands+=("top") commands+=("uncordon") + commands+=("upgrade") commands+=("verify-image-signature") flags=() diff --git a/contrib/completions/zsh/oc b/contrib/completions/zsh/oc index 2a141fab8f43..10f3f1e3d7af 100644 --- a/contrib/completions/zsh/oc +++ b/contrib/completions/zsh/oc @@ -2191,104 +2191,6 @@ _oc_adm_create-login-template() noun_aliases=() } -_oc_adm_create-node-config() -{ - last_command="oc_adm_create-node-config" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-disabled-docker") - local_nonpersistent_flags+=("--allow-disabled-docker") - flags+=("--dns-bind-address=") - local_nonpersistent_flags+=("--dns-bind-address=") - flags+=("--dns-domain=") - local_nonpersistent_flags+=("--dns-domain=") - flags+=("--dns-ip=") - local_nonpersistent_flags+=("--dns-ip=") - flags+=("--expire-days=") - local_nonpersistent_flags+=("--expire-days=") - flags+=("--hostnames=") - local_nonpersistent_flags+=("--hostnames=") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--listen=") - local_nonpersistent_flags+=("--listen=") - flags+=("--master=") - local_nonpersistent_flags+=("--master=") - flags+=("--network-plugin=") - local_nonpersistent_flags+=("--network-plugin=") - flags+=("--node=") - local_nonpersistent_flags+=("--node=") - flags+=("--node-client-certificate-authority=") - flags_with_completion+=("--node-client-certificate-authority") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--node-client-certificate-authority=") - flags+=("--node-dir=") - flags_with_completion+=("--node-dir") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--node-dir=") - flags+=("--server-certificate=") - flags_with_completion+=("--server-certificate") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--server-certificate=") - flags+=("--server-key=") - flags_with_completion+=("--server-key") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--server-key=") - flags+=("--signer-cert=") - flags_with_completion+=("--signer-cert") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--signer-cert=") - flags+=("--signer-key=") - flags_with_completion+=("--signer-key") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--signer-key=") - flags+=("--signer-serial=") - flags_with_completion+=("--signer-serial") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--signer-serial=") - flags+=("--volume-dir=") - flags_with_completion+=("--volume-dir") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--volume-dir=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_create-provider-selection-template() { last_command="oc_adm_create-provider-selection-template" @@ -2710,164 +2612,6 @@ _oc_adm_groups() noun_aliases=() } -_oc_adm_ipfailover() -{ - last_command="oc_adm_ipfailover" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--check-interval=") - local_nonpersistent_flags+=("--check-interval=") - flags+=("--check-script=") - local_nonpersistent_flags+=("--check-script=") - flags+=("--create") - local_nonpersistent_flags+=("--create") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--interface=") - two_word_flags+=("-i") - local_nonpersistent_flags+=("--interface=") - flags+=("--iptables-chain=") - local_nonpersistent_flags+=("--iptables-chain=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--notify-script=") - local_nonpersistent_flags+=("--notify-script=") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--preemption-strategy=") - local_nonpersistent_flags+=("--preemption-strategy=") - flags+=("--replicas=") - two_word_flags+=("-r") - local_nonpersistent_flags+=("--replicas=") - flags+=("--selector=") - two_word_flags+=("-l") - local_nonpersistent_flags+=("--selector=") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--type=") - local_nonpersistent_flags+=("--type=") - flags+=("--virtual-ip-groups=") - local_nonpersistent_flags+=("--virtual-ip-groups=") - flags+=("--virtual-ips=") - local_nonpersistent_flags+=("--virtual-ips=") - flags+=("--vrrp-id-offset=") - local_nonpersistent_flags+=("--vrrp-id-offset=") - flags+=("--watch-port=") - two_word_flags+=("-w") - local_nonpersistent_flags+=("--watch-port=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - -_oc_adm_manage-node() -{ - last_command="oc_adm_manage-node" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--force") - local_nonpersistent_flags+=("--force") - flags+=("--grace-period=") - local_nonpersistent_flags+=("--grace-period=") - flags+=("--list-pods") - local_nonpersistent_flags+=("--list-pods") - flags+=("--no-headers") - local_nonpersistent_flags+=("--no-headers") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--pod-selector=") - local_nonpersistent_flags+=("--pod-selector=") - flags+=("--schedulable") - local_nonpersistent_flags+=("--schedulable") - flags+=("--selector=") - local_nonpersistent_flags+=("--selector=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_migrate_etcd-ttl() { last_command="oc_adm_migrate_etcd-ttl" @@ -4978,104 +4722,6 @@ _oc_adm_prune() noun_aliases=() } -_oc_adm_registry() -{ - last_command="oc_adm_registry" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--cluster-ip=") - local_nonpersistent_flags+=("--cluster-ip=") - flags+=("--create") - local_nonpersistent_flags+=("--create") - flags+=("--daemonset") - local_nonpersistent_flags+=("--daemonset") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--enforce-quota") - local_nonpersistent_flags+=("--enforce-quota") - flags+=("--fs-group=") - local_nonpersistent_flags+=("--fs-group=") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--labels=") - local_nonpersistent_flags+=("--labels=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--local") - local_nonpersistent_flags+=("--local") - flags+=("--mount-host=") - local_nonpersistent_flags+=("--mount-host=") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--ports=") - local_nonpersistent_flags+=("--ports=") - flags+=("--replicas=") - local_nonpersistent_flags+=("--replicas=") - flags+=("--selector=") - local_nonpersistent_flags+=("--selector=") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--show-all") - flags+=("-a") - local_nonpersistent_flags+=("--show-all") - flags+=("--show-labels") - local_nonpersistent_flags+=("--show-labels") - flags+=("--sort-by=") - local_nonpersistent_flags+=("--sort-by=") - flags+=("--supplemental-groups=") - local_nonpersistent_flags+=("--supplemental-groups=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--tls-certificate=") - local_nonpersistent_flags+=("--tls-certificate=") - flags+=("--tls-key=") - local_nonpersistent_flags+=("--tls-key=") - flags+=("--type=") - local_nonpersistent_flags+=("--type=") - flags+=("--volume=") - local_nonpersistent_flags+=("--volume=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_release_extract() { last_command="oc_adm_release_extract" @@ -5358,148 +5004,6 @@ _oc_adm_release() noun_aliases=() } -_oc_adm_router() -{ - last_command="oc_adm_router" - commands=() - - flags=() - two_word_flags=() - local_nonpersistent_flags=() - flags_with_completion=() - flags_completion=() - - flags+=("--allow-missing-template-keys") - local_nonpersistent_flags+=("--allow-missing-template-keys") - flags+=("--ciphers=") - local_nonpersistent_flags+=("--ciphers=") - flags+=("--create") - local_nonpersistent_flags+=("--create") - flags+=("--default-cert=") - local_nonpersistent_flags+=("--default-cert=") - flags+=("--disable-namespace-ownership-check") - local_nonpersistent_flags+=("--disable-namespace-ownership-check") - flags+=("--dry-run") - local_nonpersistent_flags+=("--dry-run") - flags+=("--extended-logging") - local_nonpersistent_flags+=("--extended-logging") - flags+=("--external-host=") - local_nonpersistent_flags+=("--external-host=") - flags+=("--external-host-http-vserver=") - local_nonpersistent_flags+=("--external-host-http-vserver=") - flags+=("--external-host-https-vserver=") - local_nonpersistent_flags+=("--external-host-https-vserver=") - flags+=("--external-host-insecure") - local_nonpersistent_flags+=("--external-host-insecure") - flags+=("--external-host-internal-ip=") - local_nonpersistent_flags+=("--external-host-internal-ip=") - flags+=("--external-host-partition-path=") - local_nonpersistent_flags+=("--external-host-partition-path=") - flags+=("--external-host-password=") - local_nonpersistent_flags+=("--external-host-password=") - flags+=("--external-host-private-key=") - local_nonpersistent_flags+=("--external-host-private-key=") - flags+=("--external-host-username=") - local_nonpersistent_flags+=("--external-host-username=") - flags+=("--external-host-vxlan-gw=") - local_nonpersistent_flags+=("--external-host-vxlan-gw=") - flags+=("--force-subdomain=") - local_nonpersistent_flags+=("--force-subdomain=") - flags+=("--host-network") - local_nonpersistent_flags+=("--host-network") - flags+=("--host-ports") - local_nonpersistent_flags+=("--host-ports") - flags+=("--images=") - local_nonpersistent_flags+=("--images=") - flags+=("--labels=") - local_nonpersistent_flags+=("--labels=") - flags+=("--latest-images") - local_nonpersistent_flags+=("--latest-images") - flags+=("--local") - local_nonpersistent_flags+=("--local") - flags+=("--max-connections=") - local_nonpersistent_flags+=("--max-connections=") - flags+=("--mutual-tls-auth=") - local_nonpersistent_flags+=("--mutual-tls-auth=") - flags+=("--mutual-tls-auth-ca=") - local_nonpersistent_flags+=("--mutual-tls-auth-ca=") - flags+=("--mutual-tls-auth-crl=") - local_nonpersistent_flags+=("--mutual-tls-auth-crl=") - flags+=("--mutual-tls-auth-filter=") - local_nonpersistent_flags+=("--mutual-tls-auth-filter=") - flags+=("--output=") - two_word_flags+=("-o") - local_nonpersistent_flags+=("--output=") - flags+=("--output-version=") - local_nonpersistent_flags+=("--output-version=") - flags+=("--ports=") - local_nonpersistent_flags+=("--ports=") - flags+=("--replicas=") - local_nonpersistent_flags+=("--replicas=") - flags+=("--router-canonical-hostname=") - local_nonpersistent_flags+=("--router-canonical-hostname=") - flags+=("--secrets-as-env") - local_nonpersistent_flags+=("--secrets-as-env") - flags+=("--selector=") - local_nonpersistent_flags+=("--selector=") - flags+=("--service-account=") - local_nonpersistent_flags+=("--service-account=") - flags+=("--show-all") - flags+=("-a") - local_nonpersistent_flags+=("--show-all") - flags+=("--show-labels") - local_nonpersistent_flags+=("--show-labels") - flags+=("--sort-by=") - local_nonpersistent_flags+=("--sort-by=") - flags+=("--stats-password=") - local_nonpersistent_flags+=("--stats-password=") - flags+=("--stats-port=") - local_nonpersistent_flags+=("--stats-port=") - flags+=("--stats-user=") - local_nonpersistent_flags+=("--stats-user=") - flags+=("--strict-sni") - local_nonpersistent_flags+=("--strict-sni") - flags+=("--subdomain=") - local_nonpersistent_flags+=("--subdomain=") - flags+=("--template=") - flags_with_completion+=("--template") - flags_completion+=("_filedir") - local_nonpersistent_flags+=("--template=") - flags+=("--threads=") - local_nonpersistent_flags+=("--threads=") - flags+=("--type=") - local_nonpersistent_flags+=("--type=") - flags+=("--as=") - flags+=("--as-group=") - flags+=("--cache-dir=") - flags+=("--certificate-authority=") - flags+=("--client-certificate=") - flags+=("--client-key=") - flags+=("--cluster=") - flags+=("--config=") - flags+=("--context=") - flags+=("--insecure-skip-tls-verify") - flags+=("--kubeconfig=") - flags+=("--loglevel=") - flags+=("--logspec=") - flags+=("--match-server-version") - flags+=("--namespace=") - flags_with_completion+=("--namespace") - flags_completion+=("__oc_get_namespaces") - two_word_flags+=("-n") - flags_with_completion+=("-n") - flags_completion+=("__oc_get_namespaces") - flags+=("--request-timeout=") - flags+=("--server=") - two_word_flags+=("-s") - flags+=("--token=") - flags+=("--user=") - - must_have_one_flag=() - must_have_one_noun=() - noun_aliases=() -} - _oc_adm_taint() { last_command="oc_adm_taint" @@ -5848,6 +5352,54 @@ _oc_adm_uncordon() noun_aliases=() } +_oc_adm_upgrade() +{ + last_command="oc_adm_upgrade" + commands=() + + flags=() + two_word_flags=() + local_nonpersistent_flags=() + flags_with_completion=() + flags_completion=() + + flags+=("--force") + local_nonpersistent_flags+=("--force") + flags+=("--to=") + local_nonpersistent_flags+=("--to=") + flags+=("--to-image=") + local_nonpersistent_flags+=("--to-image=") + flags+=("--as=") + flags+=("--as-group=") + flags+=("--cache-dir=") + flags+=("--certificate-authority=") + flags+=("--client-certificate=") + flags+=("--client-key=") + flags+=("--cluster=") + flags+=("--config=") + flags+=("--context=") + flags+=("--insecure-skip-tls-verify") + flags+=("--kubeconfig=") + flags+=("--loglevel=") + flags+=("--logspec=") + flags+=("--match-server-version") + flags+=("--namespace=") + flags_with_completion+=("--namespace") + flags_completion+=("__oc_get_namespaces") + two_word_flags+=("-n") + flags_with_completion+=("-n") + flags_completion+=("__oc_get_namespaces") + flags+=("--request-timeout=") + flags+=("--server=") + two_word_flags+=("-s") + flags+=("--token=") + flags+=("--user=") + + must_have_one_flag=() + must_have_one_noun=() + noun_aliases=() +} + _oc_adm_verify-image-signature() { last_command="oc_adm_verify-image-signature" @@ -5918,24 +5470,20 @@ _oc_adm() commands+=("create-error-template") commands+=("create-kubeconfig") commands+=("create-login-template") - commands+=("create-node-config") commands+=("create-provider-selection-template") commands+=("drain") commands+=("groups") - commands+=("ipfailover") - commands+=("manage-node") commands+=("migrate") commands+=("new-project") commands+=("options") commands+=("pod-network") commands+=("policy") commands+=("prune") - commands+=("registry") commands+=("release") - commands+=("router") commands+=("taint") commands+=("top") commands+=("uncordon") + commands+=("upgrade") commands+=("verify-image-signature") flags=() diff --git a/pkg/oc/cli/admin/admin.go b/pkg/oc/cli/admin/admin.go index d8aa5a5b0beb..9c64008e9016 100644 --- a/pkg/oc/cli/admin/admin.go +++ b/pkg/oc/cli/admin/admin.go @@ -36,6 +36,7 @@ import ( "github.com/openshift/origin/pkg/oc/cli/admin/release" "github.com/openshift/origin/pkg/oc/cli/admin/router" "github.com/openshift/origin/pkg/oc/cli/admin/top" + "github.com/openshift/origin/pkg/oc/cli/admin/upgrade" "github.com/openshift/origin/pkg/oc/cli/admin/verifyimagesignature" "github.com/openshift/origin/pkg/oc/cli/kubectlwrappers" "github.com/openshift/origin/pkg/oc/cli/options" @@ -59,11 +60,9 @@ func NewCommandAdmin(name, fullName string, f kcmdutil.Factory, streams genericc groups := ktemplates.CommandGroups{ { - Message: "Component Installation:", + Message: "Cluster Management:", Commands: []*cobra.Command{ - router.NewCmdRouter(f, fullName, "router", streams), - ipfailover.NewCmdIPFailoverConfig(f, fullName, "ipfailover", streams), - registry.NewCmdRegistry(f, fullName, "registry", streams), + upgrade.New(f, fullName, streams), release.NewCmd(f, fullName, streams), }, }, @@ -80,8 +79,6 @@ func NewCommandAdmin(name, fullName string, f kcmdutil.Factory, streams genericc { Message: "Node Management:", Commands: []*cobra.Command{ - admin.NewCommandNodeConfig(admin.NodeConfigCommandName, fullName+" "+admin.NodeConfigCommandName, streams), - node.NewCommandManageNode(f, node.ManageNodeCommandName, fullName+" "+node.ManageNodeCommandName, streams), cmdutil.ReplaceCommandName("kubectl", fullName, ktemplates.Normalize(kubecmd.NewCmdCordon(f, streams))), cmdutil.ReplaceCommandName("kubectl", fullName, ktemplates.Normalize(kubecmd.NewCmdUncordon(f, streams))), cmdutil.ReplaceCommandName("kubectl", fullName, kubecmd.NewCmdDrain(f, streams)), @@ -132,6 +129,13 @@ func NewCommandAdmin(name, fullName string, f kcmdutil.Factory, streams genericc admin.NewCommandCreateKeyPair(admin.CreateKeyPairCommandName, fullName+" "+admin.CreateKeyPairCommandName, streams), admin.NewCommandCreateServerCert(admin.CreateServerCertCommandName, fullName+" "+admin.CreateServerCertCommandName, streams), admin.NewCommandCreateSignerCert(admin.CreateSignerCertCommandName, fullName+" "+admin.CreateSignerCertCommandName, streams), + + // these will be removed soon + admin.NewCommandNodeConfig(admin.NodeConfigCommandName, fullName+" "+admin.NodeConfigCommandName, streams), + node.NewCommandManageNode(f, node.ManageNodeCommandName, fullName+" "+node.ManageNodeCommandName, streams), + router.NewCmdRouter(f, fullName, "router", streams), + ipfailover.NewCmdIPFailoverConfig(f, fullName, "ipfailover", streams), + registry.NewCmdRegistry(f, fullName, "registry", streams), } for _, cmd := range deprecatedCommands { // Unsetting Short description will not show this command in help diff --git a/pkg/oc/cli/admin/release/info.go b/pkg/oc/cli/admin/release/info.go index c46a6264a147..a5e7f4e8d502 100644 --- a/pkg/oc/cli/admin/release/info.go +++ b/pkg/oc/cli/admin/release/info.go @@ -20,12 +20,15 @@ import ( "github.com/spf13/cobra" digest "github.com/opencontainers/go-digest" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/duration" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/genericclioptions" imageapi "github.com/openshift/api/image/v1" + configv1client "github.com/openshift/client-go/config/clientset/versioned" "github.com/openshift/origin/pkg/image/apis/image/docker10" imagereference "github.com/openshift/origin/pkg/image/apis/image/reference" "github.com/openshift/origin/pkg/oc/cli/image/extract" @@ -48,7 +51,7 @@ func NewInfo(f kcmdutil.Factory, parentName string, streams genericclioptions.IO Experimental: This command is under active development and may change without notice. `), Run: func(cmd *cobra.Command, args []string) { - kcmdutil.CheckErr(o.Complete(cmd, args)) + kcmdutil.CheckErr(o.Complete(f, cmd, args)) kcmdutil.CheckErr(o.Run()) }, } @@ -71,7 +74,32 @@ type InfoOptions struct { Verify bool } -func (o *InfoOptions) Complete(cmd *cobra.Command, args []string) error { +func (o *InfoOptions) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error { + if len(args) == 0 { + cfg, err := f.ToRESTConfig() + if err != nil { + return fmt.Errorf("info expects one argument, or a connection to a 4.0 OpenShift server: %v", err) + } + client, err := configv1client.NewForConfig(cfg) + if err != nil { + return fmt.Errorf("info expects one argument, or a connection to a 4.0 OpenShift server: %v", err) + } + cv, err := client.Config().ClusterVersions().Get("version", metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return fmt.Errorf("you must be connected to a v4.0 OpenShift server to fetch the current version") + } + return fmt.Errorf("info expects one argument, or a connection to a 4.0 OpenShift server: %v", err) + } + image := cv.Status.Current.Payload + if len(image) == 0 && cv.Spec.DesiredUpdate != nil { + image = cv.Spec.DesiredUpdate.Payload + } + if len(image) == 0 { + return fmt.Errorf("the server is not reporting a release image at this time, please specify an image to view") + } + args = []string{image} + } if len(args) < 1 { return fmt.Errorf("info expects at least one argument, a release image pull spec") } @@ -84,7 +112,7 @@ func (o *InfoOptions) Run() error { return fmt.Errorf("must specify a release image as an argument") } if len(o.From) > 0 && len(o.Images) != 1 { - return fmt.Errorf("must specify a release image as argument when comparing to another release image") + return fmt.Errorf("must specify a single release image as argument when comparing to another release image") } if len(o.From) > 0 { diff --git a/pkg/oc/cli/admin/upgrade/upgrade.go b/pkg/oc/cli/admin/upgrade/upgrade.go new file mode 100644 index 000000000000..169b60db4b89 --- /dev/null +++ b/pkg/oc/cli/admin/upgrade/upgrade.go @@ -0,0 +1,307 @@ +package upgrade + +import ( + "bytes" + "fmt" + "io" + "sort" + "strings" + "text/tabwriter" + + "github.com/blang/semver" + + "github.com/spf13/cobra" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/kubectl/cmd/templates" + kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + "k8s.io/kubernetes/pkg/kubectl/genericclioptions" + + configv1 "github.com/openshift/api/config/v1" + configv1client "github.com/openshift/client-go/config/clientset/versioned" + imagereference "github.com/openshift/library-go/pkg/image/reference" +) + +func NewOptions(streams genericclioptions.IOStreams) *Options { + return &Options{ + IOStreams: streams, + } +} + +func New(f kcmdutil.Factory, parentName string, streams genericclioptions.IOStreams) *cobra.Command { + o := NewOptions(streams) + cmd := &cobra.Command{ + Use: "upgrade --to=VERSION", + Short: "Upgrade a cluster", + Long: templates.LongDesc(` + Upgrade the cluster to a newer version + + This command will request that the cluster begin an upgrade. If no arguments are passed + the command will retrieve the current version info and display whether an upgrade is + in progress or whether any errors might prevent an upgrade, as well as show the suggested + updates available to the cluster. Information about compatible updates is periodically + retrieved from the update server and cached on the cluster - these are updates that are + known to be supported as upgrades from the current version. + + Passing --to=VERSION will upgrade the cluster to one of the available updates or report + an error if no such version exists. The cluster will then upgrade itself and report + status that is available via "oc get clusterversion" and "oc describe clusterversion". + + If the cluster is already being upgrade, or the cluster version has a failing or invalid + state you may pass --force to continue the upgrade anyway. + + If there are no versions available, or a bug in the cluster version operator prevents + updates from being retrieved, the more powerful and dangerous --to-image=IMAGE option + may be used. This forces the cluster to upgrade to the contents of the specified release + image, regardless of whether that upgrade is safe to apply to the current version. While + rolling back to a previous micro version (4.0.2 -> 4.0.1) may be safe, upgrading more + than one minor version ahead (4.0 -> 4.2) or downgrading one minor version (4.1 -> 4.0) + is likely to cause data corruption or to completely break a cluster. + + Experimental: This command is under active development and may change without notice. + `), + Run: func(cmd *cobra.Command, args []string) { + kcmdutil.CheckErr(o.Complete(f, cmd, args)) + kcmdutil.CheckErr(o.Run()) + }, + } + flags := cmd.Flags() + flags.StringVar(&o.To, "to", o.To, "Specify the version to upgrade to. The version must be on the list of previous or available updates.") + flags.StringVar(&o.ToImage, "to-image", o.ToImage, "Provide a release image to upgrade to. WARNING: This option does not check for upgrade compatibility and may break your cluster.") + flags.BoolVar(&o.Force, "force", o.Force, "Upgrade even if an upgrade is in process or other error is blocking update.") + return cmd +} + +type Options struct { + genericclioptions.IOStreams + + To string + ToImage string + + Force bool + + Client configv1client.Interface +} + +func (o *Options) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error { + if len(o.To) > 0 && len(o.ToImage) > 0 { + return fmt.Errorf("only one of --to or --to-image may be provided") + } + + if len(o.To) > 0 { + if _, err := semver.Parse(o.To); err != nil { + return fmt.Errorf("--to must be a semantic version (e.g. 4.0.1 or 4.1.0-nightly-20181104): %v", err) + } + } + // defend against simple mistakes (4.0.1 is a valid docker image) + if len(o.ToImage) > 0 { + ref, err := imagereference.Parse(o.ToImage) + if err != nil { + return fmt.Errorf("--to-image must be a valid image pull spec: %v", err) + } + if len(ref.Registry) == 0 && len(ref.Namespace) == 0 { + return fmt.Errorf("--to-image must be a valid image pull spec: no registry or repository specified") + } + if len(ref.ID) == 0 && len(ref.Tag) == 0 { + return fmt.Errorf("--to-image must be a valid image pull spec: no tag or digest specified") + } + } + + cfg, err := f.ToRESTConfig() + if err != nil { + return err + } + client, err := configv1client.NewForConfig(cfg) + if err != nil { + return err + } + o.Client = client + return nil +} + +func (o *Options) Run() error { + cv, err := o.Client.Config().ClusterVersions().Get("version", metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return fmt.Errorf("No cluster version information available - you must be connected to a v4.0 OpenShift server to fetch the current version") + } + return err + } + + switch { + case len(o.To) > 0, len(o.ToImage) > 0: + var update *configv1.Update + if len(o.To) > 0 { + for _, available := range cv.Status.AvailableUpdates { + if available.Version == o.To { + update = &available + break + } + } + if update == nil { + if len(cv.Status.AvailableUpdates) == 0 { + if c := findCondition(cv.Status.Conditions, configv1.RetrievedUpdates); c != nil && c.Status == configv1.ConditionFalse { + return fmt.Errorf("Can't look up image for version %s. %v", o.To, c.Message) + } + return fmt.Errorf("No available updates, specify --to-image or wait for new updates to be available") + } + return fmt.Errorf("The update %s is not one of the available updates: %s", o.To, strings.Join(versionStrings(cv.Status.AvailableUpdates), ", ")) + } + } + if len(o.ToImage) > 0 { + update = &configv1.Update{ + Version: "", + Payload: o.ToImage, + } + } + + if !o.Force { + if err := checkForUpgrade(cv); err != nil { + return err + } + } + + cv.Spec.DesiredUpdate = update + + _, err := o.Client.Config().ClusterVersions().Update(cv) + if err != nil { + return fmt.Errorf("Unable to upgrade: %v", err) + } + + if len(update.Version) > 0 { + fmt.Fprintf(o.Out, "Updating to %s\n", update.Version) + } else { + fmt.Fprintf(o.Out, "Updating to release image %s\n", update.Payload) + } + + return nil + + default: + if c := findCondition(cv.Status.Conditions, configv1.OperatorFailing); c != nil && c.Status == configv1.ConditionTrue { + prefix := "No upgrade is possible due to an error" + if c := findCondition(cv.Status.Conditions, configv1.OperatorProgressing); c != nil && c.Status == configv1.ConditionTrue && len(c.Message) > 0 { + prefix = c.Message + } + if len(c.Message) > 0 { + return fmt.Errorf("%s:\n\n Reason: %s\n Message: %s\n\n", prefix, c.Reason, c.Message) + } + return fmt.Errorf("The cluster can't be upgraded, see `oc describe clusterversion`") + } + + if c := findCondition(cv.Status.Conditions, configv1.OperatorProgressing); c != nil && len(c.Message) > 0 { + if c.Status == configv1.ConditionTrue { + fmt.Fprintf(o.Out, "info: An upgrade is in progress. %s\n", c.Message) + } else { + fmt.Fprintln(o.Out, c.Message) + } + } else { + fmt.Fprintln(o.ErrOut, "warning: No current status info, see `oc describe clusterversion` for more details") + } + fmt.Fprintln(o.Out) + + if len(cv.Status.AvailableUpdates) > 0 { + fmt.Fprintf(o.Out, "Updates:\n\n") + w := tabwriter.NewWriter(o.Out, 0, 2, 1, ' ', 0) + fmt.Fprintf(w, "VERSION\tIMAGE\n") + // TODO: add metadata about version + for _, update := range cv.Status.AvailableUpdates { + fmt.Fprintf(w, "%s\t%s\n", update.Version, update.Payload) + } + w.Flush() + if c := findCondition(cv.Status.Conditions, configv1.RetrievedUpdates); c != nil && c.Status == configv1.ConditionFalse { + fmt.Fprintf(o.ErrOut, "warning: Cannot refresh available updates:\n Reason: %s\n Message: %s\n\n", c.Reason, c.Message) + } + } else { + if c := findCondition(cv.Status.Conditions, configv1.RetrievedUpdates); c != nil && c.Status == configv1.ConditionFalse { + fmt.Fprintf(o.ErrOut, "warning: Cannot display available updates:\n Reason: %s\n Message: %s\n\n", c.Reason, c.Message) + } else { + fmt.Fprintf(o.Out, "No updates available. You may force an upgrade to a specific release image, but doing so may not be supported and result in downtime or data loss.\n") + } + } + + // TODO: print previous versions + } + + return nil +} + +func errorList(errs []error) string { + if len(errs) == 1 { + return errs[0].Error() + } + buf := &bytes.Buffer{} + fmt.Fprintf(buf, "\n\n") + for _, err := range errs { + fmt.Fprintf(buf, "* %v\n", err) + } + return buf.String() +} + +func stringArrContains(arr []string, s string) bool { + for _, item := range arr { + if item == s { + return true + } + } + return false +} + +func writeTabSection(out io.Writer, fn func(w io.Writer)) { + w := tabwriter.NewWriter(out, 0, 4, 1, ' ', 0) + fn(w) + w.Flush() +} + +func sortSemanticVersions(versions []configv1.Update) { + sort.Slice(versions, func(i, j int) bool { + a, errA := semver.Parse(versions[i].Version) + b, errB := semver.Parse(versions[j].Version) + if errA == nil && errB != nil { + return true + } + if errB == nil && errA == nil { + return false + } + if errA != nil && errB != nil { + if versions[i].Version < versions[j].Version { + return true + } + return false + } + if a.Compare(b) < 0 { + return true + } + return false + }) +} + +func versionStrings(updates []configv1.Update) []string { + var arr []string + for _, update := range updates { + arr = append(arr, update.Version) + } + return arr +} + +func findCondition(conditions []configv1.ClusterOperatorStatusCondition, name configv1.ClusterStatusConditionType) *configv1.ClusterOperatorStatusCondition { + for i := range conditions { + if conditions[i].Type == name { + return &conditions[i] + } + } + return nil +} + +func checkForUpgrade(cv *configv1.ClusterVersion) error { + if c := findCondition(cv.Status.Conditions, "Invalid"); c != nil && c.Status == configv1.ConditionTrue { + return fmt.Errorf("The cluster version object is invalid, you must correct the invalid state first. %v", c.Message) + } + if c := findCondition(cv.Status.Conditions, configv1.OperatorFailing); c != nil && c.Status == configv1.ConditionTrue { + return fmt.Errorf("The cluster is experiencing an error preventing upgrade, use --force to upgrade anyway. %v", c.Message) + } + if c := findCondition(cv.Status.Conditions, configv1.OperatorProgressing); c != nil && c.Status == configv1.ConditionTrue { + return fmt.Errorf("Already upgrading, pass --force to override. %v", c.Message) + } + return nil +}