• Cobbler 服务搭建及Cobbler api 使用


     

    Cobbler: 是一个 Linux服务器快速网络安装的工具,由python 开发

    本人开源代码: I夏/CMDB

    cobbler 提供了命令行和api进行管理

    1. cobbler check 核对当前设置是否有问题
    2. cobbler list 列出所有的cobbler元素
    3. cobbler report 列出元素的详细信息
    4. cobbler sync 同步配置到数据目录,更改配置最好都要执行下
    5. cobbler reposync 同步yum仓库
    6. cobbler distro 查看导入的发行版系统信息
    7. cobbler system 查看添加的系统信息
    8. cobbler profile 查看配置信息

    环境:centos7.2 mini x64

    ip: 192.168.5.50

    需要确保epel源已经安装成功

    1. 安装

    yum -y install httpd dhcp tftp python-ctypes cobbler  xinetd cobbler-web
    2.启动服务
    1. systemctl start httpd
    2. systemctl enable httpd
    3. systemctl start cobblerd
    4. systemctl enable cobblerd

    3.检查cobbler 配置是否正常

    1. [root@cobbler ~]# cobbler check
    2. The following are potential configuration items that you may want to fix:
    3. 1 : The 'server' field in /etc/cobbler/settings must be set to something other than localhost, or kickstarting features will not work.  This should be a resolvable hostname or IP for the boot server as reachable by all machines that will use it.
    4. 2 : For PXE to be functional, the 'next_server' field in /etc/cobbler/settings must be set to something other than 127.0.0.1, and should match the IP of the boot server on the PXE network.
    5. 3 : change 'disable' to 'no' in /etc/xinetd.d/tftp
    6. 4 : Some network boot-loaders are missing from /var/lib/cobbler/loaders, you may run 'cobbler get-loaders' to download them, or, if you only want to handle x86/x86_64 netbooting, you may ensure that you have installed a *recent* version of the syslinux package installed and can ignore this message entirely.  Files in this directory, should you want to support all architectures, should include pxelinux.0, menu.c32, elilo.efi, and yaboot. The 'cobbler get-loaders' command is the easiest way to resolve these requirements.
    7. 5 : enable and start rsyncd.service with systemctl
    8. 6 : debmirror package is not installed, it will be required to manage debian deployments and repositories
    9. 7 : ksvalidator was not found, install pykickstart
    10. 8 : The default password used by the sample templates for newly installed machines (default_password_crypted in /etc/cobbler/settings) is still set to 'cobbler' and should be changed, try: "openssl passwd -1 -salt 'random-phrase-here' 'your-password-here'" to generate new one
    11. 9 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them
    12. Restart cobblerd and then run 'cobbler sync' to apply changes.

    我们需要解决这些警告

    问题1,告诉我们 server 这个字段的值应该是一个地址不要写本地地址,因为我们是对外访问的,最后将这个字段修改为服务的ip

    sed -i 's/^server: 127.0.0.1/server: 192.168.5.50/' /etc/cobbler/settings

    问题2,next_server 该字段为pxe服务器的字段,不要设置为127.0.0.1,最好设置为自己服务器的ip

    sed -i 's/^next_server: 127.0.0.1/next_server: 192.168.5.50/' /etc/cobbler/settings # pxe服务器 即 TFTP Server 的IP地址

    问题3,cobbler服务需要tftp 服务启动,需要将 tftp 的disable 的值修改为no

    1. [root@cobbler ~]# cat /etc/xinetd.d/tftp
    2. # default: off
    3. # description: The tftp server serves files using the trivial file transfer \
    4. # protocol.  The tftp protocol is often used to boot diskless \
    5. # workstations, download configuration files to network-aware printers, \
    6. # and to start the installation process for some operating systems.
    7. service tftp
    8. {
    9. socket_type = dgram
    10. protocol = udp
    11. waityes
    12. user = root
    13. server = /usr/sbin/in.tftpd
    14. server_args = -s /var/lib/tftpboot
    15. disable = no    #默认是yes,需要修改为no
    16. per_source = 11
    17. cps = 100 2
    18. flags = IPv4
    19. }

    问题4,boot-loaders 在本地或许不存在,需要通过 命令 cobbler get-loaders 下载

    1. [root@cobbler ~]# cobbler get-loaders
    2. task started: 2018-12-04_095358_get_loaders
    3. task started (id=Download Bootloader Content, time=Tue Dec  4 09:53:58 2018)
    4. downloading https://cobbler.github.io/loaders/README to /var/lib/cobbler/loaders/README
    5. downloading https://cobbler.github.io/loaders/COPYING.elilo to /var/lib/cobbler/loaders/COPYING.elilo
    6. downloading https://cobbler.github.io/loaders/COPYING.yaboot to /var/lib/cobbler/loaders/COPYING.yaboot
    7. downloading https://cobbler.github.io/loaders/COPYING.syslinux to /var/lib/cobbler/loaders/COPYING.syslinux
    8. downloading https://cobbler.github.io/loaders/elilo-3.8-ia64.efi to /var/lib/cobbler/loaders/elilo-ia64.efi
    9. downloading https://cobbler.github.io/loaders/yaboot-1.3.17 to /var/lib/cobbler/loaders/yaboot
    10. downloading https://cobbler.github.io/loaders/pxelinux.0-3.86 to /var/lib/cobbler/loaders/pxelinux.0
    11. downloading https://cobbler.github.io/loaders/menu.c32-3.86 to /var/lib/cobbler/loaders/menu.c32
    12. downloading https://cobbler.github.io/loaders/grub-0.97-x86.efi to /var/lib/cobbler/loaders/grub-x86.efi
    13. downloading https://cobbler.github.io/loaders/grub-0.97-x86_64.efi to /var/lib/cobbler/loaders/grub-x86_64.efi
    14. *** TASK COMPLETE ***

    问题5,是 rsyncd 服务开机自动启动

    1. [root@cobbler ~]# systemctl enable rsyncd
    2. Created symlink from /etc/systemd/system/multi-user.target.wants/rsyncd.service to /usr/lib/systemd/system/rsyncd.service.

    问题6,这个和debian 有关系,目测用不到,一些企业大部分用redhat 或者centos系统

    问题7,ksvalidator没有找到,让安装 pykickstart

    [root@cobbler ~]# yum install -y pykickstart

    问题8,模板的默认密码是 cobbler,最好重新设置一些,要不要安装系统的默认密码就是cobbler,可以 通过 openssl passwd 进行设置

    1. [root@cobbler ~]# [root@cobbler ~]# openssl passwd -1 -salt 'ilove' 'nineven'     # ilove 是随机盐   nineven 是密码
    2. $1$ilove$A0hokoomR0W702oHUi1OT0
    3. #这个字段 default_password_crypted 将生成的密码替换
    4. [root@cobbler ~]# grep '^default_password_crypted' /etc/cobbler/settings
    5. default_password_crypted: "$1$ilove$A0hokoomR0W702oHUi1OT0"

    重新检查错误

    1. [root@cobbler ~]# systemctl restart cobblerd
    2. [root@cobbler ~]# cobbler check
    3. The following are potential configuration items that you may want to fix:
    4. 1 : debmirror package is not installed, it will be required to manage debian deployments and repositories
    5. 2 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them
    6. Restart cobblerd and then run 'cobbler sync' to apply changes

    这两个错误可以忽略

    4.配置cobbler 直接接管dhcp服务

    1. [root@cobbler ~]# vim /etc/cobbler/settings 
    2. [root@cobbler ~]# grep '^manage_dhcp' /etc/cobbler/settings
    3. manage_dhcp: 1

    配置dhcp模板

    1. [root@cobbler ~]# vim /etc/cobbler/dhcp.template
    2. ddns-update-style interim;
    3. allow booting;
    4. allow bootp;
    5. deny unknown-clients; # 开启白名单默认,拒绝其他客户端,默认没有,需要单独添加
    6. ignore client-updates;
    7. set vendorclass = option vendor-class-identifier;
    8. option pxe-system-type code 93 = unsigned integer 16;
    9. subnet 192.168.5.0 netmask 255.255.255.0 {
    10.      option routers             192.168.5.1;
    11.      option domain-name-servers 192.168.5.1;
    12.      option subnet-mask         255.255.255.0;
    13.      range dynamic-bootp        192.168.5.10 192.168.5.50;
    14.      
    15.      #仅列出部分

    5.配置只安装一次,要不然,会出现重复安装系统

    1. [root@cobbler ~]# vim /etc/cobbler/settings 
    2. [root@cobbler ~]# grep '^pxe_just_once' /etc/cobbler/settings
    3. pxe_just_once: 1

        修改settings 配置文件之后,需要重启cobblerd 服务,使之生效

    1. [root@cobbler ~]# systemctl restart cobblerd
    2. [root@cobbler ~]# cobbler sync
     
    

    6,导入系统:

    可以发现现在,所有都是空的,

    1. [root@cobbler ~]# cobbler list
    2. distros:
    3. profiles:
    4. systems:
    5. repos:
    6. images:
    7. mgmtclasses:
    8. packages:
    9. files:

    通过 cobbler import 导入系统

    a,先挂载系统,可以通过光驱挂载,也可以将镜像传到本地,然后进行挂载,我是通过上传镜像进行挂载的

    1. [root@cobbler ~]# mount /root/CentOS-7-x86_64-Minimal-1511.iso /mnt/
    2. mount: /dev/loop0 is write-protected, mounting read-only
    3. [root@cobbler ~]# cobbler import --path=/mnt/ --name=CentOS-7-x86_64-Minimal-1511 --arch=x86_64
    4. task started: 2018-12-04_102336_import
    5. task started (id=Media import, time=Tue Dec  4 10:23:36 2018)
    6. Found a candidate signature: breed=redhat, version=rhel6
    7. Found a candidate signature: breed=redhat, version=rhel7
    8. Found a matching signature: breed=redhat, version=rhel7
    9. Adding distros from path /var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64:
    10. creating new distro: CentOS-7-Minimal-1511-x86_64
    11. trying symlink: /var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64 -> /var/www/cobbler/links/CentOS-7-Minimal-1511-x86_64
    12. creating new profile: CentOS-7-Minimal-1511-x86_64
    13. associating repos
    14. checking for rsync repo(s)
    15. checking for rhn repo(s)
    16. checking for yum repo(s)
    17. starting descent into /var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64 for CentOS-7-Minimal-1511-x86_64
    18. processing repo at : /var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64
    19. need to process repo/comps: /var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64
    20. looking for /var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64/repodata/*comps*.xml
    21. Keeping repodata as-is :/var/www/cobbler/ks_mirror/CentOS-7-x86_64-Minimal-1511-x86_64/repodata
    22. *** TASK COMPLETE ***

    通过cobbler list 查询信息

    1. [root@cobbler ~]# cobbler list
    2. distros:
    3.    CentOS-7-Minimal-1511-x86_64
    4. profiles:
    5.    CentOS-7-Minimal-1511-x86_64
    6. systems:
    7. repos:
    8. images:
    9. mgmtclasses:
    10. packages:
    11. files:

    Cobbler 服务已经搭建好了

    Cobbler API

    关于api的一些方法,可以查看 

    /usr/lib/python2.7/site-packages/cobbler

    该目录下的remote.py 文件

    需要在cobbler 服务端的 /usr/bin/cobblerd  文件的 import 下一行增加

    1. reload(sys)
    2. sys.setdefaultencoding('utf8')

    解决ks内容出现中文的bug

    既然有API了,那么我们就可以通过web页面调用这个api ,通过页面添加安装系统任务

    具体代码请看 https://gitee.com/nineven/CMDB

    二,Cobbler API

    需要先安装好cobbler服务

    1. #!/usr/bin/env python
    2. # -*- coding:utf-8 -*-
    3. # author : liuyu
    4. # date : 2018/11/19 0019
    5. import xmlrpc.client,time,os
    6. '''
    7. 需要在cobbler 服务端的 /usr/bin/cobblerd  文件的 import 下一行增加
    8. reload(sys)
    9. sys.setdefaultencoding('utf8')
    10. 解决ks内容出现中文的bug
    11. '''
    12. class CobblerApi(object):
    13.     def __init__(self,server,user,passwd):
    14.         self.server = server
    15.         self.user = user
    16.         self.passwd = passwd
    17.         self.token = ''
    18.         self.__get_token()
    19.     def __call__(self, *args, **kwargs):
    20.         self.__sync_cobbler()
    21.         print("1223333333333333333")
    22.         self.remote_server.logout(self.token)
    23.     def end(self):
    24.         self.remote_server.logout(self.token)
    25.     def is_kickstart_in_use(self,name):
    26.         return self.remote_server.is_kickstart_in_use(name)
    27.     def is_snippets_in_use(self,name,kickstart_templates):
    28.         snsname = os.path.basename(name)
    29.         snsname="$SNIPPET('{}')".format(snsname)
    30.         for ks in kickstart_templates:
    31.             # print(ks.get("kickstart"))
    32.             context = self.read_or_write_kickstart_template(ks.get("kickstart"),"",True)
    33.             if snsname in context:
    34.                 return True,kickstart_templates
    35.         return False,kickstart_templates
    36.     '''
    37.     通过list 的格式返回每个类别的名称
    38.     '''
    39.     def __check_token(self):
    40.         return self.remote_server.token_check(self.token)
    41.     def __get_token(self):
    42.         try:
    43.             self.remote_server = xmlrpc.client.Server("http://{}/cobbler_api".format(self.server))
    44.             self.token = self.remote_server.login(self.user, self.passwd)
    45.         except Exception as e:
    46.             print(e)
    47.             return ('URL:%s no access' % self.server)
    48.     def find_distros(self):
    49.         return self.remote_server.find_distro()
    50.     def find_profiles(self):
    51.         return self.remote_server.find_profile()
    52.     def find_system(self):
    53.         return self.remote_server.find_system()
    54.     '''
    55.     通过list 的格式返回每个名称的详细信息
    56.     '''
    57.     def get_distros(self,name):
    58.         return self.remote_server.get_distro(name)
    59.     def get_profiles(self,name):
    60.         return self.remote_server.get_profile(name)
    61.     def get_system(self,name):
    62.         return self.remote_server.get_system(name)
    63.     '''
    64.     删除
    65.     '''
    66.     # prof_id = remote_server.new_profile(token)  # 创建一个新的profile 并保存
    67.     def remove_profile(self,name):
    68.         self.remote_server.remove_profile(name,self.token)
    69.         self.__sync_cobbler()
    70.     def remove_distros(self,name):
    71.         self.remote_server.remove_distro(name,self.token)
    72.         self.__sync_cobbler()
    73.     def remove_system(self,name):
    74.         print(name)
    75.         self.remote_server.remove_system(name,self.token)
    76.         self.__sync_cobbler()
    77.     '''
    78.     修改
    79.     '''
    80.     def modify_profile(self,name,key,value):
    81.         object_id = self.remote_server.get_profile_handle(name, self.token)
    82.         # remote_server.modify_profile(prof_id,'name','vm_test1',token) # 修改prof_id指定的profile 名称
    83.         # remote_server.modify_profile(prof_id,'distro','centos6.8-x86_64',token)  # 也是修改prof_id的信息
    84.         # remote_server.modify_profile(object_id, 'kickstart', '/var/lib/cobbler/kickstarts/sample_end.ks', token)
    85.         try:
    86.             self.remote_server.modify_profile(object_id, key, value, self.token)
    87.             self.remote_server.save_profile(object_id, self.token)  # 保存
    88.             self.__sync_cobbler()
    89.         except Exception as e:
    90.             return e
    91.     def modify_system(self,name,key,value):
    92.         object_id = self.remote_server.get_system_handle(name, self.token)
    93.         try:
    94.             self.remote_server.modify_system(object_id, key, value, self.token)
    95.             self.remote_server.save_system(object_id, self.token)  # 保存
    96.             self.__sync_cobbler()
    97.         except Exception as e:
    98.             return e
    99.     def modify_distros(self,name,key,value):
    100.         object_id = self.remote_server.get_distros_handle(name, self.token)
    101.         try:
    102.             self.remote_server.modify_distros(object_id, key, value, self.token)
    103.             self.remote_server.save_distros(object_id, self.token)  # 保存
    104.             self.__sync_cobbler()
    105.         except Exception as e:
    106.             return e
    107.     '''
    108.     获取ks和sns 的文件列表
    109.     '''
    110.     def get_kickstart_templates(self):
    111.         kickstartlist =[]
    112.         for ks in self.remote_server.get_kickstart_templates():
    113.             if ks.startswith('/'):
    114.                 if self.is_kickstart_in_use(ks):
    115.                     status="in-use"
    116.                 else:
    117.                     status = "not-in-use"
    118.                 kickstartlist.append({"kickstart":ks,"status":status})
    119.         return kickstartlist
    120.     def get_snippets(self):
    121.         snippetslist =[]
    122.         kickstart_templates=self.get_kickstart_templates()
    123.         for sns in self.remote_server.get_snippets():
    124.             if sns.startswith('/'):
    125.                 status,kickstart_templates=self.is_snippets_in_use(sns,kickstart_templates)
    126.                 if status:
    127.                     status="in-use"
    128.                 else:
    129.                     status = "not-in-use"
    130.                 snippetslist.append({"snippets":sns,"status":status})
    131.         return snippetslist
    132.     # 同步cobbler修改后的信息,这个做任何操作后,都要必须有
    133.     def __sync_cobbler(self):
    134.         return self.remote_server.sync(self.token) # 同步cobbler修改后的信息,这个做任何操作后,都要必须有
    135.     '''
    136.     填写ks模板
    137.         # print(remote_server.read_or_write_kickstart_template('/var/lib/cobbler/kickstarts/1234.ks',False,'123\ndead\tdd\nda',token))
    138.         替换KS字符串如果为-1,将删除此Ks文件,条件是此ks文件已不在引用
    139.     '''
    140.     def read_or_write_kickstart_template(self,filename,context,read=False):
    141.         fullfilepath = os.path.join('/var/lib/cobbler/kickstarts/',filename)
    142.         #not self.remote_server.is_kickstart_in_use(fullfilepath) and
    143.         if not os.path.exists(fullfilepath):
    144.             return self.remote_server.read_or_write_kickstart_template(fullfilepath,read,context,self.token)
    145.         else:
    146.             return "The kickstart is exists"
    147.     '''
    148.     填写sns模板
    149.      # print(remote_server.read_or_write_snippet('/var/lib/cobbler/snippets/test1',False,'zhaoyong_test',token)) # 在snippgets下建立脚本文件
    150.     '''
    151.     def read_or_write_snippet(self,filename,context,read=False):
    152.         fullfilepath = os.path.join('/var/lib/cobbler/snippets/',filename)
    153.         if not os.path.exists(fullfilepath):
    154.             return self.remote_server.read_or_write_snippet(fullfilepath,read,context,self.token)
    155.         else:
    156.             return "The snippet is exists"
    157.     '''
    158.     增加新的system
    159.     '''
    160.     def create_or_update_system(self,name,mac,ip,profile,subnet,gateway,interface,hostname,dns,netboot_enabled,
    161.                                 kickstart='/var/lib/cobbler/kickstarts/sample_end.ks',
    162.                                 kops='net.ifnames=0 biosdevname=0'):
    163.         sid = self.remote_server.new_system(self.token)
    164.         self.remote_server.modify_system(sid,'name',name,self.token)
    165.         self.remote_server.modify_system(sid, 'hostname', hostname, self.token)
    166.         self.remote_server.modify_system(sid, 'gateway', gateway, self.token)
    167.         self.remote_server.modify_system(sid, 'profile', profile, self.token)
    168.         self.remote_server.modify_system(sid, 'name_servers', dns, self.token)
    169.         self.remote_server.modify_system(sid, 'modify_interface', {
    170.             "macaddress-{}".format(interface): mac.upper(),
    171.             "ipaddress-{}".format(interface): ip,
    172.             "gateway-{}".format(interface): gateway,
    173.             "subnet-{}".format(interface):subnet,
    174.             "dnsname-{}".format(interface): ip,
    175.             "static-{}".format(interface): True,
    176.         }, self.token)
    177.         self.remote_server.modify_system(sid,'kickstart',kickstart,self.token)
    178.         self.remote_server.modify_system(sid,'kopts',kops,self.token)
    179.         self.remote_server.modify_system(sid,'netboot_enabled',netboot_enabled,self.token)
    180.         self.remote_server.save_system(sid,self.token)
    181.         self.__sync_cobbler()
    182.     '''
    183.     获取system ks 定义文件
    184.     '''
    185.     def get_system_generate_kickstart(self,system):
    186.         return self.remote_server.generate_kickstart('',system)
    187.     '''
    188.     获取profile ks 定义文件
    189.     '''
    190.     def get_profile_generate_kickstart(self,profile):
    191.         return self.remote_server.generate_kickstart(profile)
    192.     def get_status(self):
    193.         # print(self.remote_server.get_status('text',self.token))
    194.         # print(self.remote_server.get_status("normal",self.token))
    195.         return self.remote_server.get_status('json',self.token)
    196.     def get_system_status(self,name):
    197.         for ip,v in self.remote_server.get_status('json',self.token).items():
    198.             if v[2].split(":")[1] == name:
    199.                 start = totime(v[0])
    200.                 end = ""
    201.                 if v[1] != -1:
    202.                     end = totime(v[1])
    203.                 system_name = v[2].split(":")[1]
    204.                 status = v[5]
    205.                 initcount = v[3]
    206.                 successcount = v[4]
    207.                 infos= {"starttime":start,"endtime":end,"ip":ip,
    208.                         "systemname":system_name,"status":status,
    209.                         "initcount":initcount,"successcount":successcount}
    210.                 return infos
    211.         return False
    212. class init_system_api(CobblerApi):
    213.     @staticmethod
    214.     def run():
    215.         server = '10.1.41.100'
    216.         user = 'cobbler'
    217.         passwd = 'cobbler'
    218.         return CobblerApi(server,user,passwd)
    219. def totime(timeStamp):
    220.     timeArray = time.localtime(timeStamp)
    221.     otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
    222.     return otherStyleTime
    223. if __name__ == '__main__':
    224.     time_str = time.time()
    225.     server = '10.1.41.100'
    226.     user = 'cobbler'
    227.     passwd = 'cobbler'
    228.     cobbler = CobblerApi(server,user,passwd)
    229.     # print(cobbler.find_system())
    230.     # print(cobbler.find_distros())
    231.     # print(cobbler.find_profiles())
    232.     # print(cobbler.get_system('kvm-centos7-test'))
    233.     # cobbler.remove_system('centos-nineven')
    234.     info=cobbler.get_system('kvm-123')
    235.     if info == "~":
    236.         print("不存在")
    237.     else:
    238.         print(info)
    239.     # print(cobbler.remove_system('111'))
    240.     #
    241.     # infos = cobbler.get_system('centos-nineven')
    242.     # print(infos.get("name"))
    243.     # print(infos.get("profile"))
    244.     # print(infos.get("kickstart"))
    245.     # print(infos.get("kernel_options"))
    246.     # for k,v in infos.get("interfaces").items():
    247.     #     print(k)
    248.     #     print(v.get("gateway"))
    249.     #     print(v.get("hostname"))
    250.     #     print(v.get("mac_address"))
    251.     #     print(v.get("netmask"))
    252.     #     print(v.get("ip_address"))
    253.     exit()
    254.     # print(cobbler.get_status())
    255.     system_status = cobbler.get_status()
    256.     for ip,v in system_status.items():
    257.         start = totime(v[0])
    258.         end=""
    259.         if v[1] !=-1:
    260.             end = totime(v[1])
    261.         system_name = v[2]
    262.         status = v[5]
    263.         # v[4] 安装系统成功的次数  ,v[3] 安装次数
    264.         print(ip,v)
    265.         print('''
    266.         ip:             %s
    267.         start:          %s
    268.         end:            %s
    269.         system_name:    %s
    270.         status:         %s
    271.         '''%(ip,start,end,system_name,status))
    272.     # print(cobbler.get_system_generate_kickstart('Centos-7.2-mini-x86_64'))
    273.     # print(cobbler.get_profiles(cobbler.get_system('centos-nineven').get("profile")))
    274.     # print(cobbler.modify_profile('Centos-7.2-mini-x86_64','kopts','net.ifnames=0 biosdevname=0'))
    275.     # print(cobbler.create_or_update_system("centos-nineven","00:50:56:39:E6:FE","192.168.5.82","Centos-7.2-mini-x86_64",
    276.     #                          "255.255.255.0","192.168.5.1","eth0","nineven-test","114.114.114.114"))
    277.     # print(cobbler.remove_system("centos-nineven"))

  • 相关阅读:
    数据结构和算法——基于Java——3.1链表(单链表)
    docker 和 podman的区别
    Javascript知识【BootStrap技术实现商品页面】
    TensorFlow入门(八、TensorBoard可视化工具的应用)
    FPGA零基础学习:数字电路中的数字表示
    Qt扫盲- QTextStream 理论总结
    Linux PCIe驱动框架分析(第三章)
    基于Python实现的自然语言处理高级专题
    国产视觉检测设备崛起,以AI机器视觉及自研算法破解智造难题
    旅游推荐系统
  • 原文地址:https://blog.csdn.net/ly1358152944/article/details/126437104