linux下从ISO创建windows启动 USB

先贴个链接

https://thornelabs.net/posts/create-a-bootable-windows-7-or-10-usb-drive-in-linux.html

我按照这个步骤创建了windows 7的启动U盘。遇到过一个问题的就是在mount的而的错误:

$MFTMirr does not match $MFT 

试了几招都修不好,然后更换了U盘就好了。

然后就是在Lenovo Think Center M72e 从U盘启动的时候,要在bios设置为Leagcy启动模式,不要UEFI启动。

把老项目迁移到docker

有个老项目是php 5.2.17,以前用的是vagrrant, 现在想本地开发环境迁移到docker.

寻找合适的image

第一步寻找合适的镜像, pull 下来

我在这里找到一个5.2.17镜像, 先用docker pull命令拉到本地.

然后用docker images 查看,看到一个名叫

deminy/php-5.2

的镜像.

docker run 镜像名 

然后运行该镜像,可以启动一个名为”admiring_dbinsky”.的容器.

运行docker exec -it 容器名或id bash 来进入容器的shell查看.满足要求.

下一步如何基于这个镜像打造一个自己的项目镜像呢?那就需要编写dockefile了

编写dockerfile

FROM deminy/php-5.2

MAINTAINER hongyi.chen

WORKDIR /tmp

EXPOSE 80

编写完毕后, 用build命令构造一个自己的镜像 

docker build -t 项目名称_web .

完成后,就可以看到一个自己的镜像了.如果有错,就返回修改dockerfile,然后重新构建build.

发现个问题,就是每次启动这个镜像,名字都会不同.估计是默认随机名字.不过可以通过docker compose解决

编写docker-compose

为了继续偷懒,我们用docker-compose来编写.

编写完毕后,第一次运行要

docker-compose up –build

这个build参数似乎就是docker的build 命令的

启动后,就可以看到自己名字的的容器了.然后配合一个mysql的容器,这个php5.2的老项目就在本地跑起来了.

把自建的VPN集成到HA里

有时候在面需要访问家里的内网。以前专门搞了二手的树莓派pi 一代来做VPN服务器。选用的是WireGuard作为服务器.

昨天发现HA系统(homeassistant)支持WireGuard插件。因为HA运行在一台独立的树莓派Pi 4, 所以就没必要在保留pi 1了。所以果断安装此插件,把生成的二维码图片交给手机的客户端。然后在路由器上设置端口转发就好了。

旧的 Pi就放到ebay上买掉了。

通过补丁(patch)升级到cataline

通过github上的dosdude1的项目(http://dosdude1.com/catalina/) 成功把macpro 3.1升级到了catalina.

升级完毕后,发现几个问题

  1. 显卡只能输出一个显示器。我拆先原装的A卡,换上N卡问题照旧。
  2. 声卡驱动未包含,所以没有声音。
  3. 网页浏览图片时候会有马赛克花屏现象。
  4. 有一些奇怪的进程无响应象。

如果这些问题解决不了,我还是继续留在El Captian吧。

(code review记录 )用rxjs重构一个小功能

今天看同事帮我修改的代码。一段很简单的UI点击事件被修改成了基于的rxjs的实现。思路大概是这样的。

本来footer component 有一个triggerToggleNavMenu(),大概是这个样子。

....
triggerToggleNavMenu(){
    // 我原来的代码在这里直接操作DOM修改UI
}
...

同事把它改为发射一个event

triggerToggleNavMenu(){
    this.toggleNavMenu.emit();
}

当然他在component里先添加了一个事件发射器(EventEmiter)属性

@Output() toggleNavMenu =  new EventEmitter<void>();

这样把我的“简单粗暴”的点击修改UI的事件改造为了报告一个“事件”。而且事件发射器具有@Output() 修饰,说明是向父组件(page)报告。(参考: 1

那么父组件page如何获取这个事件呢? 可以观察父组件page的模板,在嵌入该组件footer的时候,有个属性绑定:

<footer .... (toggleNavMenu)="toggleFooterNavMenu()" >

这样,子组件footer中的toggleNavMenu就和父组件page里的方法toggleFooterNavMenu()绑定了。

在父组件里果然存在一个叫做toggleFooterNavMenu的方法,该方法就是调用了ui的toggleFooterNavMenu()方法。

toggleFooterNavMenu(){
    this.ui.toggleFooterNavMenu();
  }

这个ui是我们这个项目里为实现rxjs方便而组织的一个feature层的一个Facade(外框)。这Feature层相当于连通了状态机state 和 app 的一个中间层。在这一层包含了rxjs的所有实现的要素,比如action, reduce, selector

这个UI的Facade里,对整个事件处理就一句话:让store触发这个action的事件。

toggleFooterNavMenu() {
    this.store$.dispatch(UiActions.footerNavMenuToggle());
 }

这个store$就是大名鼎鼎的ngrx库里的store(状态)了。这个UiActions.footerNavMenuToggle()则返回一个通过createAction创建的一个action(我的理解action是一种自定义事件)。

触发这个事件会有什么“后果”呢?就是reduce了任务了,reduce负责“无副作用”地修改store里的状态。在reduce的定义中,我们已经定义好了这样的任务:

.......
on(action名字 (state) => ({
...state,
footerNavMenuOpen: !state.footerNavMenuOpen
})),

关键就一行 把footerNavMenuOpen 取反。因为我们这就一个bool问题,比较简单.

那么到这里为止,饶了半天这个点击动作仅仅修改了内存(store)中的一个state状态值?是的。但是一旦这个状态state发生改变后,会有一系列的“后续事件”。这就是rxjs的精妙所在。所有订阅了这个state的订阅者都会收到通知。

当然,这个状态也是事先定义好的。它有对应的状态模型。这里是指和ui相关的几个需要观察的对象的状态,比如某个菜单的开闭状态,初始状态等等。

在Facade 的中有一个可观察对象的属性:
 footerNavMenuOpen$: Observable<boolean>;
具体定义是通过一个选择器selector,选择订阅了这个状态。 
footerNavMenuOpen$ = this.store$.select(selectUiFooterNavMenuOpen);

这里的参数selectUiFooterNavMenuOpen是通过createSelecto返回的对state中,ui状态中某个特定属性名称。

当这个facade被注入到父组件page中,通过模板绑定时候

<footer [navMenuIsOpen]="ui.footerNavMenuOpen$ | async" , .... ></footer>

它又重新流回到了footer 组件里。

  @Input() navMenuIsOpen = false;

在footer 的模板里,我们又可以愉快地使用这个简单的变量来决定是否显示某些部分了。

 <div class="panel" *ngIf="!navMenuIsOpen">
    <!-- only for menu is open -->
  </div>

总结。在这个任务里,我们实现了一种”数据流“的闭环。即用户触发某个事件,该事件改变store中的某个状态,rxjs通知订阅该状态的”订阅者“,订阅者收到通知后完成自己的更新,比如更改dom. ,然后等待下个事件的触发。

这就是响应式编程 Reactive Programming。里面提到的Oberservble,就是streaming,是一种数据流,习惯上我们在命名变量的时候,需要在”流变量“名字后面加上一个$,来提示程序员,这是一个”流“。

ng-content内容投影

在review同事的修改的时候,发现了他使用ng-content来替换本来的一堆东西。那么这个ng-content 的内容是如何决定的呢? 通过2篇文章大概知道了这个东西的作用。

文章1 https://medium.com/@joshblf/wtf-is-ng-content-8382b2a664e1

文章2 https://segmentfault.com/a/1190000010730597

今天学习到的新概念就是: 内容投影 (content projection). 看来组件复用在angular里实现的真的比较彻底。

把synegy替换为barier

synergy是一款在多台主机之间共享鼠标和键盘的共享软件,开源跨多平台。但是现在已经商业化,而且最近发现有个bug,即当服务器端某些情况下会失去相应。

所以开始寻在替代品,找到了这个Barier (URL: https://github.com/debauchee/barrier )

作为synergy的继承者基本相同。但是我的一台客户机是mac os 10.11 El Captian,它只能使用 Baiere v2.1 。 服务器端我是使用ubuntu, 本地编译即可。

来源: https://github.com/debauchee/barrier/issues/544