我跟朋友说,咱们开直播吧。

朋友问,直播什么?
这真是个好问题,朋友是医生。
我说那就直播什么药不治病吧。

我跟朋友说,咱们开直播吧。
朋友问,直播什么?
这真是个好问题,朋友是医生。
我说那就直播什么药不治病吧。
最近在更新job的配置时经常出现以上的报错,开始还误以为是百度效率云的icode出了问题。跟百度效率云的团队反馈,对方一直没有响应,不知道是解散了(开个玩笑),还是觉得这不是个问题。
检索这个问题,发现很多文章都说取消全局安全配置中的CSRF Protection的勾选即可,但是我的jenkins里没有这个勾选框了。
然后又检索到https://www.cnblogs.com/kazihuo/p/12937071.html说
Jenkins版本自2.204.6以来的重大变更有:删除禁用 CSRF 保护的功能。 从较旧版本的Jenkins 升级的实例将启用 CSRF 保护和设置默认的发行者,如果之前被禁用。
这篇文章给的办法是在启动jenkins时添加一个配置
-Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true
来实现这个关闭。
但是这样很不优雅,尤其是我有两个jenkins,一个基本上是最新版,一个是为了兼容百度效率云的插件而保留的一个很老的版本。最新版是直接在服务器上跑的jar版本,老版本是用的docker。以上的方法就不好玩了。
所以受到https://stackoverflow.com/questions/49888756/how-do-you-disable-jenkins-csrf-with-script的启发,我安装了一个Strict Crumb Issuer插件,然后在跨站请求伪造保护这里,选择这个插件来工作,配置默认。保存就好了。
Aysel这个用了很长一段时间了,算是比较干净的一个模板,不过不知道为什么突然发现没有评论框了,而且一直一来也觉得code块显示的效果不好。
试了好几个,终于选定这个Appointment,还算比较清爽的,暂时也没有商业版本。写博客比起在其他地方发表东西还是觉得自主一些,虽然也未必有什么特别有价值的信息。
动过发表视频的念头,也在youtube上传过几段航拍的视频,不过想不出拿什么主题来坚持下去,好多事情不好说。
最近,大概又要建起阅读这个事情来了。具体情况请看niuduer.com,如果有进展的话。
都调试起来以后,连接打印机,发现打印机根本没反应,网上找到的相关资料很少,大部分都是在windows或者linux上做的,难道是mac的osx有一些安全限制,导致打印的指令被拦截了。
于是照着这个思路查下去,终于找到了一个新的东西:CUPS。其实这个东西支持linux也支持mac,按照说明添加上打印机之后,确实能在mac的打印机列表中看到了,而且在系统打开一个文件用这个打印机打印,是有动作的,尽管是瞎走纸,没有真正的输出。但至少说明是有希望了。
那么为什么用electron-escpos还是无法打印呢,甚至依然连走纸反应都没有。
无奈又去得力的官网看了看,找到888B这个打印机的说明书,仔细瞅了一眼,竟然发现它说他的编程语言是TSPL,不兼容ESCPOS,擦,过于相信刚找到escpos这个神奇的协议的时候它所说的几乎所有的打印机都支持了。
https://blog.csdn.net/weixin_34355881/article/details/89543300这篇文章介绍了打印机主流的指令类型(ESC命令集+CPCL命令集+TSPL命令集)之间的区别。这就解释了上面我对打印机类型的模糊认识
好了,标签打印机一般用TSPL命令集,票据打印机一般用ESCPOS。而我用的得力888B(NEW)是标签打印机。
那么,就需要将原来的escpos换成tspl来写打印命令。
接上一篇,分清楚了两种模块的规范,那么怎么解决两种规范的不同呢,似乎可以通过配置babel来实现,于是我在babel.config.js中尝试了很多办法,都没有收效,归根结底是还没有搞清楚vue和electron之间是如何各自适用这些规范的。
按照某种说法,最新的vue是遵循ES6,而electron或者说node模块是CommonJs,但是,在项目中,npm install进来的模块都放在node_modules中,怎么区分呢,如果不是babel.config.js来负责,那就应该是electron相关的,于是我找到了electronBuilder这个配置。
在vue.config.js(如果没有则在项目根目录新建)中:
module.exports = {
configureWebpack: {
devtool: "source-map"
},
pluginOptions: {
electronBuilder: {
// List native deps here if they don't work
externals: ["escpos", "escpos-usb"]
// If you are using Yarn Workspaces, you may have multiple node_modules folders
// List them all here so that VCP Electron Builder can find them
}
}
// chainWebpack: config => {
// config.module
// .rule("js")
// .test(/\.jsx?$/)
// .exclude.clear()
// .end()
// .include.add(function() {
// return ["./node_modules/escpos", "./node_modules/escpos-usb", "src"];
// })
// .end();
// }
};
这个发现得益于https://medium.com/@nyorikakar/printing-with-vue-electron-and-node-f52a730e63e7这篇文章,而且我还在后面的评论中发现了https://github.com/song940/node-escpos/issues/297,最终靠这些信息搞清楚了逻辑。
(1)对于用于node的模块,需要在vue.config.js的externals那里列出,这样,vue就不会让babel啥的那些loader去处理了。
(2)负责和node打交道的代码要放在background.js中,这在前面第二个连接中可以看到,而且最关键的是在vue的代码因为是通过BrowserWindow加载的,在其初始化是webPreferences中的nodeIntegration这个属性需要配置为true,const { ipcRenderer } = window.require(“electron”);才能用。而且,这个true如果是放在.env中不能直接给process.env.ELECTRON_NODE_INTEGRATION=true,那样,调到的是字符串,不是布尔值,会出现下面的报错:
Uncaught TypeError: window.require is not a function
at Module../node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/App.vue?vue&type=script&lang=js& (App.vue:22)
at __webpack_require__ (bootstrap:853)
at fn (bootstrap:150)
at Module../src/App.vue?vue&type=script&lang=js& (App.vue?c53a:1)
at __webpack_require__ (bootstrap:853)
at fn (bootstrap:150)
at Module../src/App.vue (App.vue:1)
at __webpack_require__ (bootstrap:853)
at fn (bootstrap:150)
at Module../src/main.js (HelloWorld.vue?adfd:1)
接上一篇,选择vue+electron之后,那就按electron-vue这个来。虽然能跑起来,但是代码上传到git以后,收到很多高危报警,https://github.com/futuremeng/electron-vue-escpos-bridge
尝试升级一下,结果发现因为版本已经差太多,需要花很多时间修,遂放弃。通过检索,发现有一个新的方案,https://nklayman.github.io/vue-cli-plugin-electron-builder/。
于是,开启新的https://github.com/futuremeng/vue-electron-builder-escpos-printer-bridge
先用vue cli4创建一个新的项目,再vue add electron-builder。尝试运行yarn electron:serve 的时候提示Vue Devtools下载失败,需要翻墙跑成功一遍才行。
接下来分析打印机如何连接,通过检索发现escpos这个协议,据说是大部分打印机都支持的。那么是否可以用escpos直接驱动打印机呢,网上有树莓派的示范。
在寻找合适的escpos驱动的时候,发现了各种版本的,除了java、python,还有php和node,我决定选择node版的https://www.npmjs.com/package/escpos。
但是,当然当我尝试引入到项目的时候,悲剧发生了。
ERROR Failed to compile with 1 errors 16:30:59
error in ./node_modules/escpos/statuses.js
Module parse failed: Unexpected token (7:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|
| class DeviceStatus {
byte = ”;
| bits = [];
| bitsAsc = [];
@ ./node_modules/escpos/index.js 12:17-38
@ ./node_modules/cache-loader/dist/cjs.js??ref–12-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref–0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=script&lang=js&
@ ./src/App.vue?vue&type=script&lang=js&
@ ./src/App.vue
@ ./src/main.js
@ multi (webpack)-dev-server/client?http://192.168.3.139:8080&sockPath=/sockjs-node (webpack)/hot/dev-server.js ./src/main.js
见到是loader的问题,我就尝试配置babel-loader script-loader file-loader。都没有解决问题,实际上,我也不是很了解这些loader到底是干什么的。
在这个过程中,了解到CommonJS和ES6这些区别,还有,在网页版的vue项目和electron中还涉及到运行环境的问题,网页中没有办法直接调用node接口。
前情回顾:做了一个网站,需要在网页上打印二维码,将热敏打印机连到电脑上,在网页上直接用print打印出来的二维码完全无法识别,应该是分辨率的问题,因为屏幕的分辨率和打印机的分辨率差太多。所以寻找解决方案,找到了c-lodop.com这个网站提供的中间件,需要付费,而且只有win版。
需求分析:现在重构网站,计划做成saas模式,在打印模块上,需要尽量摆脱第三方的束缚,所以构思如何自己实现。
网页到打印机,这中间是网页-浏览器-操作系统-usb-打印机,这样一个路径。经过确认,网页直接连打印机是不显示的,有一个比较接近的办法是通过chrome的app方案,但通用性不高,放弃,那就只剩下跟lodop一样的模式了,要么把整个网站构建成桌面程序,要么通过中间件来连打印机,网页再通过http或者socket驱动中间件。
当然,选择一个中间件是比较合适的,整个后台构建成桌面程序,没有必要,维护起来也太笨重。
接下来,就是选择跨平台的桌面程序方案来做这个中间件了。需要实现几个部分,一是http或者socket,二是打印机连接,中间的打印机连接管理。
当然,首选相对比较熟悉的vue+electron的方案。
老家的房子,没有多少人住了,房子没有人住,就坏的快了。
我家的屋脊瓦片滑脱,需要重新盖压,找不到人。
我小姑家的房梁塌陷,找不到包工队承接修复的活儿。
虽然做了确权,但是不知道什么时候就要拆了,所以没有办法投入改造成度假的拥有现代居住条件的房子,村子里的环境也不是一家两家能改善的。
前几年有说法是乡村沦陷,这是真的,沦陷不在于乡村的沉沦,而在于完整产权的丧失。
对应百度效率云的这个文档:https://cloud.baidu.com/doc/XLY/s/Fjwvy8aq6#jenkins-%E6%8F%92%E4%BB%B6%E7%94%A8%E6%88%B7%E6%8C%87%E5%8D%97
由于官方的文档用起来很多误解,这里做一下简单的说明,方便大家使用。
首先是jenkins的安装。由于百度效率云目前的jenkins插件比较老,用最新版的jenkins无法配置成功,所有需要为百度效率云部署一个专用的jenkins,这里我称之为中继jenkins。最初,我是按百度的文档所提到的方式,下载jenkis.war,并使用
nohup java -Dfile.encoding=utf-8 -Dhudson.model.ParametersAction.keepUndefinedParameters=true -jar jenkins.war –httpPort=8888 &
这个命令来部署,同时我的业务jenkins是用docker的方式部署。后来,我将业务jenkins改为yum install jenkins直接安装在宿主机了,于是需要把这个效率云jenkins改为docker,避免冲突。
docker run -d -u root –restart=always -p 8888:8080 -v /jenkins_xly:/var/jenkins_home –name jenkins_xly -idt jenkins:2.19.1
运行后打开IP:8888,即是通常的账户密码初始化过程,接下来是插件,我取消了所有插件的安装,因为这个jenkins实例只用来转发百度效率云的构建推送。
ipipe-agent.hpi,地址在文章开头那个链接中,通过百度网盘下载。在系统管理-插件管理-高级那里上传这个插件。
回到系统管理,找到iPipe agent management,按照提示填写几个字段。
点击Save,正常的情况下就直接跳转了,没有报错,如果有问题,会有报错,比如用最新版的jenkins,可以装上这个插件,但在这里提交时会报错,问题出在有一个JenkinsUUID的参数,在最新版的jenkins上是空的,我跟百度效率云团队提过这个问题,但至今尚未修复。所以只好多此一举,继续用jenkins2.19.1来中继。
item name即项目名称,尽量用英文字母写清楚,前面提到了,这个名字会出现在效率云中作为选择job的依据。
因为我前面部署这个中继时没有安装其他插件,所以我这里只需要选择构建一个自由风格的软件项目即可。而实际上,这个job需要做的也只是转发一下请求。
在job的General配置中,找到iPipe配置,只需要填写项目标识,这个项目标识跟ipipeUrl中那个项目名是一回事儿,但实际上效率云在相应的项目中显示相关job时应该是以这个job中配置的项目名为准,而前面ipipeUrl中那个项目名应该是插件的历史遗留问题,早期只考虑到一个项目的注册方式。
然后在构建Build中添加一个执行shell,只添加一行命令:
curl {你的业务jenkins的某个job的webhook地址}
job的配置到此结束。
接下来,我们先去效率云验证下这个job能否被触发。
按照百度效率云的文档配置流水线即可,需要注意的是我开始有一个误区,就是代码触发时要选merge,而不是change。否则提交代码到代码库时不会触发流水线。
最后,简单提一下我们的业务jenkins需要做什么配置来响应中继jenkins的curl请求,这个未必是最好的方式,因为不能传递参数了,也许应该用触发远程构建之类的实现,我对jenkins还不够了解。
假定按curl的话,我们需要在业务jenkins安装一个generic-webhook-trigger插件,然后在业务jenkins的job中启用这个插件的配置,填写token这个参数,这个token只要在当前的jenkins的jobs中不重复即可,但为了方便识别,我一般会加上项目标识,比如itemname-rR74nddfdsfs23mm
然后上面curl后面的网址就有了,格式是
http://JENKINS_URL/generic-webhook-trigger/invoke?token={token}
有朋友在负责丰台站和雄安站的装修项目,听说进展比较顺利,而京雄高铁往南就过衡水到商丘,最终到台湾,全程成为京台高铁。
我在衡水的房子里新规划的衡水南高铁站差不多5公里,算是一个利好。不过,前几天回老家,一个老家的已经当了爷爷的大哥提到高铁一脸的不屑,说修的越多越赔钱,我想这倒也是事实,以目前的票价,回衡水的高铁票差不多要100块,如果是5个人来回就是一千,比开车的过路费和油钱加起来还多,况且,就算做高铁到了衡水还是要接着打车。
这么算下来,即使通了高铁,我多半也是不会坐高铁回家的。
事实上,高铁也确实是贷款赔钱,这些钱是摊在所有老百姓头上的。