kubectl源码分析之convert
Posted 1994july
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubectl源码分析之convert相关的知识,希望对你有一定的参考价值。
发布一个k8s部署视频:https://edu.csdn.net/course/detail/26967
课程内容:各种k8s部署方式。包括minikube部署,kubeadm部署,kubeasz部署,rancher部署,k3s部署。包括开发测试环境部署k8s,和生产环境部署k8s。
腾讯课堂连接地址https://ke.qq.com/course/478827?taid=4373109931462251&tuin=ba64518
第二个视频发布 https://edu.csdn.net/course/detail/27109
腾讯课堂连接地址https://ke.qq.com/course/484107?tuin=ba64518
介绍主要的k8s资源的使用配置和命令。包括configmap,pod,service,replicaset,namespace,deployment,daemonset,ingress,pv,pvc,sc,role,rolebinding,clusterrole,clusterrolebinding,secret,serviceaccount,statefulset,job,cronjob,podDisruptionbudget,podSecurityPolicy,networkPolicy,resourceQuota,limitrange,endpoint,event,conponentstatus,node,apiservice,controllerRevision等。
第三个视频发布:https://edu.csdn.net/course/detail/27574
详细介绍helm命令,学习helm chart语法,编写helm chart。深入分析各项目源码,学习编写helm插件
第四个课程发布:https://edu.csdn.net/course/detail/28488
本课程将详细介绍k8s所有命令,以及命令的go源码分析,学习知其然,知其所以然
————————————————
type ConvertOptions struct {//convert结构体
PrintFlags *genericclioptions.PrintFlags
Printer printers.ResourcePrinter
OutputVersion string
Namespace string
builder func() *resource.Builder
local bool
validator func() (validation.Schema, error)
resource.FilenameOptions
genericclioptions.iostreams
}
func NewConvertOptions(ioStreams genericclioptions.IOStreams) *ConvertOptions {
return &ConvertOptions{//初始化convert结构体
PrintFlags: genericclioptions.NewPrintFlags("converted").WithTypeSetter(scheme.Scheme).WithDefaultOutput("yaml"),
local: true,
IOStreams: ioStreams,
}
}
//创建convert命令
func NewCmdConvert(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewConvertOptions(ioStreams)//初始化结构体
cmd := &cobra.Command{//创建cobra命令
Use: "convert -f FILENAME",
DisableFlagsInUseLine: true,
Short: i18n.T("Convert config files between different API versions"),
Long: convertLong,
Example: convertExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(o.Complete(f, cmd))//准备
cmdutil.CheckErr(o.RunConvert())//运行
},
}
cmd.Flags().BoolVar(&o.local, "local", o.local, "If true, convert will NOT try to contact api-server but run locally.")//local选项
cmd.Flags().StringVar(&o.OutputVersion, "output-version", o.OutputVersion, i18n.T("Output the formatted object with the given group version (for ex: ‘extensions/v1beta1‘)."))//output-version选项
o.PrintFlags.AddFlags(cmd)//打印选项
cmdutil.AddValidateFlags(cmd)//校验选项
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "to need to get converted.")//文件选项
return cmd
}
//准备
func (o *ConvertOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) (err error) {
err = o.FilenameOptions.RequireFilenameOrKustomize()//文件是必须的
if err != nil {
return err
}
o.builder = f.NewBuilder//设置builder
o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace()//设置namespace
if err != nil {
return err
}
o.validator = func() (validation.Schema, error) {//设置schemaValidator
return f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
}
// build the printer
o.Printer, err = o.PrintFlags.ToPrinter()//printflag转printer
if err != nil {
return err
}
return nil
}
//运行
func (o *ConvertOptions) RunConvert() error {
// Convert must be removed from kubectl, since kubectl can not depend on
// Kubernetes "internal" dependencies. These "internal" dependencies can
// not be removed from convert. Another way to convert a resource is to
// "kubectl apply" it to the cluster, then "kubectl get" at the desired version.
// Another possible solution is to make convert a plugin.
fmt.Fprintf(o.ErrOut, "kubectl convert is DEPRECATED and will be removed in a future version.
In order to convert, kubectl apply the object to the cluster, then kubectl get at the desired version.
")//打印deprecated提示
b := o.builder().
WithScheme(scheme.Scheme).
LocalParam(o.local)
if !o.local {
schema, err := o.validator()
if err != nil {
return err
}
b.Schema(schema)
}
r := b.NamespaceParam(o.Namespace).
ContinueOnError().
FilenameParam(false, &o.FilenameOptions).
Flatten().
Do()//用builder构造result对象
err := r.Err()
if err != nil {
return err
}
singleItemImplied := false
infos, err := r.IntoSingleItemImplied(&singleItemImplied).Infos()//获取infos
if err != nil {
return err
}
if len(infos) == 0 {//info为0个返回错误
return fmt.Errorf("no objects passed to convert")
}
var specifiedOutputVersion schema.GroupVersion
if len(o.OutputVersion) > 0 {//如果指定了output-version
specifiedOutputVersion, err = schema.ParseGroupVersion(o.OutputVersion)//解析output-version
if err != nil {
return err
}
}
internalEncoder := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)//获取codec
internalVersionJSONEncoder := unstructured.JSONFallbackEncoder{Encoder: internalEncoder}//构造json encoder
objects, err := asVersionedObject(infos, !singleItemImplied, specifiedOutputVersion, internalVersionJSONEncoder)//转换对象
if err != nil {
return err
}
return o.Printer.PrintObj(objects, o.Out)//打印结果
}
//转换对象
func asVersionedObject(infos []*resource.Info, forceList bool, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) (runtime.Object, error) {
objects, err := asVersionedObjects(infos, specifiedOutputVersion, encoder)//转换对象
if err != nil {
return nil, err
}
var object runtime.Object
if len(objects) == 1 && !forceList {//如果结果是1个对象,不是forceList
object = objects[0]
} else {
object = &api.List{Items: objects}//把对象包装成list
targetVersions := []schema.GroupVersion{}
if !specifiedOutputVersion.Empty() {//specifiedOutputVersion非空
targetVersions = append(targetVersions, specifiedOutputVersion)//append version
}
targetVersions = append(targetVersions, schema.GroupVersion{Group: "", Version: "v1"})//append version
converted, err := tryConvert(scheme.Scheme, object, targetVersions...)//尝试转换
if err != nil {
return nil, err
}
object = converted
}
actualVersion := object.GetObjectKind().GroupVersionKind()//获取对象实际的version
if actualVersion.Version != specifiedOutputVersion.Version {//如果对象实际version不等于指定的version
defaultVersionInfo := ""
if len(actualVersion.Version) > 0 {//实际version非空,设置打印消息
defaultVersionInfo = fmt.Sprintf("Defaulting to %q", actualVersion.Version)
}
klog.V(1).Infof("info: the output version specified is invalid. %s
", defaultVersionInfo)//输出klog日志
}
return object, nil//返回对象
}
//转换对象
func asVersionedObjects(infos []*resource.Info, specifiedOutputVersion schema.GroupVersion, encoder runtime.Encoder) ([]runtime.Object, error) {
objects := []runtime.Object{}
for _, info := range infos {//遍历infos
if info.Object == nil {//info的object为空继续
continue
}
targetVersions := []schema.GroupVersion{}//构造目标version slice
// objects that are not part of api.Scheme must be converted to JSON
// TODO: convert to map[string]interface{}, attach to runtime.Unknown?
if !specifiedOutputVersion.Empty() {//指定的version非空
if _, _, err := scheme.Scheme.ObjectKinds(info.Object); runtime.IsNotRegisteredError(err) {//获取对象kind,如果是IsNotRegisteredError错误
// TODO: ideally this would encode to version, but we don‘t expose multiple codecs here.
data, err := runtime.Encode(encoder, info.Object)//encode对象
if err != nil {
return nil, err
}
// TODO: Set ContentEncoding and ContentType.
objects = append(objects, &runtime.Unknown{Raw: data})//追加objects,继续
continue
}
targetVersions = append(targetVersions, specifiedOutputVersion)//追加目标vesions
} else {//如果版本没指定
gvks, _, err := scheme.Scheme.ObjectKinds(info.Object)//获取对象kinds
if err == nil {
for _, gvk := range gvks {
targetVersions = append(targetVersions, scheme.Scheme.PrioritizedVersionsForGroup(gvk.Group)...)//追加目标versions
}
}
}
converted, err := tryConvert(scheme.Scheme, info.Object, targetVersions...)//尝试convert
if err != nil {
return nil, err
}
objects = append(objects, converted)//追加对象
}
return objects, nil//返回对象
}
//尝试转换
func tryConvert(converter runtime.ObjectConvertor, object runtime.Object, versions ...schema.GroupVersion) (runtime.Object, error) {
var last error
for _, version := range versions {//遍历目标版本
if version.Empty() {//如果版本为空,直接返回对象
return object, nil
}
obj, err := converter.ConvertToVersion(object, version)//转换对象到某个版本
if err != nil {//有错误继续
last = err
continue
}
return obj, nil//返回对象
}
return nil, last//返回错误
}
西部数据黑盘是什么,西部数据Black™ NVMe™ M.2固态硬盘评测
以上是关于kubectl源码分析之convert的主要内容,如果未能解决你的问题,请参考以下文章
Android 插件化VirtualApp 源码分析 ( 目前的 API 现状 | 安装应用源码分析 | 安装按钮执行的操作 | 返回到 HomeActivity 执行的操作 )(代码片段
Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段
Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段
[TIA PORTAL][CONVERT] Convert Char Array to DInt...DInt to Char Array..Useful and easy function(代码片段