在EdgeOS安装ZeroTier

EdgeOS更新2.0固件后底层系统从Debian7直升到了Debian9,现在已经可以直接通过ZeroTier官方提供的Linux安装脚本进行安装了。

安装ZeroTier

EdgeOS默认的apt源在国内的连接已经非常困难,非常容易因连接超时导致安装失败,建议自行替换国内镜像源。

sudo -i

curl -s https://install.zerotier.com | sudo bash

安装成功后你将得到一个ZeroTier的Client ID。

接着用ZeroTier官网申请的网络ID来加入网络即可

sudo zerotier-cli join [NETWORK-ID]

保护配置文件

为防止因固件升级导致配置文件丢失,我们可以把ZT的配置文件移动到/config/scripts再软连接回到原路径,这样在每次更新固件后重新执行一遍软连接就可以轻松恢复配置。

mv /var/lib/zerotier-one /config/scripts/

ln -s /config/scripts/zerotier-one

映射网络接口(可选)

EdgeOS无法识别ZeroTier的接口(ZT0),因此ZT0不会反映到EdgeOS的WEBUI上面。但即便如此,ZeroTier依然能够正常工作。

如果你闲得蛋疼,路由器上又正好有空闲的网口没地方用,那么可以来试一下把zt0映射到eth(0~4)上面。

在/var/lib/zerotier-one下创建一个devicemap文件,内容如下(将X替换成你闲置的那个口,下略)

<zerotiernetworkid>=ethX

重启ZeroTier

/etc/init.d/zerotier-one restart

这时ifconfig下的ethX应该已经对应zt0的接口信息了。

set interfaces ethernet ethX description "ZeroTier [NETWORK-ID]"

commit

save

 

 

巧用FontSubstitutes替换SimSun

Telegram的中文字体一直饱受吐槽,好在有网友开发了FontMod这样的插件可以替换字体。但其他拥有相同毛病的程序(比如PLEX)就不一定能靠FontMod来解决了。

偶然跟网友聊起了这个问题,当提到SimSun(中易宋体)时,网友竟勃然大怒,表示就是受不了Windows的字体机制才转向了macOS,并劝我早日弃暗投明。

恰好我也忍受PLEX很久了,由于平时不会主动去用SimSun,又不希望程序用它来显示字体,那么干脆直接干掉它?

继续阅读“巧用FontSubstitutes替换SimSun”

神奇的联合文件系统(UnionFileSystem)

关于联合文件系统(这里简称UnionFS)最早是从一段香的OMV介绍文中看到的,实际用上它的契机倒是因为近几年被老莱炒火的unRAID。

unRAID号称可以在允许磁盘休眠的同时实现跨盘卷与数据冗余,想了一想这不就是一段香提到的UFS+Snapraid吗。

本着试用结束后就回去折腾OMV的想法试了2个月的unRAID,在试用期过后系统再起不能的时候我的大脑已被真香支配,便情不自禁地冲了钱成为了正儿八经的unRAID用户。当然这并不是一篇unRAID的安利文,这里主要还是想介绍一下unRAID所使用的核心之一——UnionFS。

继续阅读“神奇的联合文件系统(UnionFileSystem)”

无法逃离PLEX的魔爪

在搞定IPV6后终于可以如愿以偿地在地铁上听PLEX上的歌了,但不知是我家上行带宽太小还是IPV6本身不稳定的缘故,间歇性的连接失败总是在比较尴尬的时刻来临。

想了想我收藏的歌其实也不是很多,为什么不直接把它们丢在第三方公有云上呢。一番搜索后得知吃灰已久的Apple Music已经提供类似网易音乐云盘的功能(iTunes Match)。

PLEX本身不会去修改任何文件信息(比如ID3),所以如果要打算回到iTunes上,那么从源头去整理ID3才是一劳永逸的。

继续一番搜索后找到了这个叫MusicBrainz的服务。

使用下来匹配精度要比PLEX高不少,针对一些疑难杂歌提供的手动匹配功能也非常顺手,唯一的缺点大概就是它只使用自家的数据库以至于确实有一部分刮削不到信息,但对于勤劳的我来说只要能自行编辑数据库那就不是问题。

得益于MusicBrainz优秀的操作体验,我花了大概儿时手动整理歌曲1/100的时间就处理完了大半的歌。

在批量执行ID3写入的时间里我打开了那个又卡又臃肿的iTunes,一边导入音乐库的同时我掏出了手机正准备订阅AM会员。而就在我打算支付的时候我才注意到资料库依旧是空空如也。

嗯!9102年了iTunes还是不支持FLAC。

iTunes再见,PLEX我又回来了。

 

通过IPv6连接你的PLEX服务器

目前国内IPv6的推进速度已经相当不错,对于有家庭服务器需求的用户来说,获取一个不知道能用多久的公网IPv4可能已经远远超过了获得原生IPv6的难度。

长期受到无公网IP的我拿到IPv6后想到的第一件事就是试试能不能透过公网连接自家的PLEX库。

前期工作

首先是配置路由器给局域各网客户机分配地址,不同路由系统对IPv6的自动化配置程度有所差异,我的Ubnt ER-X就属于比较麻烦的那种,好在官方论坛已经有比较详尽的配置示范。

仅仅配置完路由器后还无法通过IPv6测试,打开WIN10的防火墙,添加一条入站规则放行ICMPv6后一切显示正常。

继续阅读“通过IPv6连接你的PLEX服务器”

Embuary中文字体乱码修复

Embuary是我比较喜欢的一个Kodi皮肤,在我看来是kodi众多皮肤中仅有的几个符合现代审美的皮肤之一。

界面基本承袭Emby UI的设计语言,搭配Kodi + Emby这样的融合方案可谓是天衣无缝,虽然当初站了Plex的队,不过自己修改一下配色的话跟Plex也是挺搭的。

此皮肤原生支持Arial字体用于显示中、日等文本,但有一部分文字会显示成口口,打开一些其他插件更是口得一塌糊涂。

作者已在新版皮肤中修复此问题(仅限Kodi v18)

继续阅读“Embuary中文字体乱码修复”

记一次春游

前几日二哥打电话过来提议野餐,想到最近几乎每天都在沉迷只狼需要转换下状态,遂赴约。

同行的小伙伴里大部分之前都没有见过,但相处还算愉快,若是四五年前的我的话大概会被自己惊讶到。

四月的第一个星期天已经初具夏天的味道,明媚的光照也非常迎合本次野餐的目的——拍照。

BOSE的Soundlink mini发挥不错,一开腔就赶走了JBL的保温杯,几年前入手的时候就觉得它很适合户外音乐,但真正应用在实际场合这还是第一次。

太湖的夕阳还算别致,二哥喝了不少,我也找到了能拿来写一则大概算得上是日志的东西。

主题更新

一直很喜欢暗黑系的主题,毕竟暗黑就是男人的浪漫。虽然也不止一两次被吐槽过看着压抑这个问题。

前一个主题想要尝试做出Nebula那种感觉,emmmm效果虽然不是很好但应该已经不会感到很压抑了。但是这个主题里使用了大量的块来区分内容,导致整个页面能够显示的内容非常少(如下图)。

这在当时并不算一个重大问题,但如今放在4K分辨率下,偌大的一块区域里只有这么一小部分内容看着实属不适,索性就重新作一版吧。

于是,尽管能够来吐槽主题配色的人早已不知踪影,但这次还是有刻意去弄得明亮一点。虽说是换,但相较旧主题其实未做任何布局变动,因此这只能算是一个2.0版本。

新的主题同样是基于TwentySixteen作简单的样式修改,不同的是这次使用了Child Theme(子主题)的方式进行修改。

Child Theme的本质其实就是引用原主题的布局和样式,再以更高的优先级读取新的布局和样式。这样的修改方式更优雅,可以很清晰看到哪些代码是自己的,哪些是原作者的。并且在原主题更新迭代的同时,Child Theme也可以一并引继以持续保持对WP良好的兼容性。

关于子主题的使用方式,在WP的官方文档里(zh-cn:子主题)已经写得很详细。

 

修复OMV4的Python报错

由于OMV4仍然是一个开发版本, 目前仍有一些小bug,目前发现的有NUT状态异常(提示找不到pid),Python时不时弹出错误信息(通常在安装卸载软件时出现,见下图)。

NUT在今天的插件更新后已经修复,剩下的就是Python了。

Python的报错到目前为止没有发现任何影响,但看到报错放着不管总觉得不太舒服,官方论坛里搜索了一番疑似是Python3.5的一个bug,可以直接修改对应文件解决(链接)

vim /usr/lib/python3.5/weakref.py

分别修改109和117两行即可(删除和高亮部分)

self, *args = args
if len(args) > 1:
raise TypeError(‘expected at most 1 arguments, got %d’ % len(args))
def remove(wr, selfref=ref(self)):
def remove(wr, selfref=ref(self), _atomic_removal=_remove_dead_weakref):
self = selfref()
if self is not None:
if self._iterating:
self._pending_removals.append(wr.key)
else:
# Atomic removal is necessary since this function
# can be called asynchronously by the GC
_remove_dead_weakref(d, wr.key)
_atomic_removal(d, wr.key)
self._remove = remove
# A list of keys to be removed
self._pending_removals = []