-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
514 lines (421 loc) · 51.9 KB
/
index.html
File metadata and controls
514 lines (421 loc) · 51.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Jackless - Python、Go、DevOps、Docker、Kubernetes</title><meta name="keywords" content="Python、Go、DevOps、Docker、Kubernetes"><meta name="author" content="Jackless"><meta name="copyright" content="Jackless"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="Jackless blog">
<meta property="og:type" content="website">
<meta property="og:title" content="Jackless">
<meta property="og:url" content="https://jackless.cf/index.html">
<meta property="og:site_name" content="Jackless">
<meta property="og:description" content="Jackless blog">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://img.jackless.cf/202111211217351.jpeg">
<meta property="article:author" content="Jackless">
<meta property="article:tag" content="Python、Go、DevOps、Docker、Kubernetes">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://img.jackless.cf/202111211217351.jpeg"><link rel="shortcut icon" href="/img/favicon.png"><link rel="canonical" href="https://jackless.cf/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//hm.baidu.com"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><meta name="google-site-verification" content="UkjYb9NMX_wE4Ru7aoFPU0qyez5BO-9tH058yHpmBVc"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css" media="print" onload="this.media='all'"><script>var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?e51a57dc19008056321e7b3d7fcd560a";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script><script>const GLOBAL_CONFIG = {
root: '/',
algolia: undefined,
localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容:${query}"}},
translate: undefined,
noticeOutdate: undefined,
highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
copy: {
success: '复制成功',
error: '复制错误',
noSupport: '浏览器不支持'
},
relativeDate: {
homepage: false,
post: false
},
runtime: '天',
date_suffix: {
just: '刚刚',
min: '分钟前',
hour: '小时前',
day: '天前',
month: '个月前'
},
copyright: {"limitCount":50,"languages":{"author":"作者: Jackless","link":"链接: ","source":"来源: Jackless","info":"著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。"}},
lightbox: 'fancybox',
Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#121212","position":"bottom-left"},
source: {
jQuery: 'https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js',
justifiedGallery: {
js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
},
fancybox: {
js: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js',
css: 'https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css'
}
},
isPhotoFigcaption: false,
islazyload: true,
isanchor: true
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
title: 'Jackless',
isPost: false,
isHome: true,
isHighlightShrink: undefined,
isToc: false,
postUpdate: '2022-02-19 08:14:15'
}</script><noscript><style type="text/css">
#nav {
opacity: 1
}
.justified-gallery img {
opacity: 1
}
#recent-posts time,
#post-meta time {
display: inline !important
}
</style></noscript><script>(win=>{
win.saveToLocal = {
set: function setWithExpiry(key, value, ttl) {
if (ttl === 0) return
const now = new Date()
const expiryDay = ttl * 86400000
const item = {
value: value,
expiry: now.getTime() + expiryDay,
}
localStorage.setItem(key, JSON.stringify(item))
},
get: function getWithExpiry(key) {
const itemStr = localStorage.getItem(key)
if (!itemStr) {
return undefined
}
const item = JSON.parse(itemStr)
const now = new Date()
if (now.getTime() > item.expiry) {
localStorage.removeItem(key)
return undefined
}
return item.value
}
}
win.getScript = url => new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = url
script.async = true
script.onerror = reject
script.onload = script.onreadystatechange = function() {
const loadState = this.readyState
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
script.onload = script.onreadystatechange = null
resolve()
}
document.head.appendChild(script)
})
win.activateDarkMode = function () {
document.documentElement.setAttribute('data-theme', 'dark')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
}
}
win.activateLightMode = function () {
document.documentElement.setAttribute('data-theme', 'light')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
}
}
const t = saveToLocal.get('theme')
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified
if (t === undefined) {
if (isLightMode) activateLightMode()
else if (isDarkMode) activateDarkMode()
else if (isNotSpecified || hasNoSupport) {
const now = new Date()
const hour = now.getHours()
const isNight = hour <= 6 || hour >= 18
isNight ? activateDarkMode() : activateLightMode()
}
window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
if (saveToLocal.get('theme') === undefined) {
e.matches ? activateDarkMode() : activateLightMode()
}
})
} else if (t === 'light') activateLightMode()
else activateDarkMode()
const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
if (asideStatus === 'hide') {
document.documentElement.classList.add('hide-aside')
} else {
document.documentElement.classList.remove('hide-aside')
}
}
const detectApple = () => {
if (GLOBAL_CONFIG_SITE.isHome && /iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
document.documentElement.classList.add('apple')
}
}
detectApple()
})(window)</script><!-- hexo injector head_end start --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/css/main.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/l-lin/font-awesome-animation/dist/font-awesome-animation.min.css" media="defer" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-butterfly-tag-plugins-plus@latest/lib/tag_plugins.min.css" media="defer" onload="this.media='all'"><script async src="https://cdn.jsdelivr.net/npm/hexo-butterfly-tag-plugins-plus@latest/lib/carousel-touch.min.js"></script><!-- hexo injector head_end end --><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="Jackless" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111211217351.jpeg" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data"><div class="data-item is-center"><div class="data-item-link"><a href="/archives/"><div class="headline">文章</div><div class="length-num">9</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/tags/"><div class="headline">标签</div><div class="length-num">5</div></a></div></div><div class="data-item is-center"><div class="data-item-link"><a href="/categories/"><div class="headline">分类</div><div class="length-num">2</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/message/"><i class="fa-fw fas fa-list"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="page" id="body-wrap"><header class="full_page" id="page-header" style="background-image: url('http://img.jackless.cf/202111221443706.jpg')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/">Jackless</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/message/"><i class="fa-fw fas fa-list"></i><span> 留言板</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="site-info"><h1 id="site-title">Jackless</h1><div id="site-subtitle"><span id="subtitle"></span></div><div id="site_social_icons"><a class="social-icon" href="https://github.com/ljd1995" rel="external nofollow noreferrer" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:ljd19950912@gmail.com" rel="external nofollow noreferrer" target="_blank" title="Email"><i class="fas fa-envelope"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="fas fa-rss"></i></a></div></div><div id="scroll-down"><i class="fas fa-angle-down scroll-down-effects"></i></div></header><main class="layout" id="content-inner"><div class="recent-posts" id="recent-posts"><div class="recent-post-item"><div class="post_cover left_radius"><a href="/post/50c5b9ad/" title="博客撰写计划"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149497.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="博客撰写计划"></a></div><div class="recent-post-info"><a class="article-title" href="/post/50c5b9ad/" title="博客撰写计划">博客撰写计划</a><div class="article-meta-wrap"><span class="article-meta"><i class="fas fa-thumbtack sticky"></i><span class="sticky">置顶</span><span class="article-meta__separator">|</span></span><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-21T11:26:37.000Z" title="发表于 2021-11-21 19:26:37">2021-11-21</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/python/">python</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/go/">go</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/devops/">devops</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/linux/">linux</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/%E8%BF%90%E7%BB%B4/">运维</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/50c5b9ad/#post-comment"><span class="waline-comment-count" id="/post/50c5b9ad/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">缘起
这些年记忆力越来越差,趁我还没老,趁我还在从事运维开发的工作,在这里记录下运维以及运维开发过程中经验,分享下运维以及运维开发的技术实战,分享尽量以项目实战为主!
运维管理平台项目
CMDB
WEBSSH
任务管理
发布部署
操作日志
权限管理
用户管理
模拟K8s管理系统
docker管理
容器调度
容器编排
模拟salt/Ansible
SSH形式、短连接模式、websocket长连接模式
...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/post/679a57d2/" title="ITIL和DevOps"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149494.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="ITIL和DevOps"></a></div><div class="recent-post-info"><a class="article-title" href="/post/679a57d2/" title="ITIL和DevOps">ITIL和DevOps</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-02-19T00:13:52.000Z" title="发表于 2022-02-19 08:13:52">2022-02-19</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/%E8%BF%90%E7%BB%B4/">运维</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/679a57d2/#post-comment"><span class="waline-comment-count" id="/post/679a57d2/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">ITILITIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部门CCTA(Central Computing and Telecommunications Agency)在20世纪80年代末制订,现由英国商务部OGC(Office of Government Commerce)负责管理,主要适用于IT服务管理(ITSM)。ITIL为企业的IT服务管理实践提供了一个客观、严谨、可量化的标准和规范。
1、事件管理(Incident Management)
事故管理负责记录、归类和安排专家处理事故并监督整个处理过程直至事故得到解决和终止。事故管理的目的是在尽可能最小地影响客户和用户业务的情况下使IT系统恢复到服务级别协议所定义的服务级别。
2、问题管理(Problem Management)
问题管理是指通过调查和分析IT基础架构的薄弱环节、查明事故产生的潜在原因,并制定解决事故的方案和防止事故再次发生的措施,将由于问题和事故对业务产生的负面影响减小到最低的服务管理流程。与事故管理强调 ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/post/c3df8a2e/" title="Web后端开发知识点"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149493.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Web后端开发知识点"></a></div><div class="recent-post-info"><a class="article-title" href="/post/c3df8a2e/" title="Web后端开发知识点">Web后端开发知识点</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2022-02-19T00:12:52.000Z" title="发表于 2022-02-19 08:12:52">2022-02-19</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/python/">python</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/go/">go</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/c3df8a2e/#post-comment"><span class="waline-comment-count" id="/post/c3df8a2e/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">做Web后端开发需要学习什么
学习一门面向对象的编程语言(java、python、go、nodejs、c#、php)
学习一个web框架(python:Flask/Django/Sanic go: Gin/Beego/GoFrame nodejs: egg.js koa express php: Larvel/ThinkPhp java: Spring全家桶)
学习关系型数据库(MySql/MariaDB/Postgresql)相关知识
学习缓存(Redis/Memcache)相关知识
学习消息队列(kafka/RabbitMQ)相关知识
Linux/网络/TCP IP协议…
Web后端框架知识点Request后端与前端交互的来源,Request需要掌握的知识点有
如何获取前端请求过来的参数,GET、POST请求参数如何获取
如何获取JSON格式的请求体
如何获取请求上传过来的文件,并保存这些文件
如何获取动态路由的参数
如何校验请求过来的参数是否符合要求
Response得益于http协议的定义,有请求就必须有响应,Response需要掌握的知识点有
如何响应文本类型数据
如 ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/post/1c8b7bb6/" title="模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212113587.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)"></a></div><div class="recent-post-info"><a class="article-title" href="/post/1c8b7bb6/" title="模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)">模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-28T08:29:51.000Z" title="发表于 2021-11-28 16:29:51">2021-11-28</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/python/">python</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/devops/">devops</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/linux/">linux</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/%E8%BF%90%E7%BB%B4/">运维</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/1c8b7bb6/#post-comment"><span class="waline-comment-count" id="/post/1c8b7bb6/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">前言前面讲了基于短连接的saltstack主要功能实现,今天我来讲讲基于长连接方式的saltstack实现。
长连接长连接和短连接的区别HTTP长连接、短连接究竟是什么?
使用的长连接实现模块websocket-clientgevent-websocket
这里没有使用websockets这个库来做长连接的客户端和服务端,主要考虑的是上面2个库来做客户端和服务端的代码更容易理解
由于以上2个模块都属于第三方库,所以需要使用如下命令先行安装
1pip install websocket-client gevent-websocket
具体代码实现长连接服务端1234567891011121314151617181920212223from geventwebsocket import WebSocketServer, WebSocketApplication, Resourcefrom collections import OrderedDictclass EchoApplication(WebSocketApplication): def on_open(self): ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/post/3de380ec/" title="模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149497.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)"></a></div><div class="recent-post-info"><a class="article-title" href="/post/3de380ec/" title="模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)">模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-24T13:44:31.000Z" title="发表于 2021-11-24 21:44:31">2021-11-24</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/python/">python</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/devops/">devops</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/linux/">linux</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/%E8%BF%90%E7%BB%B4/">运维</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/3de380ec/#post-comment"><span class="waline-comment-count" id="/post/3de380ec/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">前言前面讲了基于SSH的ansible实现,今天我来讲讲基于短连接方式的saltstack实现。
为什么要讲基于短连接的saltstack实现呢?
前面不是说saltstack是基于长连接的吗?原因就在于当你掌握了短连接的实现后,长连接就水到渠成了,你也更能理解到短连接和长连接实现的一个区别
Agent设计不管是短连接实现还是长连接实现,都需要在远程主机起一个服务来承担Agent角色,就如同saltstack的salt-minion 一样。
下面我们就基于flask来简单实现一个短连接形式的agent(考虑性能的话可以使用sanic,这里用flask的原因是本人团队内部培训时,我主要培训的是flask)
由于flask属于第三方库,所以需要使用如下命令先行安装
1pip install flask
如果想做成和salt-minion二进制模式启动的话,我们还需要安装一个额外的模块pyinstaller
1pip install pyinstaller
以下是flask作为一个服务端基本的代码: app.py
12345678910from flask import Flaska ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/post/b95044a6/" title="模拟 saltstack/ansible 系列二(实现ansible主要功能)"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212113587.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟 saltstack/ansible 系列二(实现ansible主要功能)"></a></div><div class="recent-post-info"><a class="article-title" href="/post/b95044a6/" title="模拟 saltstack/ansible 系列二(实现ansible主要功能)">模拟 saltstack/ansible 系列二(实现ansible主要功能)</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-23T11:43:51.000Z" title="发表于 2021-11-23 19:43:51">2021-11-23</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/python/">python</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/devops/">devops</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/linux/">linux</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/%E8%BF%90%E7%BB%B4/">运维</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/b95044a6/#post-comment"><span class="waline-comment-count" id="/post/b95044a6/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">前言本次主要分享是如何基于Python模拟实现ansible的主要功能
ansible功能分析与代码实现连接远程主机ansible连接远程主机是通过SSH实现的,因此我们可以通过Python的SSH模块来实现连接远程主机。
Python中SSH模块主要是三方的paramiko 模块,这个模块也是ansible内部实现SSH所用的模块。
由于paramiko属于第三方库,所以需要使用如下命令先行安装
1pip install paramiko
下面是使用paramiko进行SSH连接和SFTP连接的相关代码
获取一个SSH连接
123456789101112131415def get_ssh_conn(hostname, port, username, password): try: # 实例化SSHClient ssh_client = paramiko.SSHClient() # 当远程服务器没有本地主机的密钥时自动添加到本地,这样不用在建立连接的时候输入yes或no进行确认 ssh_client.set_missi ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/post/e4dbd1fc/" title="模拟saltstack/ansible系列一(序言)"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149493.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟saltstack/ansible系列一(序言)"></a></div><div class="recent-post-info"><a class="article-title" href="/post/e4dbd1fc/" title="模拟saltstack/ansible系列一(序言)">模拟saltstack/ansible系列一(序言)</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-22T13:12:52.000Z" title="发表于 2021-11-22 21:12:52">2021-11-22</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF/">技术</a><i class="fas fa-angle-right"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/python/">python</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/devops/">devops</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/linux/">linux</a><span class="article-meta__link">•</span><a class="article-meta__tags" href="/tags/%E8%BF%90%E7%BB%B4/">运维</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/e4dbd1fc/#post-comment"><span class="waline-comment-count" id="/post/e4dbd1fc/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">序言项目介绍
做过运维的同学应该都知道,saltstack 和ansible 都是运维常用的自动化工具,可以用来做批量系统配置、批量程序部署、批量运行命令等功能
本教程将分析saltstack和ansible的核心功能实现,然后自己用Python 实现一个类似saltstack和ansible的项目
saltstack、ansible原理
ansible
无Agent架构,基于SSH
ansible playbook可以按任务对批量主机编排
Python语言开发
saltstack
Agent架构,基于长连接
可以通过state文件来对批量主机编排
Python语言开发
自己如何开发一个实现ansible和saltstack基本功能的程序?具体实现功能
主机连接模式
SSH连接模式
短连接模式
websocket长连接模式
Ad-hoc
ping功能
执行命令功能
copy文件功能
fetch文件功能
模拟playbook、state文 ...</div></div></div><div class="recent-post-item"><div class="post_cover right_radius"><a href="/post/510972a/" title="M1 MAC安装ubuntu系统的另一个选择-Multipass"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149497.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="M1 MAC安装ubuntu系统的另一个选择-Multipass"></a></div><div class="recent-post-info"><a class="article-title" href="/post/510972a/" title="M1 MAC安装ubuntu系统的另一个选择-Multipass">M1 MAC安装ubuntu系统的另一个选择-Multipass</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-21T07:00:01.000Z" title="发表于 2021-11-21 15:00:01">2021-11-21</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E5%88%86%E4%BA%AB/">分享</a></span><span class="article-meta tags"><span class="article-meta__separator">|</span><i class="fas fa-tag"></i><a class="article-meta__tags" href="/tags/linux/">linux</a></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/510972a/#post-comment"><span class="waline-comment-count" id="/post/510972a/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">缘起
今年Apple发布了新款搭载M1 Pro和M1 Max芯片的Macbook Pro,看着那屏幕甚是喜欢,性能也是爆炸。由于自己用了快2年的豆子峡谷黑苹果,貌似是CPU硅脂没了,温度动不动100℃,导致系统自动死机或重启,于是果断换成了丐版标配的M1 Pro Macbook。别说,新版Mac真的香!
由于M1芯片基于ARM,所以一些软件或虚拟机都得搞成ARM的,试过Parallels Desktop,搞起来不是很方便,巧合的突然想起以前下载Ubuntu server镜像时看到Multipass工具,它可以快速的初始化一个Linux系统,于是搜索了下发现Multipass工具已支持ARM运行Linux。so,开干!
Multipass官网介绍
Multipass is a lightweight VM manager for Linux, Windows and macOS. It’s designed for developers who want a fresh Ubuntu environment with a single command. It uses KVM on ...</div></div></div><div class="recent-post-item"><div class="post_cover left_radius"><a href="/post/4a17b156/" title="Hello World"> <img class="post_bg" src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149492.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Hello World"></a></div><div class="recent-post-info"><a class="article-title" href="/post/4a17b156/" title="Hello World">Hello World</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2021-11-18T11:26:37.000Z" title="发表于 2021-11-18 19:26:37">2021-11-18</time></span><span class="article-meta"><span class="article-meta__separator">|</span><i class="fas fa-comments"></i><a href="/post/4a17b156/#post-comment"><span class="waline-comment-count" id="/post/4a17b156/"></span></a><span class="article-meta-label"> 条评论</span></span></div><div class="content">Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
Quick StartCreate a new post1$ hexo new "My New Post221"
More info: Writing
Run server1$ hexo server
More info: Server
Generate static files1$ hexo generate
More info: Generating
Deploy to remote sites1$ hexo deploy
More info: Deployment
</div></div></div><nav id="pagination"><div class="pagination"><span class="page-number current">1</span></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111211217351.jpeg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">Jackless</div><div class="author-info__description">分享技术,记录生活</div></div><div class="card-info-data"><div class="card-info-data-item is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">9</div></a></div><div class="card-info-data-item is-center"><a href="/tags/"><div class="headline">标签</div><div class="length-num">5</div></a></div><div class="card-info-data-item is-center"><a href="/categories/"><div class="headline">分类</div><div class="length-num">2</div></a></div></div><a class="button--animated" id="card-info-btn" target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/ljd1995"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/ljd1995" rel="external nofollow noreferrer" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="mailto:ljd19950912@gmail.com" rel="external nofollow noreferrer" target="_blank" title="Email"><i class="fas fa-envelope"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="fas fa-rss"></i></a></div></div><div class="sticky_layout"><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/post/679a57d2/" title="ITIL和DevOps"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149494.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="ITIL和DevOps"/></a><div class="content"><a class="title" href="/post/679a57d2/" title="ITIL和DevOps">ITIL和DevOps</a><time datetime="2022-02-19T00:13:52.000Z" title="发表于 2022-02-19 08:13:52">2022-02-19</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/post/c3df8a2e/" title="Web后端开发知识点"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149493.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="Web后端开发知识点"/></a><div class="content"><a class="title" href="/post/c3df8a2e/" title="Web后端开发知识点">Web后端开发知识点</a><time datetime="2022-02-19T00:12:52.000Z" title="发表于 2022-02-19 08:12:52">2022-02-19</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/post/1c8b7bb6/" title="模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212113587.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)"/></a><div class="content"><a class="title" href="/post/1c8b7bb6/" title="模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)">模拟 saltstack/ansible系列四(基于长连接实现salt主要功能)</a><time datetime="2021-11-28T08:29:51.000Z" title="发表于 2021-11-28 16:29:51">2021-11-28</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/post/3de380ec/" title="模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212149497.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)"/></a><div class="content"><a class="title" href="/post/3de380ec/" title="模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)">模拟 saltstack/ansible 系列三(基于短连接实现saltstack主要功能)</a><time datetime="2021-11-24T13:44:31.000Z" title="发表于 2021-11-24 21:44:31">2021-11-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/post/b95044a6/" title="模拟 saltstack/ansible 系列二(实现ansible主要功能)"><img src= "data:image/gif;base64,R0lGODdhAQABAPAAAMPDwwAAACwAAAAAAQABAAACAkQBADs=" data-lazy-src="http://img.jackless.cf/202111212113587.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="模拟 saltstack/ansible 系列二(实现ansible主要功能)"/></a><div class="content"><a class="title" href="/post/b95044a6/" title="模拟 saltstack/ansible 系列二(实现ansible主要功能)">模拟 saltstack/ansible 系列二(实现ansible主要功能)</a><time datetime="2021-11-23T11:43:51.000Z" title="发表于 2021-11-23 19:43:51">2021-11-23</time></div></div></div></div><div class="card-widget" id="card-newest-comments"><div class="item-headline"><i class="fas fa-comment-dots"></i><span>最新评论</span></div><div class="aside-list"><span>正在加载中...</span></div></div><div class="card-widget card-categories"><div class="item-headline">
<i class="fas fa-folder-open"></i>
<span>分类</span>
</div>
<ul class="card-category-list" id="aside-cat-list">
<li class="card-category-list-item "><a class="card-category-list-link" href="/categories/%E5%88%86%E4%BA%AB/"><span class="card-category-list-name">分享</span><span class="card-category-list-count">8</span></a></li><li class="card-category-list-item "><a class="card-category-list-link" href="/categories/%E6%8A%80%E6%9C%AF/"><span class="card-category-list-name">技术</span><span class="card-category-list-count">6</span></a></li>
</ul></div><div class="card-widget card-tags"><div class="item-headline"><i class="fas fa-tags"></i><span>标签</span></div><div class="card-tag-cloud"><a href="/tags/python/" style="font-size: 1.45em; color: rgb(92, 84, 12)">python</a><a href="/tags/go/" style="font-size: 1.15em; color: rgb(124, 172, 80)">go</a><a href="/tags/devops/" style="font-size: 1.3em; color: rgb(90, 76, 182)">devops</a><a href="/tags/linux/" style="font-size: 1.45em; color: rgb(196, 126, 165)">linux</a><a href="/tags/%E8%BF%90%E7%BB%B4/" style="font-size: 1.45em; color: rgb(10, 34, 112)">运维</a></div></div><div class="card-widget card-archives"><div class="item-headline"><i class="fas fa-archive"></i><span>归档</span></div><ul class="card-archive-list"><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2022/02/"><span class="card-archive-list-date">二月 2022</span><span class="card-archive-list-count">2</span></a></li><li class="card-archive-list-item"><a class="card-archive-list-link" href="/archives/2021/11/"><span class="card-archive-list-date">十一月 2021</span><span class="card-archive-list-count">7</span></a></li></ul></div></div></div></main><footer id="footer" style="background-image: url('http://img.jackless.cf/202111221443706.jpg')"><div id="footer-wrap"><div class="copyright">©2021 - 2022 By Jackless</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener external nofollow noreferrer" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script>function panguFn () {
if (typeof pangu === 'object') pangu.autoSpacingPage()
else {
getScript('https://cdn.jsdelivr.net/npm/pangu/dist/browser/pangu.min.js')
.then(() => {
pangu.autoSpacingPage()
})
}
}
function panguInit () {
if (false){
GLOBAL_CONFIG_SITE.isPost && panguFn()
} else {
panguFn()
}
}
document.addEventListener('DOMContentLoaded', panguInit)</script><script src="/js/search/local-search.js"></script><script>var preloader = {
endLoading: () => {
document.body.style.overflow = 'auto';
document.getElementById('loading-box').classList.add("loaded")
},
initLoading: () => {
document.body.style.overflow = '';
document.getElementById('loading-box').classList.remove("loaded")
}
}
window.addEventListener('load',preloader.endLoading())</script><div class="js-pjax"><script>(() => {
function loadWaline () {
function initWaline () {
let initData = {
el: null,
serverURL: 'https://blog-comment-js38sj1b8-jackless.vercel.app',
}
const waline = new Waline(initData)
}
if (typeof Waline === 'function') initWaline()
else getScript('https://cdn.jsdelivr.net/npm/@waline/client/dist/Waline.min.js').then(initWaline)
}
window.pjax ? loadWaline() : window.addEventListener('load', loadWaline)
})()</script><script>function subtitleType () {
fetch('https://v1.hitokoto.cn')
.then(response => response.json())
.then(data => {
if (true) {
var from = '出自 ' + data.from
var sub = "".length == 0 ? new Array() : "".split(',')
var both = sub.unshift(data.hitokoto, from)
var typed = new Typed('#subtitle', {
strings: sub,
startDelay: 300,
typeSpeed: 150,
loop: true,
backSpeed: 50,
})
} else {
document.getElementById('subtitle').innerHTML = data.hitokoto
}
})
}
if (true) {
if (typeof Typed === 'function') {
subtitleType()
} else {
getScript('https://cdn.jsdelivr.net/npm/typed.js/lib/typed.min.js').then(subtitleType)
}
} else {
subtitleType()
}
</script></div><script>window.addEventListener('load', () => {
const changeContent = (content) => {
if (content === '') return content
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code
content = content.replace(/<[^>]+>/g,"") // remove html tag
if (content.length > 150) {
content = content.substring(0,150) + '...'
}
return content
}
const getIcon = (ava,mail) => {
if (ava) return ava
let defaultIcon = '?d=monsterid'
let iconUrl = "https://seccdn.libravatar.org/avatar/" + mail + defaultIcon
return iconUrl
}
const generateHtml = array => {
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class=\'aside-list-item\'>'
if (true) {
const name = 'data-lazy-src'
result += `<a href='${array[i].url}' class='thumbnail'><img ${name}='${array[i].avatar}' alt='${array[i].nick}'></a>`
}
result += `<div class='content'>
<a class='comment' href='${array[i].url}'>${array[i].content}</a>
<div class='name'><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '没有评论'
}
let $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh($dom)
}
const getComment = () => {
const loadWaline = () => {
Waline.Widget.RecentComments({
serverURL: 'https://blog-comment-js38sj1b8-jackless.vercel.app',
count: 6
}).then(res => {
const walineArray = res.comments.map(e => {
return {
'content': changeContent(e.comment),
'avatar': getIcon(e.QQAvatar,e.mail),
'nick': e.nick,
'url': e.url + '#' + e.objectId,
'date': e.updatedAt,
}
})
saveToLocal.set('waline-newest-comments', JSON.stringify(walineArray), 10/(60*24))
generateHtml(walineArray)
}).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "无法获取评论,请确认相关配置是否正确"
})
}
if (typeof Waline === 'function') loadWaline()
else getScript('https://cdn.jsdelivr.net/npm/@waline/client/dist/Waline.min.js').then(loadWaline)
}
const newestCommentInit = () => {
if (document.querySelector('#card-newest-comments .aside-list')) {
const data = saveToLocal.get('waline-newest-comments')
if (data) {
generateHtml(JSON.parse(data))
} else {
getComment()
}
}
}
newestCommentInit()
document.addEventListener('pjax:complete', newestCommentInit)
})</script><script defer="defer" id="fluttering_ribbon" mobile="true" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-fluttering-ribbon.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = false;
POWERMODE.mobile = true;
document.body.addEventListener('input', POWERMODE);
</script><script id="click-heart" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/click-heart.min.js" async="async" mobile="false"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><!-- hexo injector body_end start --><script data-pjax>function history_calendar_injector_config(){
var parent_div_git = document.getElementsByClassName('sticky_layout')[0];
var item_html = '<div class="card-widget card-history"><div class="card-content"><div class="item-headline"><i class="fas fa-clock fa-spin"></i><span>那年今日</span></div><div id="history-baidu" style="height: 100px;overflow: hidden"><div class="history_swiper-container" id="history-container" style="width: 100%;height: 100%"><div class="swiper-wrapper" id="history_container_wrapper" style="height:20px"></div></div></div></div>';
console.log('已挂载history_calendar')
// parent_div_git.innerHTML=item_html+parent_div_git.innerHTML // 无报错,但不影响使用(支持pjax跳转)
parent_div_git.insertAdjacentHTML("afterbegin",item_html) // 有报错,但不影响使用(支持pjax跳转)
}if( document.getElementsByClassName('sticky_layout')[0] && (location.pathname ==='/'|| '/' ==='all')){
history_calendar_injector_config()
} </script><script data-pjax src="https://cdn.jsdelivr.net/npm/swiper/swiper-bundle.min.js"></script><script data-pjax src="https://cdn.jsdelivr.net/gh/Zfour/Butterfly-card-history/baiduhistory/js/main.js"></script><script async src="//at.alicdn.com/t/font_2032782_8d5kxvn09md.js"></script><!-- hexo injector body_end end --></body></html>