有些人就是喜欢折腾

最近又心血来潮,打算把两年前的坑填上,整了两天,算是把部署OpenStack的坑踩得差不多了。部署方法和之前一样,还是采用的kolla-ansible,主要是neutron_external_interface的文档还是写的比较模糊,加上OpenVirtualSwitch一起,折腾了不少时间。

总结起来,这次折腾的主要结论是,能用,但没必要。由于OpenStack本来就是工业级的设计,开发者原本就是基于企业环境控制网络和外网分离的假设做的实现,因而把两个网络合并势必会受到操作系统等外部组件的设计阻碍,这次的坑基本上都是来自这方面。

首先一开始是打算虚拟一个接口给外网,然后用系统做流量转发给物理网口,但是因为技艺不精,一直失败,只好作罢。后来看到OpenStack的开发文档中提到,由于开发者电脑不一定像工业级服务器一样有两个网口,因而还是允许使用单网口机器部署的。只不过由于ovs要独占外网网口,对外网的访问要从原本的物理网口转移到虚拟网口,导致网络配置丢失,因而必须要使用非远程的方法进行配置(BMC除外)。

大致配置流程如下(假设网卡为eth0):

  1. 按照正常流程配置OpenStack安装,并将network_interfaceneutron_external_interface都设置为eth0
    安装到一半的时候,由于kolla-ansible配置了ovs,导致原有网络配置失效,无法访问外网,表现为某些docker pull失败,说无法连接到quay.io。
  2. 此时可以发现eth0被连接到了ovs-system,但是用ovs-vsctl查看,发现eth0又被分配给了br-ex。用nmcli手动进行网络地址的配置:
    nmcli connection modify br-ex connection.autoconnect yes
    nmcli connection modify br-ex ipv4.addresses xxx.xxx.xxx.xxx
    nmcli connection modify br-ex ipv4.gateway xxx.xxx.xxx.xxx
    nmcli connection modify br-ex ipv4.method manual
    nmcli connection modify br-ex ipv4.dns xxx.xxx.xxx.xxx

    其中xxx.xxx.xxx.xxx设置为网卡正常访问外网时的配置即可。需要注意这几条命令的顺序最好不要修改,因为nmcli会做参数检查,如果没设置好某些参数是设置不了另一些的。

  3. 执行nmcli device set br-ex managed yes,将br-ex的网络配置交给nmcli执行,此时可以用ping检查网络是否配置完成;
  4. 修改kolla-ansibleglobals.yml,将network_interface配置为br-ex,因为此时eth0已经无法正常用于访问网络;
  5. 重新执行kolla-ansibledeploy指令,等待部署完成即可。

由于nmtui似乎没法快捷方便地管理ovs的网卡配置,因而每次重启后需要手动将br-ex设置为managed模式,才能由NetworkManager进行配置,即手动执行第三步。

接下来如果有新坑的话,就是在Linux上配个子网,然后让OpenStack用本地虚拟子网作为外网了

最近发现手机里的b站即使在完全关闭的情况下,还是会发推送消息,于是一气之下删了换上国际版。然而国际版的应用大多早就换上了咕果的新技术,下下来是一堆apk,单装一个还没法使用。虽然部分国外安装器提供了安装xapk的功能(如apkpure),然而实质上做的也只是调用系统api来处理这些apk文件,而且在小米手机上还要关闭miui优化才装的上。。

于是到网上找了个教程,发现结果最后还是用的pm,和传统安装的区别在于,咕果把split apk的安装流程做成了事务形式,创建transaction之后,把要安装的多个apk文件以二进制流的形式读入,然后再在submit transaction之后,通过内部处理完成apk的最终安装。还有些其他教程说用可以用adb install-multiple,然而我的adb似乎没有这个选项,只好作罢了。

以b站国际版为例,从网上下载的xapk包展开后有以下类似内容:

$ ls -al
total 147503
drwxrwx--x 2 root sdcard_rw     3488 1970-01-01 08:00 .
drwxrwx--x 8 root sdcard_rw    20480 1970-01-01 08:00 ..
-rw-rw---- 1 root sdcard_rw       59 1970-01-01 08:00 APKComboInstaller.url
-rw-rw---- 1 root sdcard_rw 74755493 1970-01-01 08:00 com.bilibili.app.in.apk
-rw-rw---- 1 root sdcard_rw 74301935 1970-01-01 08:00 config.armeabi_v7a.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.hdpi.apk
-rw-rw---- 1 root sdcard_rw    66460 1970-01-01 08:00 config.ldpi.apk
-rw-rw---- 1 root sdcard_rw    66460 1970-01-01 08:00 config.mdpi.apk
-rw-rw---- 1 root sdcard_rw    99803 1970-01-01 08:00 config.tvdpi.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.xhdpi.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.xxhdpi.apk
-rw-rw---- 1 root sdcard_rw    70616 1970-01-01 08:00 config.xxxhdpi.apk
-rw-rw---- 1 root sdcard_rw  1255351 1970-01-01 08:00 config.zh.apk
-rw-rw---- 1 root sdcard_rw     6602 1970-01-01 08:00 icon.png
-rw-rw---- 1 root sdcard_rw     3331 1970-01-01 08:00 manifest.json

出于严格的安全措施考虑,放在/sdcard目录下的文件存在权限问题,pm读取不到,因而根据报错信息的建议,把文件复制到权限更为宽松的/data/local/tmp,然后就可以正常进行软件包的读取操作了。

安装步骤大致可以分为三步:

  1. 创建安装事务

    pm install-create

    如果成功执行,命令应该给出类似的返回信息:

    Success: created install session [631152719]

    其中方括号里的是创建成功的事务编号,后面还要用到,需要记下来。

  2. 添加安装包 安装split apk的关键就在这里,我们将分散的多个apk通过pm install-write命令添加到安装数据流中。该命令需要提供当前apk文件名、文件大小、事务编号和分包编号作为参数,一般将主程序包作为第一个添加:

    pm install-write -S 74755493 631152719 0 com.bilibili.app.in.apk

    一般来讲,还需要添加库包、资源包、语言包,这些根据自己的需求添加即可。这里选择armeabixxhdpi(1080P)、zh-CN成安装:

    pm install-write -S 74301935 631152719 1 config.armeabi_v7a.apk
    pm install-write -S 70616 631152719 2 config.xxhdpi.apk
    pm install-write -S 1255351 631152719 3 config.zh.apk

    这些包的顺序似乎没有多大影响,我按照这个顺序安装出来是成功的。

  3. 提交安装事务
    pm install-commit 631152719

    完成commit之后,pm开始安装所导入的应用包,并会在命令行中给出Success或者Failed信息。

然而在尝试过程中发现,似乎还是得关闭MIUI优化,不然会报出INSTALL_FAILED_USER_RESTRICTED错误,估计是MIUI阻止了安装= =

参考:https://raccoon.onyxbits.de/blog/install-split-apk-adb/

TAP作为一款轻量化的Windows虚拟网卡,在许多场景下都有广泛应用,比如远程连接私有网络,或者游戏加速一类的。

然而让人恼火的是,在新版的Windows中,在使用无线网卡的时候,关闭TAP相关服务后无线网会自己断连,然后断连后还不会再次加入同一个网络,也就是说一定要自己手动去点一次连接网络才行,非常麻烦。然而由于看不出关键信息,不知道具体是哪个地方引起的wifi断连,一直都没能找到一个令可用的解决方案。

然而苍天不负有心人,近日随手一搜,发现两个月前有人遇到了相同的问题:https://learn.microsoft.com/en-us/answers/questions/1047476/what-is-the-cause-of-34wlan-autoconfig-detected-li.html

解决方法很简单,创建一个DWORD类型的注册表项

HKLM\SOFTWARE\Microsoft\WcmSvc\EnableBadStateTracking

,并将值设置为0即可。

简单来讲,原理似乎大概是,断开TAP网络的短暂时间内,系统发现当前连接的无线网络无法正常连网,于是通知驱动重新配置网络。而可能intel的驱动恰好采用了重启网卡的方式来重配网络,导致网络断连,并且受到WLAN AutoConfig的阻止,无法重新连接到之前认为不能联网的网络。而该注册表项的功能则是告诉WLAN AutoConfig服务,即使连不了网也不要自作主张通知网卡切断网络,因而避免了断连的问题。

之前因为不熟悉Hyper-V,有些功能不会用,因而一直在说 不要使用Hyper-V,会变得不幸 。由于最近需要一个vscode来读代码,在被RK3328+eMMC这种更加不幸的组合折磨之后,决定回过头来看看能不能把之前遇到的问题解决。功夫不负有心人,误打误撞之下,最终还是找到了解决方案。

前情提要:Hyper-V自带了一个用于虚拟机与主机通信的默认交换机,但是该交换机不支持网段配置,每次重启会在10.0.0.0网段下随机选一个子网段给当前DHCP用于分配IP。于是为了获得可以稳定访问的虚拟机IP,就不能使用默认交换机,必须自己单独配一个固定网段,然后给虚拟机分配静态IP。

然后又来到了万能的StackOverflow:网友指出,在已经启用了Hyper-V的情况下,通过PowerShell调用系统接口,可以创建指定网段的NAT,无需配置网关即可访问外网,具体步骤如下:

New-VMSwitch -SwitchName "SwitchName" -SwitchType Internal
Get-NetAdapter       // (note down ifIndex of the newly created switch as INDEX)
New-NetIPAddress -IPAddress 192.168.0.1 -PrefixLength 24 -InterfaceIndex <INDEX>
New-NetNat -Name MyNATnetwork -InternalIPInterfaceAddressPrefix 192.168.0.0/24

其中关键在于最后一步New-NetNat。前面几步分别可以通过在Hyper-V图形管理界面中新建虚拟网卡,以及直接在控制面板中修改对应虚拟网卡的IP完成。

创建完虚拟NAT并修改虚拟网卡的IP之后,在虚拟机中配置静态IP,并将网关设置为主机的虚拟网卡IP,就可以实现虚拟机连通外网了。

这里顺便说一下Hyper-V中的三类虚拟网卡,这篇文章及其配图做了一个还比较好的解释。三种可以在Hyper-V中创建的虚拟网卡分别是外部、内部和私有网卡,特征大致如下:

  • 外部网卡(External):虚拟机直接连通外网,虚拟机与主机处于同一网络层级(都直接获取上层路由器的IP,如果是需要登录的网络,则相当于使用了新设备,需要重新登录);
  • 内部网卡(Internal):虚拟机只连通主机,不连通外网;
  • 私有网卡(Private):虚拟机间相互连通,不连通主机和外网。

需要注意的是,Hyper-V中只有默认的虚拟网卡才带DHCP,所有自己创建的虚拟网卡都是不提供DHCP服务的,只能配静态IP或者自己部署一个DHCP服务端。

之前由于没有搞清几类虚拟网卡的区别,一直在用外部网卡,加上恰好手头的网络是要登录才能使用的,折磨了老久都没用;然后换了内部网卡又不知道要配NAT,属实是十分的不幸了。

现象是找不到部分常见的插件,比如微软家的C/C++和Python插件等。

参考https://stackoverflow.com/a/37238623。原因是根据vscode协议,只允许插件在vscode内自由使用;而根据vscode开源代码独自构建的编辑器理论上已经不算vscode了,所以再用官方源的话就有吃官司的危险,因而大部分基于vscode的开源项目都采用第三方插件源代替微软的官方插件源,如openvsx等。

具体步骤:把下面这段配置贴到code-server的product.json文件中,作为最顶层元素添加即可(通常位于/usr/lib/code-server/lib/vscode/product.json):

  "extensionsGallery": {
      "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
      "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index",
      "itemUrl": "https://marketplace.visualstudio.com/items"
  }

完成添加后,重启code-server服务,再去插件区就能搜索到官方源的插件了。


2023.4更新

VSCode IntelliSense是个什么垃圾东西,食我vscode-clangd