Cobbler自动装机
preface
我们之前批量安装操作系统的时候都是采用pxe来安装,pxe也是通过网络安装操作系统的,但是PXE依赖于DHCP,HTTP/TFTP,kicstart等支持。安装流程如下所示:
对于上面的PXE安装流程,我们需要知道我们做了以下的工作:
- 配置服务,如DHCP、TFTP、(HTTP、FTP、和NFS)
- 在dhcp和TFTP配置文件中填入客户端机器的信息。
- 创建自动部署文件(比如kickstart)
- 将安装的媒介解压缩到HTTP/FTP/NFS存储库中。
PXE装机也是一个不错的选择对于批量装机的话,现在呢我们学习另一种安装操作系统的软件cobbler。它具有以下功能:
- 使用一个以前定义的模版来配置DHCP服务(如果启用了管理DHCP)
- 将一个存储库(yum或rsync)建立镜像或者解压缩一个媒介,以注册一个新的操作系统。
- 在DHCP配置文件中为需要安装的机器创建一个条目并使用我们指定的参数(IP、mac地址)
- 在TFTP服务目录下创建适当的PXE文件
- 重新启动DHCP服务以反映更改
- 重新启动机器以开始安装(如果电源管理已经启用的话。)
cobbler简介:
- Disribution : 发行内核,initrd等东西
- Repository: 创建仓库,比如yum仓库等。
- system: 通过mac地址来定制化系统
- profile: 对需要安装某个系统的所有配置。
基础环境介绍
首先我先说说的环境吧
IP地址 | 主机名 |
---|---|
192.168.56.11 | linux-node1.example.com |
- 内核为3.10.0-514.2.2.el7.x86_64
- 网卡名字设置为了eth0。
- 关闭了selinux,iptables。
- 时间同步ntp.chinacache.com
- hosts文件里面需要写下hostname,便于解析。
开始安装cobbler
我们采用yum安装的方式来安装:
1.安装cobbler以及相关的软件
[root@linux-node1 ~]# yum -y install httpd dhcp tftp python-ctypes cobbler xinetd
2.启动服务(先起服务是因为这样才知道我们没有配置哪些东东)
[root@linux-node1 ~]# systemctl start httpd
[root@linux-node1 ~]# systemctl enable httpd
[root@linux-node1 ~]# systemct1 enable cobblerd
[root@linux-node1 ~]# systemctl start cobblerd
3.看看哪些配置文件没有改,下面的工作就是要处理掉这些提示信息。这样cobbler就能够正常工作了。
[root@linux-node1 ~]# cobbler check
The following are potential configuration items that you may want to fix: 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. # 设置PXE文件
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.
# 设置tftp
3 : change 'disable' to 'no' in /etc/xinetd.d/tftp
# 把网络的boot-loaders通过cobbler get-loaders后放在/var/lib/cobbler/loaders
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.
# 启动rsync服务
5 : enable and start rsyncd.service with systemctl 6 : debmirror package is not installed, it will be required to manage debian deployments and repositories
# 生成一个默认的密码对于新安装的设备
7 : 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
#
8 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them Restart cobblerd and then run 'cobbler sync' to apply changes.
4.修改配置文件
[root@linux-node1 ~]# vim /etc/cobbler/settings
server: 192.168.56.11 # 把这些地址都改为本机的IP
next_server: 192.168.56.11
5.再次检测配置文件,显然这提示的数量下降到了5,我们在逐个击破。
[root@linux-node1 ~]# cobbler check #
The following are potential configuration items that you may want to fix: 1 : change 'disable' to 'no' in /etc/xinetd.d/tftp
2 : enable and start rsyncd.service with systemctl
3 : debmirror package is not installed, it will be required to manage debian deployments and repositories
4 : 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
5 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them
6.修改xinetd的配置文件以及启动和启动rsync
[root@linux-node1 ~]# vim /etc/xinetd.d/tftp
disable : no
[root@linux-node1 ~]# systemctl start rsyncd
[root@linux-node1 ~]# systemctl enable rsyncd.service
[root@linux-node1 ~]# systemctl restart xinetd
7.配置cobbler的密码
[root@linux-node1 ~]# openssl passwd -1 -salt '123123' '123123'
$1$123123$MAV.kVI/b3swmFLErPD2b0
[root@linux-node1 ~]# vim /etc/cobbler/settings
default_password_crypted: "$1$123123$MAV.kVI/b3swmFLErPD2b0"
为什么我们这样设置密码呢?因为我们看cobbler这样提示的:try: "openssl passwd -1 -salt 'random-phrase-here' 'your-password-here'" to generate new one
,所以我们使用这个命令来做。
8.下载loader
[root@cobbler ~]# cobbler get-loaders
9.最后查看cobbler check
[root@linux-node1 ~]# cobbler check
The following are potential configuration items that you may want to fix: 1 : debmirror package is not installed, it will be required to manage debian deployments and repositories
2 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them Restart cobblerd and then run 'cobbler sync' to apply changes.
我们可以看到还有2条提示信息,我们可以暂且忽略他们。不需要关注。
配置cobbler-DHCP
我们配置cobbler的DHCP,使其cobbler来控制dhcp服务在进行装机的时候。
1.修改cobbler配置:
[root@linux-node1 cobbler]# vim /etc/cobbler/settings
manage_dhcp: 1 # set to 1 to enable Cobbler's DHCP management features.
2.修改dhcp.templates配置文件
[root@linux-node1 ~]# cd /etc/cobbler/
[root@linux-node1 cobbler]# vim dhcp.template # 主要是修改了下面几项
subnet 192.168.56.0 netmask 255.255.255.0 { # 子网
option routers 192.168.56.2; # 网关
option domain-name-servers 192.168.56.2; # dns-server
option subnet-mask 255.255.255.0; # 子网掩码
range dynamic-bootp 192.168.56.100 192.168.56.254; # 地址池
3.重启服务并同步配置,改完dhcp必须要sync同步配置。
[root@linux-node1 cobbler]# systemctl restart cobblerd
[root@linux-node1 cobbler]# cobbler sync
task started: 2017-02-25_051458_sync
task started (id=Sync, time=Sat Feb 25 05:14:58 2017)
...省略N行提示
generating /etc/dhcp/dhcpd.conf # 注意这个dhcp,会自动生成我们刚才的配置。
*** TASK COMPLETE ***
4.检测dhcp端口
[root@linux-node1 cobbler]# netstat -lnup |grep dhcp
udp 0 0 0.0.0.0:67 0.0.0.0:* 31034/dhcpd
udp 0 0 0.0.0.0:55385 0.0.0.0:* 31034/dhcpd
udp6 0 0 :::35318 :::* 31034/dhcpd
导入CentOs-7的镜像
我们先上传一个镜像到linux-node1.example.com上。然后开始导入:
[root@linux-node1 cobbler]# mount -o loop /opt/CentOS-7.0-1406-x86_64-DVD.iso /mnt/
mount: /dev/loop0 is write-protected, mounting read-only
[root@linux-node1 cobbler]# cobbler import --path=/mnt --name=CentOS-7.0-1406-x86_64 --arch=x86_64
导入时间有点长,稍等下。
导入的文件是放在这里/var/www/cobbler/ks_mirror的:
[root@linux-node1 ks_mirror]# pwd
/var/www/cobbler/ks_mirror
[root@linux-node1 ks_mirror]# ls
CentOS-7.0-1406-x86_64 config
之所以导入到这里,是因为apache的配置文件,详情可看/etc/httpd/conf.d/cobbler.conf
.
导入完镜像以后,那么就使查看下cobbler
[root@linux-node1 cobbler]# cobbler list
distros:
CentOS-7.0-1406-x86_64 profiles:
CentOS-7.0-1406-x86_64 systems: repos: images: mgmtclasses: packages: files:
导入kickstarts配置文件
上面有了镜像,那么下一步我们就需要导入kickstarts了。
[root@linux-node1 kickstarts]# pwd
/var/lib/cobbler/kickstarts
[root@linux-node1 kickstarts]# ll -rt
total 52
-rw-r--r-- 1 root root 5879 Nov 16 11:09 sample.seed
-rw-r--r-- 1 root root 3419 Nov 16 11:09 sample_old.seed
-rw-r--r-- 1 root root 1784 Nov 16 11:09 sample.ks
-rw-r--r-- 1 root root 386 Nov 16 11:09 sample_esxi5.ks
-rw-r--r-- 1 root root 324 Nov 16 11:09 sample_esxi4.ks
-rw-r--r-- 1 root root 0 Nov 16 11:09 sample_esx4.ks
-rw-r--r-- 1 root root 1825 Nov 16 11:09 sample_end.ks
-rw-r--r-- 1 root root 2916 Nov 16 11:09 sample_autoyast.xml
-rw-r--r-- 1 root root 292 Nov 16 11:09 pxerescue.ks
-rw-r--r-- 1 root root 1424 Nov 16 11:09 legacy.ks
-rw-r--r-- 1 root root 22 Nov 16 11:09 esxi5-ks.cfg
-rw-r--r-- 1 root root 22 Nov 16 11:09 esxi4-ks.cfg
-rw-r--r-- 1 root root 115 Nov 16 11:09 default.ks
drwxr-xr-x 2 root root 54 Feb 25 04:09 install_profiles
到了这一步,我把自己写的kickstart文件给上传上去,然后执行下面命令导入刚才的:
[root@linux-node1 kickstarts]# cobbler profile report
[root@linux-node1 kickstarts]# cobbler profile list
CentOS-7.0-1406-x86_64
[root@linux-node1 kickstarts]# cobbler profile edit --name CentOS-7.0-1406-x86_64 --kickstart=/var/lib/cobbler/kickstarts/CentOS-7.1-x86_64_cobbler.cfg #这里写我们刚才上传的配置文件。
[root@linux-node1 kickstarts]# cobbler profile edit --name CentOS-7.0-1406-x86_64 --kopts='net.ifnames=0 biosdevname=0' # 添加内核参数在grub配置文件里面,换句话说就是系统启动的时候。
[root@linux-node1 kickstarts]# cobbler profile report # 再次执行这个,看有没有修改成功
我的kickstart文件内容如下:
#platform=x86, AMD64, or Intel EM64T
#System language
lang en_US
#System keyboard
keyboard us
#Sytem timezone
timezone Asia/Shanghai
#Root password
rootpw --iscrypted $default_password_crypted
#rootpw --iscrypted $1$ops-node$7hqdpgEmIE7Z0RbtQkxW20
#Use text mode install
text
#Install OS instead of upgrade
install
#Use NFS installation Media
url --url=$tree
#url --url=http://192.168.56.11/CentOS-7.1-x86_64
#System bootloader configuration
bootloader --location=mbr
#Clear the Master Boot Record
zerombr
#Partition clearing information
clearpart --all --initlabel
#Disk partitioning information
part /boot --fstype xfs --size 1024 --ondisk sda
part swap --size 1024 --ondisk sda
part / --fstype xfs --size 1 --grow --ondisk sda
#System authorization infomation
auth --useshadow --enablemd5
#Network information
$SNIPPET('network_config')
#network --bootproto=dhcp --device=eth0 --onboot=on
# Reboot after installation
reboot
#Firewall configuration
firewall --disabled
#SELinux configuration
selinux --disabled
#Do not configure XWindows
skipx
#Package install information
%pre
$SNIPPET('log_ks_pre')
$SNIPPET('kickstart_start')
$SNIPPET('pre_install_network_config')
# Enable installation monitoring
$SNIPPET('pre_anamon')
%end %packages
@ base
@ core
sysstat
iptraf
ntp
lrzsz
ncurses-devel
openssl-devel
zlib-devel
OpenIPMI-tools
mysql
nmap
screen
%end %post
systemctl disable postfix.service # Start yum configuration
$yum_config_stanza
# End yum configuration
rpm -ihv https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
%end
最后一步同步数据:
[root@linux-node1 kickstarts]# cobbler sync
安装CentOs-7操作系统。
- 此时Cobbler已经能够安装操作系统了,下一步我们就创建一台虚拟机来安装操作系统吧。
- 我们使用vmware来创建一个虚拟机,同时调整vmware的网络参数,关闭vmware的DHCP功能,同事确保新创建的虚拟机和cobbler主机在同一网段。
- 启动刚才新创建的虚拟机,选择网络安装操作系统就可以了。
附加功能
1.修改安装界面的标题
我们可以自定义安装的tittle,如下所示:
[root@linux-node1 pxe]# vim /etc/cobbler/pxe/pxedefault.template
MENU TITLE | http://cobbler.github.io/ # 自定义标题。
TIMEOUT 200 # 超时时间20S,单位为毫秒
2.使用cobbler-web功能
我们安装下cobbler-web功能
[root@linux-node1 pxe]# yum -y install cobbler-web
[root@linux-node1 pxe]#systemctl restart httpd.service # 重启下apache即可,因为配置文件有变动
然后访问登陆即可:
https://192.168.56.11/cobbler_web/,默认用户名密码是cobbler/cobbler
登陆的用户名密码在这里存放着:
[root@linux-node1 pxe]# tail /etc/cobbler/users.conf # 存放用户名权限的
[admins]
admin = ""
cobbler = ""
[root@linux-node1 pxe]# tail /etc/cobbler/users.digest # 存放密码的
cobbler:Cobbler:a2d6bae81669d707b72c0bd9806e01f3
看了 上面的用户名密码的存放文件后,那么下面我们修改下他的密码,使用下面的命令:
[root@linux-node1 pxe]# htdigest /etc/cobbler/users.digest "Cobbler" cobbler #连续输入2次密码即可。
我这里输入的密码是123456
3.使用koan实现重新安装系统
koan是安装在某一个需要重新安装系统的服务器上,比如我s1服务需要重新安装系统,不可能说人去一趟机房安装吧,而采用cobbler安装的话,在重启的时候需要人工选择安装哪个系统,不然默认从local启动。那怎么办呢?koan这个软件就能够很好的解决这个问题。
我们先下载阿里云的repo:https://mirrors.aliyun.com/repo/,到这里下载一个合适的yum源,我这里的下载的是CentOs7的。然后开始安装koan。
[root@localhost yum.repos.d]# yum -y install koan
安装好以后,我们可以查看cobbler-server上有哪些系统提供了。
[root@localhost yum.repos.d]# koan --server=192.168.56.11 --list=profiles
- looking for Cobbler at http://192.168.56.11:80/cobbler_api
CentOS-7.0-1406-x86_64 # 罗列出来的系统
选择重装的系统:
[root@localhost yum.repos.d]# koan --replace-self --server=192.168.56.11 --profile=CentOS-7.0-1406-x86_64
[root@localhost grub2]# less /boot/grub2/grub.cfg # 我们可以查看这个启动项里面,发现多了一些内容,这就是为啥开机后能够自动选择网络安装,是因为grub启动项里设置了。
重启系统就可以安装了。在重启的时候,我们可以看到这新添加的一个启动项,且默认是走它:
4. 创建yum仓库
cobbler不但可以装机,还可以自建yum仓库,这个仓库可以从公网的yum源进行同步到公司内网,节省带宽。同步命令如下所示:
cobbler repo add --name=CentOS-7-x86_64-epel --mirro=https://mirrors.aliyun.com/epel/7Server/x86_64/ --arch=x86_64 --breed=yum
cobbler repo add --name=openstack-newton --mirror=https://mirrors.aliyun.com/centos/7.3.1611/cloud/x86_64/openstack-newton/ --arch=x86_64 --breed=yum
cobbler reposync --tries=3 --no-fail
参数解释下:
- repo add : 添加一个repo源
- name : 为这个yum源命名
- mirror : 指定一个源的地址。
- arch : 指定平台
- breed: 类型为yum
5. 通过mac地址来定制化、自动化系统
在这一步,我们需要提前知道需要装机服务器的MAC地址,一般情况下,服务器供应商会提供了每个网卡的MAC地址,所以我们可以根据不同的MAC地址来给安装 不同的操作系统,配置不同的静态iP,设置不同的主机名等等。命令如下:
cobbler system add --name=linux-node3 --mac=00:50:56:24:82:3A \
--profile=CentOS-7.0-1406-x86_64 \
--ip-address=192.168.56.100 --subnet=255.255.255.0 \
--gateway=192.168.56.2 --interface=eth0 \
--static=1 --hostname=linux-node3.example.com \
--name-servers="192.168.56.2" \
--kickstart=/var/lib/cobbler/kickstarts/CentOS-7.1-x86_64_cobbler.cfg
参数解释下:
- system add 添加一个系统定制
- name 定义这个新添加的系统定制的名字
- mac 指定MAC
- profile 指定profile,通过
cobbler profile list
查看 - ip-address 指定静态IP
- subnet 指定子网掩码
- gateway 指定网关
- interface 指定网卡
- static=1 设置为静态IP
- hostname 这是主机名
- name-servers 设置dns服务器
- kickstart 设置kickstart,通过
cobbler profile report
来查看。
[root@linux-node1 ~]# cobbler system list # 创建成功后能够看到刚才新建的系统模版
linux-node3
我们创建一个虚拟机,mac地址为00:50:56:24:82:3A,启动后你就会发现自动进入安装系统了,等安装完以后,所有的配置都和我们当初设置的一样。
6. cobbler-api
cobbler也是通过restful-api来调用对应的接口,下面请看两个小脚本:
都是采用opython2.7版本运行的
[root@linux-node1 ~]# cat cobbler_list.py
#!/usr/bin/python
import xmlrpclib
server = xmlrpclib.Server("http://192.168.56.11/cobbler_api")
print server.get_distros()
print server.get_profiles()
print server.get_systems()
print server.get_images()
print server.get_repos()
下面看看创建system模版的:
[root@linux-node1 ~]# cat cobbler-api.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import xmlrpclib class CobblerAPI(object):
def __init__(self,url,user,password):
self.cobbler_user= user
self.cobbler_pass = password
self.cobbler_url = url def add_system(self,hostname,ip_add,mac_add,profile):
'''
Add Cobbler System Infomation
'''
ret = {
"result": True,
"comment": [],
}
#get token
remote = xmlrpclib.Server(self.cobbler_url)
token = remote.login(self.cobbler_user,self.cobbler_pass) #add system
system_id = remote.new_system(token)
remote.modify_system(system_id,"name",hostname,token)
remote.modify_system(system_id,"hostname",hostname,token)
remote.modify_system(system_id,'modify_interface', {
"macaddress-eth0" : mac_add,
"ipaddress-eth0" : ip_add,
"dnsname-eth0" : hostname,
}, token)
remote.modify_system(system_id,"profile",profile,token)
remote.save_system(system_id, token)
try:
remote.sync(token)
except Exception as e:
ret['result'] = False
ret['comment'].append(str(e))
return ret def main():
cobbler = CobblerAPI("http://192.168.56.11/cobbler_api","cobbler","123456")
ret = cobbler.add_system(hostname='cobbler-api-test',ip_add='192.168.56.101',mac_add='00:50:56:21:65:78',profile='CentOS-7.0-1406-x86_64')
print ret if __name__ == '__main__':
main()
通过这样api的方式,也能够创建system模版实现安装主机的功能。
Cobbler自动装机的更多相关文章
- CentOS7中搭建cobbler自动装机服务
一.实验环境 一台centos7 epel源网址 https://fedoraproject.org/wiki/EPEL?rd=Epel 使用nat模式 二.实验步骤 1.下载epel源后进行文件夹挂 ...
- Cobbler自动装机试验
Cobbler自动装机简介:Cobbler是一个使用Python开发的开源项目,通过将部署系统所涉及的所有服务集中在一起,来提供一个全自动的批量快速建立Linux系统的网络安装环境.Cobbler提供 ...
- Cobbler自动装机--2
自动重装工具--koan 客户机已经通过cobbler安装centos7系统完毕. 安装koan,能实现重装,安装之前先安装epel源 koan是kickstart-over-a-network的缩 ...
- Cobbler自动装机--1
cobbler介绍 cobbler官网:http://cobbler.github.io/用个人的话来说就是cobbler就是一款通过网络快速安装Linux操作系统的产品.cobbler可以配置,管理 ...
- 1. 自动化运维系列之Cobbler自动装机
preface 我们之前批量安装操作系统的时候都是采用pxe来安装,pxe也是通过网络安装操作系统的,但是PXE依赖于DHCP,HTTP/TFTP,kicstart等支持.安装流程如下所示: 对于上面 ...
- cobbler自动装机服务简介与配置
cobbler简介 Cobbler是一个Linux服务器安装的服务,可以通过网络启动(PXE)的方式来快速安装.重装物理服务器和虚拟机,同时还可以管理DHCP,DNS等. Cobbler可以使用命令行 ...
- Cobbler自动部署装机 轻松解决装机烦恼
Cobbler自动部署装机一.实验准备二.搭建步骤1.导入epel源2.安装Cobbler以及其相关服务软件包3.修改Cobbler 主配置文件4.启动相关服务并关闭防火墙和selinux5.使用co ...
- pxe+kickstart cobbler无人值守装机
环境准备: 一台服务器 [root@admin tftpboot]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [roo ...
- Cobbler自动部署主机系统
Cobbler自动部署主机系统 简介: Cobbler由python语言开发,是对PXE和 Kickstart以及DHCP的封装.融合很多特性,提供了CLI和Web的管理形式.更加方便的实行网络安装. ...
随机推荐
- python 爬虫 requests模块(response常用属性)
response常用属性 content获取的response对象中的二进制(byte)类型的页面数据response.content 返回响应状态码response.status_code 200 ...
- linux静态IP配置和网关配置
我们在配置CentOS的时候,很多情况需要能联外网,那么就需要DNS解析功能,默认的是没有配置DNS信息的,所以我们得配置DNS信息起因我们在搜索Centos配置DNS信息的时候,很多都是说在这个文件 ...
- 小菜鸟之Oracle数据库之事务
Oracle数据库之事务 1. 什么是事务 在数据库中事务是工作的逻辑单元,一个事务是由一个或多个完成一组的相关行为的SQL语句组成,通过事务机制确保这一组SQL语句所作的操作要么都成功执行,完成整个 ...
- 创建Maven Web项目时很慢解决办法
点击加号,Name输入archetypeCatalog,Value输入internal archetypeCatalog表示插件使用的archetype元数据,不加这个参数时默认为remote,loc ...
- Java基础开篇
我是一个2019毕业的非计算机的毕业生,从大二开始喜欢上Java直到现在一直都在学习,Brid从小就对计算机感兴趣,可惜高中的时候不懂事,没有规划未来,考上了一所专科学院,然后大一并不能转专业,现在毕 ...
- 测试基础_<一>
1: 过程决定质量, 测试过程贯穿整个软件开发声明周期; 2: 测试过程和开发过程在整个开发周期相辅相成; 3: 测试过程是对整个开发过程的验证, 二者互相依赖 4: 测试过程是整个测试活动中一个至关 ...
- Python 入门 之 双下方法
Python 入门 之 双下方法 1.双下方法 定义:双下方法是特殊方法,它是解释器提供的 由双下划线加方法名加双下划线 方法名的具有特殊意义的方法,双下方法主要是python源码程序员使用的,我 ...
- 华为wlan配置流程及相关重要步骤AC配置
本次介绍是AC+fitAP组网方式的重要步骤. 一.基础配置 1.规划好ac+ap的组网方式和转发方式.(本次以三层旁挂直接转发),规划管理vlan,业务vlan,与AC连接的vlan,以及他们接口的 ...
- Erasing Substrings CodeForces - 938F (字符串dp)
大意: 给定字符串$s$, 长度为$n$, 取$k=\lfloor log2(n)\rfloor$, 第$i$次操作删除一个长度为$2^{i-1}$的子串, 求一种方案使得, $k$次操作后$s$的字 ...
- leetcode中等题
# Title Solution Acceptance Difficulty Frequency 1 Two Sum 44.5% Easy 2 Add Two Number ...