From cee6e2d5b07287a4de8975e63fd0b0dd6cd3b0fb Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 22 Nov 2015 12:00:19 +0800 Subject: [PATCH 01/52] First commit --- .gitignore | 7 ++++ .gitmodules | 3 ++ _config.yml | 71 ++++++++++++++++++++++++++++++++++++ package.json | 19 ++++++++++ scaffolds/draft.md | 3 ++ scaffolds/page.md | 3 ++ scaffolds/post.md | 4 ++ source/_posts/hello-world.md | 37 +++++++++++++++++++ themes/landscape | 1 + 9 files changed, 148 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 _config.yml create mode 100644 package.json create mode 100644 scaffolds/draft.md create mode 100644 scaffolds/page.md create mode 100644 scaffolds/post.md create mode 100644 source/_posts/hello-world.md create mode 160000 themes/landscape diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..063b0e4c --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Thumbs.db +db.json +*.log +node_modules/ +public/ +.deploy*/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..1847a103 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "themes/landscape"] + path = themes/landscape + url = https://github.com/hexojs/hexo-theme-landscape.git diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..57e708ec --- /dev/null +++ b/_config.yml @@ -0,0 +1,71 @@ +# Hexo Configuration +## Docs: http://hexo.io/docs/configuration.html +## Source: https://github.com/hexojs/hexo/ + +# Site +title: Hexo +subtitle: +description: +author: John Doe +language: +timezone: + +# URL +## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' +url: http://yoursite.com +root: / +permalink: :year/:month/:day/:title/ +permalink_defaults: + +# Directory +source_dir: source +public_dir: public +tag_dir: tags +archive_dir: archives +category_dir: categories +code_dir: downloads/code +i18n_dir: :lang +skip_render: + +# Writing +new_post_name: :title.md # File name of new posts +default_layout: post +titlecase: false # Transform title into titlecase +external_link: true # Open external links in new tab +filename_case: 0 +render_drafts: false +post_asset_folder: false +relative_link: false +future: true +highlight: + enable: true + line_number: true + auto_detect: true + tab_replace: + +# Category & Tag +default_category: uncategorized +category_map: +tag_map: + +# Date / Time format +## Hexo uses Moment.js to parse and display date +## You can customize the date format as defined in +## http://momentjs.com/docs/#/displaying/format/ +date_format: YYYY-MM-DD +time_format: HH:mm:ss + +# Pagination +## Set per_page to 0 to disable pagination +per_page: 10 +pagination_dir: page + +# Extensions +## Plugins: http://hexo.io/plugins/ +## Themes: http://hexo.io/themes/ +theme: landscape + +# Deployment +## Docs: http://hexo.io/docs/deployment.html +deploy: + type: \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..f39f5e7e --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "hexo-site", + "version": "0.0.0", + "private": true, + "hexo": { + "version": "" + }, + "dependencies": { + "hexo": "^3.1.0", + "hexo-generator-archive": "^0.1.2", + "hexo-generator-category": "^0.1.2", + "hexo-generator-index": "^0.1.2", + "hexo-generator-tag": "^0.1.1", + "hexo-renderer-ejs": "^0.1.0", + "hexo-renderer-stylus": "^0.3.0", + "hexo-renderer-marked": "^0.2.4", + "hexo-server": "^0.1.2" + } +} \ No newline at end of file diff --git a/scaffolds/draft.md b/scaffolds/draft.md new file mode 100644 index 00000000..45b1bb75 --- /dev/null +++ b/scaffolds/draft.md @@ -0,0 +1,3 @@ +title: {{ title }} +tags: +--- diff --git a/scaffolds/page.md b/scaffolds/page.md new file mode 100644 index 00000000..f484b761 --- /dev/null +++ b/scaffolds/page.md @@ -0,0 +1,3 @@ +title: {{ title }} +date: {{ date }} +--- diff --git a/scaffolds/post.md b/scaffolds/post.md new file mode 100644 index 00000000..c590d7a7 --- /dev/null +++ b/scaffolds/post.md @@ -0,0 +1,4 @@ +title: {{ title }} +date: {{ date }} +tags: +--- diff --git a/source/_posts/hello-world.md b/source/_posts/hello-world.md new file mode 100644 index 00000000..d2f98927 --- /dev/null +++ b/source/_posts/hello-world.md @@ -0,0 +1,37 @@ +title: Hello World +--- +Welcome to [Hexo](http://hexo.io/)! This is your very first post. Check [documentation](http://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](http://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). + +## Quick Start + +### Create a new post + +``` bash +$ hexo new "My New Post" +``` + +More info: [Writing](http://hexo.io/docs/writing.html) + +### Run server + +``` bash +$ hexo server +``` + +More info: [Server](http://hexo.io/docs/server.html) + +### Generate static files + +``` bash +$ hexo generate +``` + +More info: [Generating](http://hexo.io/docs/generating.html) + +### Deploy to remote sites + +``` bash +$ hexo deploy +``` + +More info: [Deployment](http://hexo.io/docs/deployment.html) diff --git a/themes/landscape b/themes/landscape new file mode 160000 index 00000000..22476aa9 --- /dev/null +++ b/themes/landscape @@ -0,0 +1 @@ +Subproject commit 22476aa92700b9e243f9c6516c886bc0fdd00cfd From e35c9b780511add8e3d54350e1f1e81ef38bc2ba Mon Sep 17 00:00:00 2001 From: leesei Date: Tue, 8 Dec 2015 10:23:09 +0800 Subject: [PATCH 02/52] wrap front matter in `---` so GitHub can preview it in a table Changes to be committed: modified: scaffolds/draft.md modified: scaffolds/page.md modified: scaffolds/post.md modified: source/_posts/hello-world.md --- scaffolds/draft.md | 1 + scaffolds/page.md | 1 + scaffolds/post.md | 1 + source/_posts/hello-world.md | 1 + 4 files changed, 4 insertions(+) diff --git a/scaffolds/draft.md b/scaffolds/draft.md index 45b1bb75..498e95ba 100644 --- a/scaffolds/draft.md +++ b/scaffolds/draft.md @@ -1,3 +1,4 @@ +--- title: {{ title }} tags: --- diff --git a/scaffolds/page.md b/scaffolds/page.md index f484b761..f01ba3cd 100644 --- a/scaffolds/page.md +++ b/scaffolds/page.md @@ -1,3 +1,4 @@ +--- title: {{ title }} date: {{ date }} --- diff --git a/scaffolds/post.md b/scaffolds/post.md index c590d7a7..1f9b9a46 100644 --- a/scaffolds/post.md +++ b/scaffolds/post.md @@ -1,3 +1,4 @@ +--- title: {{ title }} date: {{ date }} tags: diff --git a/source/_posts/hello-world.md b/source/_posts/hello-world.md index d2f98927..e8110e3c 100644 --- a/source/_posts/hello-world.md +++ b/source/_posts/hello-world.md @@ -1,3 +1,4 @@ +--- title: Hello World --- Welcome to [Hexo](http://hexo.io/)! This is your very first post. Check [documentation](http://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](http://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). From f6279645115483d22382f1b4eaf0017e49ab1535 Mon Sep 17 00:00:00 2001 From: leesei Date: Tue, 8 Dec 2015 14:22:00 +0800 Subject: [PATCH 03/52] highlight:auto_detect default as false Changes to be committed: modified: _config.yml --- _config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_config.yml b/_config.yml index 57e708ec..b7d669e0 100644 --- a/_config.yml +++ b/_config.yml @@ -40,7 +40,7 @@ future: true highlight: enable: true line_number: true - auto_detect: true + auto_detect: false tab_replace: # Category & Tag @@ -68,4 +68,4 @@ theme: landscape # Deployment ## Docs: http://hexo.io/docs/deployment.html deploy: - type: \ No newline at end of file + type: From cf813091b5002e73d62f53aa441b3e921d553851 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 13 Dec 2015 21:17:28 +0800 Subject: [PATCH 04/52] Update theme to latest commit --- themes/landscape | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/landscape b/themes/landscape index 22476aa9..cec7746c 160000 --- a/themes/landscape +++ b/themes/landscape @@ -1 +1 @@ -Subproject commit 22476aa92700b9e243f9c6516c886bc0fdd00cfd +Subproject commit cec7746c852676d311246c789a0f0a0f28da4c9f From 18988b038a57f70f391c82096b9f9f9989ec7d62 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 13 Dec 2015 21:20:12 +0800 Subject: [PATCH 05/52] Use HTTPS url for hexo.io --- _config.yml | 8 ++++---- source/_posts/hello-world.md | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/_config.yml b/_config.yml index b7d669e0..26c27e99 100644 --- a/_config.yml +++ b/_config.yml @@ -1,5 +1,5 @@ # Hexo Configuration -## Docs: http://hexo.io/docs/configuration.html +## Docs: https://hexo.io/docs/configuration.html ## Source: https://github.com/hexojs/hexo/ # Site @@ -61,11 +61,11 @@ per_page: 10 pagination_dir: page # Extensions -## Plugins: http://hexo.io/plugins/ -## Themes: http://hexo.io/themes/ +## Plugins: https://hexo.io/plugins/ +## Themes: https://hexo.io/themes/ theme: landscape # Deployment -## Docs: http://hexo.io/docs/deployment.html +## Docs: https://hexo.io/docs/deployment.html deploy: type: diff --git a/source/_posts/hello-world.md b/source/_posts/hello-world.md index e8110e3c..c090297c 100644 --- a/source/_posts/hello-world.md +++ b/source/_posts/hello-world.md @@ -1,7 +1,7 @@ --- title: Hello World --- -Welcome to [Hexo](http://hexo.io/)! This is your very first post. Check [documentation](http://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](http://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). +Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). ## Quick Start @@ -11,7 +11,7 @@ Welcome to [Hexo](http://hexo.io/)! This is your very first post. Check [documen $ hexo new "My New Post" ``` -More info: [Writing](http://hexo.io/docs/writing.html) +More info: [Writing](https://hexo.io/docs/writing.html) ### Run server @@ -19,7 +19,7 @@ More info: [Writing](http://hexo.io/docs/writing.html) $ hexo server ``` -More info: [Server](http://hexo.io/docs/server.html) +More info: [Server](https://hexo.io/docs/server.html) ### Generate static files @@ -27,7 +27,7 @@ More info: [Server](http://hexo.io/docs/server.html) $ hexo generate ``` -More info: [Generating](http://hexo.io/docs/generating.html) +More info: [Generating](https://hexo.io/docs/generating.html) ### Deploy to remote sites @@ -35,4 +35,4 @@ More info: [Generating](http://hexo.io/docs/generating.html) $ hexo deploy ``` -More info: [Deployment](http://hexo.io/docs/deployment.html) +More info: [Deployment](https://hexo.io/docs/deployment.html) From d3e5a4f9044508a2eef9c79a2f023fb09d93699e Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 13 Dec 2015 21:20:21 +0800 Subject: [PATCH 06/52] Update dependencies --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f39f5e7e..c6c23a04 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,14 @@ "version": "" }, "dependencies": { - "hexo": "^3.1.0", - "hexo-generator-archive": "^0.1.2", - "hexo-generator-category": "^0.1.2", - "hexo-generator-index": "^0.1.2", - "hexo-generator-tag": "^0.1.1", + "hexo": "^3.1.1", + "hexo-generator-archive": "^0.1.3", + "hexo-generator-category": "^0.1.3", + "hexo-generator-index": "^0.2.0", + "hexo-generator-tag": "^0.1.2", "hexo-renderer-ejs": "^0.1.0", "hexo-renderer-stylus": "^0.3.0", - "hexo-renderer-marked": "^0.2.4", + "hexo-renderer-marked": "^0.2.6", "hexo-server": "^0.1.2" } } \ No newline at end of file From 205dc1a6a9fcbbc48e620c61b5d5c7da6f2b2635 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 7 Feb 2016 17:20:49 +0800 Subject: [PATCH 07/52] Update deps --- package.json | 10 +++++----- themes/landscape | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c6c23a04..68ba7b61 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,13 @@ }, "dependencies": { "hexo": "^3.1.1", - "hexo-generator-archive": "^0.1.3", + "hexo-generator-archive": "^0.1.4", "hexo-generator-category": "^0.1.3", "hexo-generator-index": "^0.2.0", - "hexo-generator-tag": "^0.1.2", - "hexo-renderer-ejs": "^0.1.0", + "hexo-generator-tag": "^0.2.0", + "hexo-renderer-ejs": "^0.1.1", "hexo-renderer-stylus": "^0.3.0", - "hexo-renderer-marked": "^0.2.6", - "hexo-server": "^0.1.2" + "hexo-renderer-marked": "^0.2.9", + "hexo-server": "^0.1.3" } } \ No newline at end of file diff --git a/themes/landscape b/themes/landscape index cec7746c..a9c29e94 160000 --- a/themes/landscape +++ b/themes/landscape @@ -1 +1 @@ -Subproject commit cec7746c852676d311246c789a0f0a0f28da4c9f +Subproject commit a9c29e946aa5ec058b5a108583815cf1510c1dc6 From fbf4d54b565cd7a1a1ca53d227182dc3d2df4779 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 28 Feb 2016 02:16:11 +0800 Subject: [PATCH 08/52] Update theme submodule --- themes/landscape | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/landscape b/themes/landscape index a9c29e94..8bdbcfb7 160000 --- a/themes/landscape +++ b/themes/landscape @@ -1 +1 @@ -Subproject commit a9c29e946aa5ec058b5a108583815cf1510c1dc6 +Subproject commit 8bdbcfb7ec053a1a255e4bbcfcf00a3ceb18aacd From 1628db7329dba6b82a4d21882e696680401e609f Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Sun, 28 Feb 2016 11:58:30 +0800 Subject: [PATCH 09/52] Update theme submodule --- themes/landscape | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/landscape b/themes/landscape index 8bdbcfb7..decdc2d9 160000 --- a/themes/landscape +++ b/themes/landscape @@ -1 +1 @@ -Subproject commit 8bdbcfb7ec053a1a255e4bbcfcf00a3ceb18aacd +Subproject commit decdc2d9956776cbe95420ae94bac87e22468d38 From 221419b9b86d6be0f811c4f244eb2160ea2ac9c6 Mon Sep 17 00:00:00 2001 From: Tommy Chen Date: Mon, 29 Feb 2016 18:06:59 +0800 Subject: [PATCH 10/52] Update dependencies --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 68ba7b61..04a426e3 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,14 @@ "version": "" }, "dependencies": { - "hexo": "^3.1.1", + "hexo": "^3.2.0", "hexo-generator-archive": "^0.1.4", "hexo-generator-category": "^0.1.3", "hexo-generator-index": "^0.2.0", "hexo-generator-tag": "^0.2.0", - "hexo-renderer-ejs": "^0.1.1", - "hexo-renderer-stylus": "^0.3.0", - "hexo-renderer-marked": "^0.2.9", - "hexo-server": "^0.1.3" + "hexo-renderer-ejs": "^0.2.0", + "hexo-renderer-stylus": "^0.3.1", + "hexo-renderer-marked": "^0.2.10", + "hexo-server": "^0.2.0" } } \ No newline at end of file From afd4eddb3e64ce50ba172841a5aa8d8222563b39 Mon Sep 17 00:00:00 2001 From: Abner Chou Date: Tue, 11 Jul 2017 10:31:05 -0400 Subject: [PATCH 11/52] Update _config.yml --- _config.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 26c27e99..8cadcdc8 100644 --- a/_config.yml +++ b/_config.yml @@ -42,7 +42,16 @@ highlight: line_number: true auto_detect: false tab_replace: - + +# Home page setting +# path: Root path for your blogs index page. (default = '') +# per_page: Posts displayed per page. (0 = disable pagination) +# order_by: Posts order. (Order by date descending by default) +index_generator: + path: '' + per_page: 10 + order_by: -date + # Category & Tag default_category: uncategorized category_map: From 288af02591f2deab5f5581fccd8ae56b85ea82cf Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 16 Jul 2017 22:04:57 +0800 Subject: [PATCH 12/52] add cource --- .gitignore | 1 + .gitmodules | 3 - _config.yml | 64 ++- package.json | 12 +- source/_posts/hello-world.md | 38 -- source/_posts/live/summary-2016.org | 61 +++ .../tech/emacs/elpy/python_goto_define.org | 124 +++++ source/_posts/tech/emacs/emacs_keys.org | 493 ++++++++++++++++++ .../_posts/tech/linux/arch/arch_install.org | 102 ++++ source/_posts/tech/linux/arch/laptop-mode.org | 41 ++ source/_posts/tech/linux/install_flash.org | 18 + source/_posts/tech/linux/proxychains.org | 39 ++ .../_posts/tech/python/django/django_401.md | 118 +++++ source/_posts/tech/python/flask/flask_env.org | 41 ++ .../_posts/tech/python/pep8_pycodestyle.org | 36 ++ source/_posts/tech/python/py3_2_diff.org | 26 + .../tech/python/some_python_phenomenon.org | 109 ++++ source/assets/favicon.ico | Bin 0 -> 4286 bytes source/assets/img/alipay.jpg | Bin 0 -> 50393 bytes source/assets/img/flytrap.jpg | Bin 0 -> 7498 bytes source/assets/img/weixin.jpg | Bin 0 -> 48916 bytes themes/landscape | 1 - themes/yilia | 1 + yilia_config.yml | 118 +++++ 24 files changed, 1391 insertions(+), 55 deletions(-) delete mode 100644 source/_posts/hello-world.md create mode 100644 source/_posts/live/summary-2016.org create mode 100644 source/_posts/tech/emacs/elpy/python_goto_define.org create mode 100644 source/_posts/tech/emacs/emacs_keys.org create mode 100644 source/_posts/tech/linux/arch/arch_install.org create mode 100644 source/_posts/tech/linux/arch/laptop-mode.org create mode 100644 source/_posts/tech/linux/install_flash.org create mode 100644 source/_posts/tech/linux/proxychains.org create mode 100644 source/_posts/tech/python/django/django_401.md create mode 100644 source/_posts/tech/python/flask/flask_env.org create mode 100644 source/_posts/tech/python/pep8_pycodestyle.org create mode 100644 source/_posts/tech/python/py3_2_diff.org create mode 100644 source/_posts/tech/python/some_python_phenomenon.org create mode 100644 source/assets/favicon.ico create mode 100644 source/assets/img/alipay.jpg create mode 100644 source/assets/img/flytrap.jpg create mode 100644 source/assets/img/weixin.jpg delete mode 160000 themes/landscape create mode 160000 themes/yilia create mode 100644 yilia_config.yml diff --git a/.gitignore b/.gitignore index 063b0e4c..039326b0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ Thumbs.db db.json *.log node_modules/ +hexo-org-cache/ public/ .deploy*/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 1847a103..e69de29b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "themes/landscape"] - path = themes/landscape - url = https://github.com/hexojs/hexo-theme-landscape.git diff --git a/_config.yml b/_config.yml index 8cadcdc8..31bd6894 100644 --- a/_config.yml +++ b/_config.yml @@ -3,16 +3,17 @@ ## Source: https://github.com/hexojs/hexo/ # Site -title: Hexo -subtitle: -description: -author: John Doe +title: 俗子 +subtitle: 无意之中是真意,随心而行 +description: 野生程序员一枚,传统文化和前沿科技的忠实拥护者,二者并不矛盾 +author: 俗子 language: timezone: +keywords: "django,后端,python,linux,程序员,形意,易,中医" # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' -url: http://yoursite.com +url: http://blog.flytrap.top root: / permalink: :year/:month/:day/:title/ permalink_defaults: @@ -54,8 +55,16 @@ index_generator: # Category & Tag default_category: uncategorized -category_map: -tag_map: +category_map: categories +tag_map: tags + +# Archives +## 2: Enable pagination +## 1: Disable pagination +## 0: Fully Disable +archive: 1 +category: 1 +tag: 1 # Date / Time format ## Hexo uses Moment.js to parse and display date @@ -72,9 +81,46 @@ pagination_dir: page # Extensions ## Plugins: https://hexo.io/plugins/ ## Themes: https://hexo.io/themes/ -theme: landscape +theme: yilia # Deployment ## Docs: https://hexo.io/docs/deployment.html deploy: - type: + type: git + repository: git@github.com:flytrap/flytrap.github.io.git + branch: master + + +jsonContent: + meta: false + pages: false + posts: + title: true + date: true + path: true + text: false + raw: false + content: false + slug: false + updated: false + comments: false + link: false + permalink: false + excerpt: false + categories: true + tags: true + +org: + emacs: 'D:\tools\emacs\bin\emacs.exe' + # emacs: /bin/emacs + common: | + #+OPTIONS: toc:nil + #+BIND: org-html-postamble \"Last Updated %C.
Render by hexo-renderer-org with %c\" + cachedir: './hexo-org-cache/' + +feed: + type: atom + path: atom.xml + limit: 20 + hub: + content: \ No newline at end of file diff --git a/package.json b/package.json index 04a426e3..b3e31a21 100644 --- a/package.json +++ b/package.json @@ -3,17 +3,21 @@ "version": "0.0.0", "private": true, "hexo": { - "version": "" + "version": "3.3.7" }, "dependencies": { - "hexo": "^3.2.0", + "hexo": "^3.3.7", + "hexo-deployer-git": "^0.3.0", "hexo-generator-archive": "^0.1.4", "hexo-generator-category": "^0.1.3", + "hexo-generator-feed": "^1.2.0", "hexo-generator-index": "^0.2.0", + "hexo-generator-json-content": "^3.0.1", "hexo-generator-tag": "^0.2.0", "hexo-renderer-ejs": "^0.2.0", - "hexo-renderer-stylus": "^0.3.1", "hexo-renderer-marked": "^0.2.10", + "hexo-renderer-org": "https://github.com/CodeFalling/hexo-renderer-org#emacs", + "hexo-renderer-stylus": "^0.3.1", "hexo-server": "^0.2.0" } -} \ No newline at end of file +} diff --git a/source/_posts/hello-world.md b/source/_posts/hello-world.md deleted file mode 100644 index c090297c..00000000 --- a/source/_posts/hello-world.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Hello World ---- -Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). - -## Quick Start - -### Create a new post - -``` bash -$ hexo new "My New Post" -``` - -More info: [Writing](https://hexo.io/docs/writing.html) - -### Run server - -``` bash -$ hexo server -``` - -More info: [Server](https://hexo.io/docs/server.html) - -### Generate static files - -``` bash -$ hexo generate -``` - -More info: [Generating](https://hexo.io/docs/generating.html) - -### Deploy to remote sites - -``` bash -$ hexo deploy -``` - -More info: [Deployment](https://hexo.io/docs/deployment.html) diff --git a/source/_posts/live/summary-2016.org b/source/_posts/live/summary-2016.org new file mode 100644 index 00000000..b06e336b --- /dev/null +++ b/source/_posts/live/summary-2016.org @@ -0,0 +1,61 @@ +#+TITLE:flytrap 2016 +#+DATE: <2017-02-04 Sat 17:49> +#+TAGS: coder, orgmode, read, book, 生活 +#+LAYOUT: post +#+CATEGORIES: live + +* 虚度2016 +** 读了几本不错的书 +*** 技术类: +- 代码整洁之道 +- python源码剖析 +- http权威指南 +- sqlite权威指南 +- python渗透测试 +- Linux 内核技术手册 +- + +*** 人物/历史: +- 卑鄙圣人曹操 +- 人类简史 +- 孙子兵法 +- 掘金黑客 + +** 新的语言 +- command lisp (这个值得研究) +- elisp (为了emacs嘛,这个是必须的, 算是离不开了) +- java (spark 工作需要,虽然写了没多久,算是入门吧) + +#+BEGIN_HTML + +#+END_HTML + +** 源码 +*** python +- python2 c源码,大致过了一遍,收获颇多. +- sqlmap 主要精力在整体框架上,略有收获 +- emacs linux kernel 环境 + +*** elsip +- elpy 由一个函数跳转问题引发的,不得不通读源码,大致了解了作者的思路,挺不错的python插件. +- 一些python相关的插件和大牛的配置. + +** 文档 +- python3 (tutorial,未完待续) +- elpy +- ecb +- arch +- i3-wm +- emacs(part) +- nethunter + +** 收获 +- python 并发处理(多进程,比较深刻,顺便看了不少python源代码) +- emacs(代码跳转,补齐,pep8) +- spark map,reduce思维 +- 代码整洁,工程管理 +- docker 各种环境搭建 +- arch i3 深入理解linux工作细节 +- blog 迁移至github page +- 日常linux +- one plus 2黑手nethunter(cm14) diff --git a/source/_posts/tech/emacs/elpy/python_goto_define.org b/source/_posts/tech/emacs/elpy/python_goto_define.org new file mode 100644 index 00000000..617f2b86 --- /dev/null +++ b/source/_posts/tech/emacs/elpy/python_goto_define.org @@ -0,0 +1,124 @@ +#+TITLE:python 代码跳转 +#+DATE: <2017-01-11 Wed 21:20> +#+TAGS: python, elpy +#+LAYOUT: post +#+CATEGORIES: tech + + +** summary +這裏使用的插件是elpy,代碼跳轉使用的是jedi +問題:No definition found +代碼結構: +#+begin_src shell +╰─➤ tree elpy_q +elpy_q +├── __init__.py +├── __main__.py +├── sub +│   ├── __init__.py +│   └── sub.py +└── sub2 + ├── __init__.py + └── sub2.py + +2 directories, 6 files +#+end_src +** code +*** __main__.py +#+begin_src python + 1│from sub2.sub2 import test2 + 2│ + 3│ + 4│test2() +#+end_src +*** sub.py +#+begin_src python + 1│import os + 2│ + 3│ + 4│def test(): + 5│ print('sub: ' + os.getcwd()) +#+end_src +*** sub2.py +#+begin_src python + 1│from sub.sub import test + 2│ + 3│ + 4│def test2(): + 5│ print('sub2 call sub') + 6│ test() +#+end_src +在文件sub2中跳轉到test位置,提示: +No definition found . +但是呢,sub1中明明是有的。 + +#+BEGIN_HTML + +#+END_HTML + +** analysis +#+begin_src elisp +1707│(defun elpy-goto-definition () +1708│ "Go to the definition of the symbol at point, if found." +1709│ (interactive) +1710│ (let ((location (elpy-rpc-get-definition))) +1711│ (if location +1712│ (elpy-goto-location (car location) (cadr location)) +1713│ (error "No definition found")))) +#+end_src +#+begin_src elisp +2721│(defun elpy-rpc--get-rpc-buffer () +2722│ "Return the RPC buffer associated with the current buffer, +2723│creating one if necessary." +2724│ (when (not (elpy-rpc--process-buffer-p elpy-rpc--buffer)) +2725│ (setq elpy-rpc--buffer +2726│ (or (elpy-rpc--find-buffer (elpy-library-root) +2727│ elpy-rpc-python-command) +2728│ (elpy-rpc--open (elpy-library-root) +2729│ elpy-rpc-python-command)))) +#+end_src +#+begin_src elisp +1226│(defun elpy-library-root () +1227│ "Return the root of the Python package chain of the current buffer. +1228│ +1229│That is, if you have /foo/package/module.py, it will return /foo, +1230│so that import package.module will pick up module.py." +1231│ (locate-dominating-file default-directory +1232│ (lambda (dir) +1233│ (not (file-exists-p +1234│ (format "%s/__init__.py" +1235│ dir)))))) +#+end_src +最後終於找到了elpy-library-root這個函數。 +代碼都快讀完了都沒有發現啥問題,不知道讀到這裏的聰明的你有沒有看出啥來。 +#+begin_src python + 27│ def __init__(self, project_root): + 28│ self.project_root = project_root + 29│ self.completions = {} + 30│ sys.path.append(project_root) +#+end_src +甚至在這裏把項目的路徑根都保存出來啦。 +發現一個問題,出現的這個路徑是有問題的,總是我項目的父路徑,爲什麼呢? +#+begin_src elisp + 27│ def __init__(self, project_root): + 28│ self.project_root = project_root + 29│ self.completions = {} + 30│ sys.path.append(project_root) +#+end_src +甚至在這裏把項目的路徑根都保存出來啦。 +發現一個問題,出現的這個路徑是有問題的,總是我項目的父路徑,爲什麼呢? +重點來了。 +#+begin_src elisp +(locate-dominating-file default-directory + (lambda (dir) + (not (file-exists-p + (format "%s/__init__.py" + dir)))))) +#+end_src +這個方法是用來幹嘛的?看半天沒看明白,後來才明白,是根據第二個參數向上級目錄遍歷, +直到找到滿足條件的目錄,然後把他的父目錄返回,就是我項目的父目錄。 +我們看到這個匿名函數是幹嘛的? +是檢查該目錄下有沒有"__init__.py"文件,思考一下,作者爲啥這麼寫呢。 +其實想想也挺簡單的,檢查這是不是一個包嘛,如果是包,就默認去找上級沒有"__init__.py". +** Reflection +代碼不規範,主函數怎麼能定義在包裏呢? diff --git a/source/_posts/tech/emacs/emacs_keys.org b/source/_posts/tech/emacs/emacs_keys.org new file mode 100644 index 00000000..b53ae06e --- /dev/null +++ b/source/_posts/tech/emacs/emacs_keys.org @@ -0,0 +1,493 @@ +#+TITLE: emacs快捷键 +#+DATE: <2016-12-10> +#+TAGS: emacs +#+LAYOUT: post +#+CATEGORIES: tech + +* base +** normal +| C-g | keyboard-quit | | +| C-x C-f | find-file | | +| C-x C-v | find-alternate-file | | +| C-x i | insert-file | | +| C-x C-s | save-buffer | | +| C-x C-w | write-file | # other file | +| C-x C-c | save-buffers-kill-emacs | | +| C-h | help-command | | +| C-h f | describe-function | | +| C-h k | describe-key | | +| C-h t | help-with-tutorial | | +| C-h i | info-goto-emacs-command-mode | | + +* file editor +** normal +| C-f | forward-char | | +| C-b | backward-char | | +| C-p | previous-line | | +| C-n | next-line | | +| ESC e | forward-sentence | | +| ESC a | backward-sentend | | +| ESC } | forward-paragraph | | +| ESC { | backward-paragraph | | +| C-v | scroll-up | | +| Esc v | scroll-down | | +| C-x ] | forward-page | # curor | +| C-x [ | backward-page | # curor | +| ESC < | beginning-of-buffer | # file-header | +| ESC > | end-of-buffer | # file-end | +| | goto-line | # point lines | +| | goto-char | # point char | +| C-l | recenter | # flush pic | +| ESC n | digit-argument | # repeat command | +| C-u n | universal-argument | # repeat command(defualt 4) | + +#+BEGIN_HTML + +#+END_HTML + +** delete +| C-d | delete-char | | +| DEL | delete-backward-char | | +| ESC d | kill-word | | +| ESC DEL | backward-kill-word | | +| C-k | kill-line | # del to end line | +| ESC k | kill-sentence | | +| C-x DEL | backward-kill-sentence | # sentence | +| C-y/SHIFT-INSERT | yank | # resore | +| C-w/SHIFT-DELETE | kill-region | # file->cut | +| | kill-paragraph | | +| | backward-kill-paragraph | | +** block +| C-@/C-SPACE | set-mark-command | +| C-x C-x | exchange-point-and-mark | +| ESC w/C-INSERT | kill-ring-save | +| ESC h | mark-paragraph | +| C-x C-p | mark-page | +| C-x h | mark-whole-buffer | +| ESC y | yank-pop | +** editor +| C-t | transpose-chars | # change char | +| ESC t | transpose-words | # change word | +| C-x C-t | transpose-lines | # change line | +| | transpose-sentences | | +| | transpose-paragraphs | | + +| ESC c | cpitalize-word | +| ESC n | upcase-word | +| ESC - ECS c | negitive-argument;captitalize-word | +| ESC - ESC u | negitive-argument;upcase-word | +| ESC - ESC l | negtive-argument;downcase-word | + +** other +| INSERT | overwrite-mode | | +| | rever-buffer | # reload file | +| C-x n | advertised-undo | # revoked | +| C-_/C-/ | undo | | +| | revert-buffer | # resotre to disk | +| | recover-file | # show auto save | +* find and replace +** isearch +| C-s | isearch-forward | | +| C-r | isearch-backward | | +| RETURN | | | +| C-g | keyboard-quit | | +| DEL | | | +| C-s C-w | | select word isearch | +| C-s ESC y | | delete word isearch | +| C-s C-s | | repeat | +** simple search +| C-s RETURN | | Search->Search | +| C-s | | next | +| C-r RETURN | | Search->Search Backwards | +| C-r | | back next | +** replace +| ESC % | | Search-Query Replace | +| SPACE/y | | new string relace old | +| DEL/n | | not replace | +| . | | replace and exit | +| , | | replace and stop (y)continue | +| \! | | next all replace | +| \^ | | return up replace location | +| RETURN/q | | quit query, replace option | +| C-r | | Recursion editor | +| ESC C-c | | quit Recursion status, continue | +| C-] | | quit Recursion,query,replace status | +ESC x set-variable RETURN case-fold-search RETURN nil RETURN # no case +** regexp +| ESC C-s RETURN | re-search-forward | +| ESC C-r RETURN | re-search-backward | +| ESC C-s | isearch-forward-regexp | +| ESC C-r | isearch-backward-regexp | +| | query-relace-regexp | +| | replace-regexp | +** Ispell +| ESC $ | ispell-word | check cur location word | +| | ispell-reglon | check text work | +| | ispell-buffer | check buffer work | +| | ispell-message | check email text | +| C-u ESC $ | ispell-continue | restart run | +| | ispell-kill-ispell | kill ispell | +| ESC TAB | ispell-complete-word | text auto completion | +** abbrev +| | abbrev-mode | on | +| C-x a - | inverse-add-global-abbrev | global | +| C-x a i g | | global | +| C-x a i l | inverse-add-mode-adrev | local | +| | unexpund-abbrev | undo | +| | write-abbrev-file | save file | +| | edit-abbrevs | | +| | list-abbrevs | view | +| | kill-all-abbrevs | off | +* buffer and window +** window +| C-x 2 | split-window-vertically | +| C-x 3 | split-window-borttontally | +| C-x > | scroll-right | +| C-x < | scroll-left | + +** buffer +| C-x b | switch-to-buffer | +| C-x C-b | list-buffer | +| C-x k | kill-buffer | +| | kill-some-buffer | +| | rename-buffer | +| C-x s | save-some-buffers | + +| C-x n | next-buffer | +| SPACE | next-buffer | +| C-p | per-buffer | +| d | add del tag 'x' run | +| k | add del tag 'x' run | +| s | add save tag | +| n | add opt tag | +| x | add run tag | +| DEL | del buffer tag | +| ~ | buffer add unchange tag | +| % | readonly | +| 1 | max | +| 2 | self and next buffer to same window | +| f | change buffer window | +| o | move to other window | +| m | buffer add visble tag | +| v | show 'm' command tag | +| q | exit buffer list | +** bookmark +| C-x r b | bookmark-jump | +| | bookmark-delete | +| C-x r l | bookmark-menu-list | +| d | bookmark-delete | +| r | bookmark-rename | +| s | bookmark-save | +| f | show tag | +| m | add show tag | +| v | add visble tag | +| t | change tab status | +| w | show file location | +| x | del d tag | +| u | del per tag | +| DEL | cancel tag opt | +| q | exit bookmark list | +| | bookmark-insert | +| | bookmark-write | +| | bookmark-load | +** window block +| C-x 5 o | other-frame | +| C-x 5 0 | delete-frame | +| C-x 5 2 | makr-frame | +| C-x 5 r | find-file-read-only-oher-frame | +| C-x 5 f | find-file-other-frame | +| C-x 5 b | swith-to-buffer-other-frame | + +* emacs work +** shell +| C-c C-c | comint-interrupt-subjob | +| C-d | comint-delchr-or-maybe-eof | +| C-c C-d | comint-send-eof | +| C-c C-u | comint-kill-input | +| C-c C-z | comint-stop-subjob | +| ESC p | comint-previous-input | +| ESC n | comint-send-input | +| RETURN | comint-send-input | +| TAB | comint-dynamic-complete | +| C-c C-o | comint-kill-output | +| C-c C-r | comint-show-output | +| C-c C-e | somint-show-maximum-output | +| C-c C-p | comint-previous-prompt | +| C-c C-n | comint-next-prompt | +** Dired +| C-x d | dired | +| C | Dired-do-copy | +| d | dired-flag-file-deletion | +| D | dired-to-delete | +| e | dired-find-file | +| f | dired-advertisd-find-file | +| g | rever-buffer | +| G | dired-do-chgrp | +| k | dired-do-kill-lines | +| m | dired-mark | +| n | dired-next-line | +| o | dired-find-file-other-window | +| C-o | dired-display-file | +| P | dired-do-print | +| q | dired-quit | +| Q | dired-do-query-replace | +| R | dired-do-rename | +| u | dired-unmark | +| v | dired-view-file | +| x | dired-do-flagged-delete | +| Z | dired-do-compress | +| ESC DEL | dired-unmark-all-files | +| ~ | dired-flag-backup-files | +| * | dired-mark-executables | +| # | dired-flag-auto-save-files | +| ` | dired-clean-directory | +| / | dired-mark-directories | +| = | dired-diff | +| ESC = | dired-bakup-diff | +| ! | dired-do-shell-command | +| ESC ) | dired-next-mark-file | +| ESC ( | dired-prev-marked-file | +| %d | dired-flag-files-regexp | +| %m | dired-mark-files-regexp | +| + | dired-creat-directory | +| > | dired-next-dirline | +| < | dired-prev-dirline | +| S | dired-sort-toggle-or-edit | +** print +| ESC x print-buffer | +| ESC x print-region | +| ESC x lpr-buffer | +| ESC x lpr-region | +| ESC x dired-do-print | +| ESC x ps-print-buffer-with-faces | +** time +| display-time | +| calendar | +** calendar +| . | calendar-goto-today | +| C-f | calendar-forward-day | +| C-b | calendar-backward-day | +| C-n | calendar-forward-week | +| C-p | calendar-backward-week | +| ESC } | calendar-forward-month | +| ESC { | calendar-backward-month | +| C-x ] | calendar-forward-year | +| C-x [ | calendar-backward-year | +| C-a | calendar-gedinning-of-week | +| C-e | calendar-end-of-week | +| ESC a | calendar-beginning-of-month | +| ESC e | calendar-end-of-month | +| ESC < | calendar-beginning-of-year | +| ESC > | calendar-beginning-of-year | +| C-u n | nuiversal-argument | +| g d | calendar-goto-date | +| o | calendar-other-month | +| C-x < | scroll-calendar-left | +| C-x > | scroll-calendar-right | +| SPACE | scroll-other-window | +* mail +** mail send +| C-x m | mail | +| C-x 4 m | mail-other-window | +| C-x 5 m | mail-other-frame | +| C-c C-f C-t | mail-to | +| C-c C-f C-c | mail-cc | +| C-c C-f C-b | mail-bcc | +| C-c C-f C-f | mail-fcc | +| C-c C-f C-r | mail-reply-to | +| C-c C-f C-s | mail-subject | +| C-c C-t | mail-text | +| C-c C-w | mail-signature | +| C-c C-c | mail-send-and-exit | +| C-c C-s | mail-send | +| | defind-mail-alias | +| | mail-dont-send | +** mail read +| SPACE | scroll-up | +| DEL | scroll-down | +| . | rmail-beginning-of-message | +| n | rmail-next-undeleted-message | +| p | rmail-previour-undeleted-message | +| < | rmail-first-message | +| > | rmail-last-message | +| j | rmail-show-message | +** del mail +| d | rmail-delete-forward | +| C-d | rmail-delete-backward | +| ESC n | rmail-next-message | +| ESC p | rmail-previous-message | +| u | rmail-undelete-previour-message | +| x | rmail-expunge | +| s | rmail-expunge-and-save | +** save mail +| o filename RETURN | rmail-output-to-rmail-file | +| C-o filename RETURN | rmail-output | +| i filename RETURN | rmail-input | +| | unrmail | +** gnus +| | gnus | +| SPACE | gnus-group-read-group | +| j | gnus-group-jump-to-group | +| n | gnus-group-next-unread-group | +| p | gnus-group-prev-unread-group | +| N | gnus-group-next-group | +| P | gnus-group-prev-group | +| < | beginning-of-buffer | +| > | end-of-buffer | +| u | gnus-group-unsubseribe-current-group | +| U | gnus-group-unsubscribe-group | +| c | gnus-group-catchup-current | +| C | gnus-group-catchup-current-all | +| A k | gnus-group-list-killed | +| I | gnus-group-list-groups | +| L | gnus-group-list-all-groups | +| g | gnus-group-get-new-news | +| R | gnus-group-restart | +| b | gnus-group-check-bogus-groups | +| a | gnus-group-post-news | +| C-x C-t | gnus-group-transpose-groups | +| s | gnus-group-save-newrc | +| z | gnus-group-suspend | +| q | gnus-group-exit | +| Q | gnus-group-quit | +| V | gnus-version | +*** summary +| SPACE | gnus-summary-next-page | | | | | +| DEL | gnus-summary-prev-page | | | | | +| RETURN | gnus-summary-scroll-up | | | | | +| . | gnus-summary-first-unread-article | | | | | +| < | gnus-summary-beginning-of-article | | | | | +| > | gnus-summary-end-of-article | | | | | +| n | gnus-summary-next-unread-artcle | | | | | +| N | gnus-summary-next-article | | | | | +| p | gnus-summary-prev-unread-article | | | | | +| P | gnus-summary-prev-article | | | | | +| l | gnus-summary-goto-last-article | | | | | +| H f | gnus-summary-fetch-faq | | | | | +| ESC C-t | gnus-summary-toggle-thread | | | | | +| ESC C-k | gnus-summary-kill-thread | | | | | +| ESC C-d | gnus-summary-down-thread | | | | | +| ESC C-u | gnus-summary-up-thread | | | | | +| ESC C-f | gnus-summary-next-thread | | | | | +| ESC C-b | gnus-summary-prev-thread | | | | | +| ESC C-h | gnus-summary-hide-thread | | | | | +| ESC C-s | gnus-summary-showthread | | | | | +| q | gnus-summary-exit | | | | | +| Q | gnus-summary-exit | | | | | +| c | gnus-summary-catchup-and-exit | | | | | +| u | gnus-summary-tick-article-forward | | | | | +| U | gnus-summary-tic-article-backward | | | | | +| C-o | gnus-summary-save-article-mail | | | | | +| o | gnus-summary-save-article | | | | | +| d | gnus-summary-mark-as-read-backward | | | | | +| D | gnus-summary-mark-as-read-backward | | | | | +| j | guns-summary-goto-subject | | | | | +| ESC n | gnus-summary-next-unread-subject | | | | | +| ESC p | gnus-summary-prev-unread-subject | | | | | +| ESC C-n | gnus-summary-next-save-subject | | | | | +| ESC C-p | gnus-summary-prev-save-subject | | | | | +| m | gnus-summary-mail-other-window | | | | | +| C-c C-f | gnus-summary-mail-forward | | | | | +| = | guns-summary-expand-window | | | | | +| g | gnus-summary-show-article | | | | | +| s | gnus-summary-isearch-article | | | | | +| ESC s | gnus-summary-search-article-forward | | | | | +| ESC r | gnus-summary-search-article-backward | | | | | +| t | gnus-summary-toggle-header | | | | | +| w | gnus-summary-stop-page-breaking | | | | | +| x | gnus-summary-remove-lines-marked-as-read | | | | | +| C-c TAB | gnus-info-find-node | | | | | +| C-c C-r | gnus-summary-caesar-message | | | | | +| C-x C-s | gnus-summary-reselect-current-group | | | | | +| ESC t | gnus-summary-toggle-mime | | | | | +| ESC U | gnus-summary-clear-mark-backward | | | | | +| ESC u | gnus-summary-clear-mark-forward | | | | | +| C-t | gnus-summary-toggle-truncation | | | | | +| & | gnus-summary-execute-command | | | | | +| | gnus-summary-pipe-output | | | | | +| C-d | gnus-summary-rmail-digest | | | | | +*** filter +| C-k | gnus-summary-kill-same-subject | +| k | gnus-summary-kill-same-subject-and-select | +| ESC k | gnus-summary-edit-local-kill | +| ESC K | gnus-summary-edit-global-kill | +| C-c C-k C-a | gnus-kill-file-kill-by-author | +| C-c C-k C-s | gnus-kill-file-kill-by-subject | +| C-c C-c | gnus-kill-file-exit | +*** post article +| a | gnus-summary-post-news | +| r | gnus-summary-reply | +| R | gnus-summary-reply-with-original | +| f | gnus-summary-followup | +| F | gnus-summary-followup-with-original | +| C-c C-f C-n | news-reply-newsgroups | +| C-c C-f C-f | news-reply-followup-to | +| C-c C-f C-k | news-reply-keywords | +| C-c C-f C-d | news-reply-distribution | +| C-c C-f C-a | news-reply-summary | +| C-c C-y | news-reply-yank-original | +| C-c C-q | mail-fill-yanked-message | +| C-c C-r | gnus-summary-caesar-message | +| C-c C-c | news-inesw | +| C | gnus-summary-cancel-article | +* net tools +** telnet +| | tlenet | +| C-d | comint-delchar-or-maybe-eof | +| RETURN | telnet-send-input | +| C-c C-c | telnet-interrupt-subjob | +| C-c C-q | send-process-next-char | +| C-c C-d | comint-send-eof | +| C-c C-r | comint-show-output | +| ESC C-l | comint-show-output | +| C-c C-e | comint-show-maximum-output | +| C-c C-o | comint-kill-output | +| C-c C-z | telnet-c-z | +| C-c C-w | backward-kill-word | +| C-c C-u | comint-kill-input | +| ESC n | comint-next-input | +| ESC P | comint-previous-input | +** w3 +| | w3-follow-URL-at-point | +| | w3 | +| C-o | w3-fetch | +| SPACE | scroll-up | +| DEL | scroll-down | +| RETURN | w3-follow-link | +| < | w3-start-of-document | +| < | w3-end-of-document | +| TAB/n | w3-forward-link | +| b | w3-back-link | +| m | w3-complete-link | +| I | w3-goto-last-buffer | +| B | w3-backward-in-history | +| F | w3-forward-in-history | +| C-c C-b | w3-show-history-list | +| a | w3-hotlist-add-document | +| A | w3-hotlist-add-document-at-point | +| d | w3-hotlist-delete | +| H | w3-show-hotlist | +| b | w3-use-hotlist | +| | w3-rename-hotlist-entry | +| ESC RETURN | w3-follow-inlined-image | +| v | url-view-url | +| V | w3-view-this-url | +| k/C-k | w3-save-url | +| K | w3-save-this-url | +| s | w3-source-document | +| S | w3-source-document-point | +| o | w3-optn-local | +| U | w3-use-lines | +| ? | w3-help | +| Q/u | w3-leave-buffer | +| q | w3-quit | +| g/r | w3-reload-document | +| l | w3-goto-last-buffer | +| P | w3-print-url-under-point | +| p | w3-submit-bug | +| C-c C-v | w3-version | +| ESC s | w3-search | +| ESC m | w3-mail-current-document | +| ESC M | w3-mail-document-under-point | +| ESC TAB | w3-insert-this-url | +| | w3-import-netscape-bookmarks | diff --git a/source/_posts/tech/linux/arch/arch_install.org b/source/_posts/tech/linux/arch/arch_install.org new file mode 100644 index 00000000..889bcb38 --- /dev/null +++ b/source/_posts/tech/linux/arch/arch_install.org @@ -0,0 +1,102 @@ +#+TITLE: arch linux 安装 +#+DATE: <2016-12-04 Sun 22:20> +#+TAGS: linux, arch +#+LAYOUT: post +#+CATEGORIES: tech + +* arch linux install +** system install +*** download iso +#+begin_src bash +wget http://mirror.lzu.edu.cn/archlinux/iso/2016.10.01/archlinux-2016.10.01-dual.iso +md5sum archlinux-2016.10.01-dual.iso # make sure md5sum is true +#+end_src + +#+BEGIN_HTML + +#+END_HTML + +*** install arch system +running in iso # get a shell +#+begin_src shell +loadkeys us # set key layout +ping -c 2 qq.com # make sure connect to internet +timedatectl set-ntp true # update system time +lsblk /dev/sda # view disk part +fdisk /dev/sda # part install disk + --> n \n p \n \n +512M \n \n + --> n \n p \n \n \n w +fdisk -l # tow part disk +# sda 8:0 0 20G 0 disk +# ├─sda1 8:1 0 512M 0 part +# ├─sda2 8:2 0 15.5G 0 part +mkfs.fat /dev/sda1 # fomat part to fat32(boot) +mkfs.ext4 /dev/sda2 # fomat part to ext4(root) +mount /dev/sda2 /mnt # / part +mkdir -p /mnt/boot # make boot dir +mount /dev/sda1 /mnt/boot # sda1 is boot part +sed -i '/Score/{/China/!{n;s/^/#/}}' /etc/pacman.d/mirrorlist # command other score url +pacstrap /mnt base base-devel net-tools # start install system to disk +genfstab -U /mnt >> /mnt/etc/fstab # add mount table +arch_chroot /mnt # change root directory to install disk +echo flytrap > /etc/hostname # set hostname +passwd # input the same password to stdin, set root password +pacman -S zsh # install zsh +chsh -s /bin/zsh # change default shell to zsh +systemctl enable dhcpcd # the boot is start dhcp +pacman -S grub # install grub +grub-install --boot-directory=/boot /dev/sda # install grub to disk +grub-mkconfig -o /boot/grub/grub.cfg # retouch grub config file +exit # exit cur shell +reboot +#+end_src +system install ok!!! +Use root user login to system. +#+begin_src shell +echo $SHELL # /bin/zsh +# hwclock --systohc --utc +#+end_src +*** install arch desktop +i3 install ok!!! +#+begin_src shell +pacman -S xorg-server xorg-xinit # install xorg server and xinit +pacman -S i3 # install i3 desktop system +pacman -S xf86-video-vesa # device open sorce +cd /etc/X11/xinit/ # change xinit setting +# command last five line and add two line: +i3-wm & +exec i3 +startx +#+end_src +*** install arch to usb +install arch to usb + +#+begin_src shell +mount ~/soft/iso/archlinux-2016.10.01-dual.iso /mnt/iso/ # mount iso to disk +unsquashfs -d /tmp/arch ./x86_64/airootfs.sfs # system install env ready +fdisk /dev/sdc # part disk +fdisk /dev/sdc # part install disk + --> n \n p \n \n +256M \n \n + --> n \n p \n \n \n w +lsblk /dev/sdc # tow part disk +# sdc 8:32 1 7.4G 0 disk +# ├─sdc1 8:33 1 256M 0 part +# └─sdc2 8:34 1 7.1G 0 part +cd /tmp/arch # change pwd to arch env +cp /etc/resolv.conf etc/ +mount --rbind /proc/ proc/ +mount --rbind /sys/ sys/ +mount --rbind /dev/ dev/ +mount --rbind /run/ run/ +chroot . # change path +mkfs.fat /dev/sdc1 +mkfs.ext4 /dev/sdc2 +mount /dev/sdc2 /mnt/usb/ +mkdir -p /mnt/usb/boot/efi +mount /dev/sdc1 /mnt/usb/ +mount /dev/sdc1 /mnt/usb/boot/efi/ +mount --rbind /mnt mnt/ +sed -i '/Score/{/China/!{n;s/^/#/}}' /etc/pacman.d/mirrorlist +pacstrap /mnt base base-devel net-tools +... +#+end_src diff --git a/source/_posts/tech/linux/arch/laptop-mode.org b/source/_posts/tech/linux/arch/laptop-mode.org new file mode 100644 index 00000000..dce652c2 --- /dev/null +++ b/source/_posts/tech/linux/arch/laptop-mode.org @@ -0,0 +1,41 @@ +#+TITLE: laptop-mode 安装 +#+DATE: <2017-02-26 Sun 23:16> +#+TAGS: linux, laptop +#+LAYOUT: post +#+CATEGORIES: tech + + +* laptop-mode +** summary +Laptop Mode Tools 是一个 Linux 系统下的笔记本电源管理软件 +** install +#+begin_src shell +yaourt -Ss laptop-mode +yaourt -Syu laptop-mode-tools +#+end_src +** startup laptop-mode +#+begin_src shell +systemctl start laptop-mode +systemctl enable laptop-mode +#+end_src + +#+BEGIN_HTML + +#+END_HTML + +** setting +*** set brightness +editor /etc/laptop-mode/conf.d/lcd-brightness.conf +#+begin_src bash +CONTROL_BRIGHTNESS=1 + +BATT_BRIGHTNESS_COMMAND="echo 100" +LM_AC_BRIGHTNESS_COMMAND="echo 100" +NOLM_AC_BRIGHTNESS_COMMAND="echo 100" +BRIGHTNESS_OUTPUT="/sys/class/backlight/intel_backlight/brightness" +#+end_src +*** set network +editor /etc/laptop-mode/conf.d/ethernet.conf +#+begin_src bash +ETHERNET_DEVICES="enp0s25" # set network device +#+end_src diff --git a/source/_posts/tech/linux/install_flash.org b/source/_posts/tech/linux/install_flash.org new file mode 100644 index 00000000..805108e8 --- /dev/null +++ b/source/_posts/tech/linux/install_flash.org @@ -0,0 +1,18 @@ +#+TITLE: linux 安装flash +#+DATE: <2016-12-04 Sun 13:41> +#+TAGS: linux, flash +#+LAYOUT: post +#+CATEGORIES: tech + +* linux install flash +** firefox +#+begin_src bash +# download install_flash_player_11_linux.x86_64.tar.gz +mkdir firefox_flash +tar zxvf install_flash_player_11_linux.x86_64.tar.gz -C firefox_flash +cd firefox_flash +sudo cp usr/* /usr/ # cp flash lib +sudo cp libflashplayer.so /usr/lib/mozilla/plugins/ +# restart firefox +#+end_src + diff --git a/source/_posts/tech/linux/proxychains.org b/source/_posts/tech/linux/proxychains.org new file mode 100644 index 00000000..7b53df6e --- /dev/null +++ b/source/_posts/tech/linux/proxychains.org @@ -0,0 +1,39 @@ +#+TITLE: proxychains 实现终端代理 +#+DATE: <2016-11-29 Tue 00:15> +#+TAGS: proxychains, 命令行代理 +#+LAYOUT: post +#+CATEGORIES: tech + + +* proxychains +** desc +小夥伴都知道在瀏覽器中配置代理,在各種軟件中配置代理,可是終端呢? +很簡單,就這麼幹,這篇文章就是爲你解決這個問題的。 +** proxychains install +#+begin_src bash +pacman -Syu proxychains # arch +apt-get install proxychains # debian, ubuntu +yum/dnf install proxychains # redhat, centos, fedora +#+end_src +非root用戶,自動前面追加sudo +裝不了?沒關系,檢查自己的源。 + +#+BEGIN_HTML + +#+END_HTML + +** proxychains setting +#+begin_src bash +vim + /etc/proxychains.conf + +[ProxyList] +http 0.0.0.0 80 +socks4 0.0.0.0 4444 +socks5 0.0.0.0 5555 +# 只要一行,選擇自己的代理類型,修改之. +格式:代理類型 ip 端口 +#+end_src +** proxychains use +#+begin_src bash +proxychains command # proxychains 後面跟上你的命令就行咯. +#+end_src diff --git a/source/_posts/tech/python/django/django_401.md b/source/_posts/tech/python/django/django_401.md new file mode 100644 index 00000000..7f4c0073 --- /dev/null +++ b/source/_posts/tech/python/django/django_401.md @@ -0,0 +1,118 @@ +title: 关于不需要权限访问的接口,错误token,报401的解释 +date: 2017-06-25 20:10:33 +tags: django, python, token +layout: post +categories: tech +--- + +问题描述: +不需要权限接口,传入错误token,没有权限访问。 + +错误抛出位置(DRF框架) + +``` python +def perform_authentication(self, request): + """ + Perform authentication on the incoming request. + + Note that if you override this and simply 'pass', then authentication + will instead be performed lazily, the first time either + `request.user` or `request.auth` is accessed. + """ + request.user +``` +获取用户信息 + + + +``` python +@property + def user(self): + """ + Returns the user associated with the current request, as authenticated + by the authentication classes provided to the request. + """ + if not hasattr(self, '_user'): + self._authenticate() + return self._user +``` +没有user,则验证user + +``` python + def _authenticate(self): + """ + Attempt to authenticate the request using each authentication instance + in turn. + Returns a three-tuple of (authenticator, user, authtoken). + """ + for authenticator in self.authenticators: + try: + user_auth_tuple = authenticator.authenticate(self) + except exceptions.APIException: + self._not_authenticated() + raise # 异常抛出点 + + if user_auth_tuple is not None: + self._authenticator = authenticator + self.user, self.auth = user_auth_tuple + return + + self._not_authenticated() +``` + +获取通过token获取user(有token,才会验证) +``` python +def authenticate(self, request): + auth = get_authorization_header(request).split() + + if not auth or auth[0].lower() != self.keyword.lower().encode(): + return None + + if len(auth) == 1: + msg = _('Invalid token header. No credentials provided.') + raise exceptions.AuthenticationFailed(msg) + elif len(auth) > 2: + msg = _('Invalid token header. Token string should not contain spaces.') + raise exceptions.AuthenticationFailed(msg) + + try: + token = auth[1].decode() + except UnicodeError: + msg = _('Invalid token header. Token string should not contain invalid characters.') + raise exceptions.AuthenticationFailed(msg) + + return self.authenticate_credentials(token) + + def authenticate_credentials(self, key): + model = self.get_model() + try: + token = model.objects.select_related('user').get(key=key) + except model.DoesNotExist: + raise exceptions.AuthenticationFailed(_('Invalid token.')) # 异常抛出位置 + + if not token.user.is_active: + raise exceptions.AuthenticationFailed(_('User inactive or deleted.')) + + return (token.user, token) +``` + +``` python +def _not_authenticated(self): + """ + Set authenticator, user & authtoken representing an unauthenticated request. + + Defaults are None, AnonymousUser & None. + """ + self._authenticator = None + + if api_settings.UNAUTHENTICATED_USER: + self.user = api_settings.UNAUTHENTICATED_USER() # 得到AnonymousUser + else: + self.user = None + + if api_settings.UNAUTHENTICATED_TOKEN: + self.auth = api_settings.UNAUTHENTICATED_TOKEN() + else: + self.auth = None +``` +虽然得到了AnonymousUser, 但是依然抛出了异常 \ No newline at end of file diff --git a/source/_posts/tech/python/flask/flask_env.org b/source/_posts/tech/python/flask/flask_env.org new file mode 100644 index 00000000..c1d28f8b --- /dev/null +++ b/source/_posts/tech/python/flask/flask_env.org @@ -0,0 +1,41 @@ +#+TITLE: flask环境 +#+DATE: <2016-11-29 Tue 00:27> +#+TAGS: python, flask +#+LAYOUT: post +#+CATEGORIES: tech + +* flask env install +** install virtualenv +#+begin_src bash +pip install virtualenv +#+end_src +** install flask +#+begin_src bash +virtualenv --no-download flask_env # create virtualenv no download +source flask_env/bin/activate +pip install flask # bask pkg +#+end_src +** install flask ext +#+begin_src bash +pip install flask-Bootstrap # bootstrap forward +pip install flask-Script # auto +pip install flask-Moment # locate time +pip install flask-WTF # form auth +pip install Flask-SQLAlchemy # database manager +#+end_src + +#+BEGIN_HTML + +#+END_HTML + +裝不上? +有代理沒有? +有:請移步 + [[http://flytrap.github.io/2016/11/29/tech/linux/proxychains/][proxychains]] + 查看如何在命令行中使用代理。 +沒有: + 安裝命令後面追加 +#+begin_src bash +-i http://pypi.douban.com/simple # 豆瓣源 +#+end_src +也是一個不錯的選擇哦。 diff --git a/source/_posts/tech/python/pep8_pycodestyle.org b/source/_posts/tech/python/pep8_pycodestyle.org new file mode 100644 index 00000000..bdad9ba7 --- /dev/null +++ b/source/_posts/tech/python/pep8_pycodestyle.org @@ -0,0 +1,36 @@ +#+TITLE: pep8 pycodestyle 检查 +#+DATE: <2017-01-02 Mon 22:12> +#+TAGS: python, pep8 +#+LAYOUT: post +#+CATEGORIES: tech + +* pep8(pycodestyle) +** Summary +doc:Python style guide checker +用於檢查python代碼是否符合pep8標準, +該項目目前更名爲pycodestyle. +** install +#+begin_src python +pip install pep8 +#+end_src +** directory tree +#+begin_src shell +ls pep8* + +pep8.py + +pep8-1.7.0.dist-info +#+end_src +可以看到只有這一個文件. + +#+BEGIN_HTML + +#+END_HTML + +** usage +#+begin_src shell +python -m pep8 python_file_name.py +python_file_name.py:101:6: E225 missing whitespace around operator +--show-source # 顯示代碼 +#+end_src +這是最簡單的用法。當然還有很多選項,詳情請參考官方文檔,這裏只是聲明這個模塊的存在。 diff --git a/source/_posts/tech/python/py3_2_diff.org b/source/_posts/tech/python/py3_2_diff.org new file mode 100644 index 00000000..12aa5aa0 --- /dev/null +++ b/source/_posts/tech/python/py3_2_diff.org @@ -0,0 +1,26 @@ +#+TITLE: 关于py2和py3区别的一些记录 +#+DATE: <2016-11-27 Sun 12:36> +#+TAGS: python +#+LAYOUT: post +#+CATEGORIES: tech + + +* python2 and python3 lib different points +** Summary +記錄一些遇到的不同的包的位置。 +其實說白了python3所做的事情就是把這些包分了一下類,把原來的零散的包,歸納到了一起。 +** urllib +*** python2 +#+begin_src python +urllib. +urllib2. +#+end_src + +#+BEGIN_HTML + +#+END_HTML + +*** python3 +#+begin_src python +urllib. +#+end_src diff --git a/source/_posts/tech/python/some_python_phenomenon.org b/source/_posts/tech/python/some_python_phenomenon.org new file mode 100644 index 00000000..ac43b05e --- /dev/null +++ b/source/_posts/tech/python/some_python_phenomenon.org @@ -0,0 +1,109 @@ +#+TITLE: 一些python现象理解 +#+DATE: <2016-11-27 Sun 15:36> +#+TAGS: python +#+LAYOUT: post +#+CATEGORIES: tech + +* loop +** code +#+begin_src python +>items():pass +> +>y +>{'a': 1, 'b': 2} +#+end_src +** analysis +#+begin_src python +>x.iterms() # (('a', 1), ('b', 2)) +>k = 'a' +>y['a'] = 1 +>pass +>k = 'b' +>y['b'] = 2 +#+end_src + +#+BEGIN_HTML + +#+END_HTML + +* bool +** code +#+begin_src python +>"Hello" + True +>TypeError: Can't convert 'bool' object to str implicitly +>"Hello" * True +>'Hello' +#+end_src +** analysis +#+begin_src python +>int(True) # True 真實值爲1,參見python C源碼定義, True就是整型的特殊值. +>1 +#+end_src + +* hash +** code +#+begin_src python +>def greet(): return +>d = {greet: 1} +>d +>{: 1} +#+end_src +** analysis +#+begin_src python +>hasattr(greet, '__hash__') # True +>greet.__hash__() # -9223363285414220592 +#+end_src +function 是可哈希的,在其生成的一瞬間,就已經固定不變,包括其中參數的id + +* int +#+begin_src python +>x = 1 +>y = 1 +>x is y +>True +>x = 999 +>y = 999 +>x is y +>False +#+end_src +** analysis +詭異? +其實python在初始化的時候就把一部分整型對象生成好了(這個叫小整型對象池), +但是不可能所有的都生成,官方會測試出一個最佳值來在源碼中寫死; +大於其值,則重新生成,小於等於則直接返回給你,所以,你懂得. +999明顯大於,而1,明顯是直接返回的,只是內部引用增加了而已 +正常編譯應該是[-5,256]. +測試代碼: +#+begin_src python +# 1) +>x = -5 +>x is int(str(x)) # False +# 2) +>test_int = lambda x: x is int(str(x)) +>test_int(256) # True +# [-5, 256] return True +# <=-6, >=257 return False +#+end_src + +* tuple +** code +#+begin_src python +>a = [1, 0] +>a[0], a[a[0]] = a[a[0]], a[0] +>a +>[1, 0] +>a[a[0]], a[0] = a[0], a[a[0]] +>a +>[0, 1] +#+end_src +** analysis +不好理解?其實就是表達式看起來復雜了點兒,道理很簡單,看代碼 +#+begin_src python +>a[0], a[a[0]] = a[a[0]], a[0] +>>a[0] = a[a[0]]; a[a[0]] = a[0] +# 其實,這個時候最後一個a[0] 可以確定是1了,而第二個a[a[0]], 是a[0]賦值過一次之後才得到a[0] +>>>a[0] = a[1] # a[0]=0; a[0] = 1 # a-->[1, 0] +# 這個好理解 +>a[a[0]], a[0] = a[0], a[a[0]] +>>a[1] = 1; a[0] = a[1] # a-->[0, 1] +#+end_src diff --git a/source/assets/favicon.ico b/source/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f2a9fc32dd453834c8c423a1bac43e2ed913e97b GIT binary patch literal 4286 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 literal 0 HcmV?d00001 diff --git a/source/assets/img/alipay.jpg b/source/assets/img/alipay.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb0c97d6b0c63752f4742be5e6b5859ddfd9a15c GIT binary patch literal 50393 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 literal 0 HcmV?d00001 diff --git a/source/assets/img/flytrap.jpg b/source/assets/img/flytrap.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d606ac7f3ae4fd7a430c05c452f216da7354bc92 GIT binary patch literal 7498 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 Hgiv{7~TY%=F*TNYEo5-;Rf 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 g+$yaGu_1i2{>g76ugh($ literal 0 HcmV?d00001 diff --git a/themes/landscape b/themes/landscape deleted file mode 160000 index decdc2d9..00000000 --- a/themes/landscape +++ /dev/null @@ -1 +0,0 @@ -Subproject commit decdc2d9956776cbe95420ae94bac87e22468d38 diff --git a/themes/yilia b/themes/yilia new file mode 160000 index 00000000..4b889f5d --- /dev/null +++ b/themes/yilia @@ -0,0 +1 @@ +Subproject commit 4b889f5d00f3d8b74dfda3217179ad55b2e44a2b diff --git a/yilia_config.yml b/yilia_config.yml new file mode 100644 index 00000000..24070c69 --- /dev/null +++ b/yilia_config.yml @@ -0,0 +1,118 @@ +# Header + +menu: + 主页: / + 技术: /categories/tech/ + 随笔: /categories/live/ + +# SubNav +subnav: + github: "https://github.com/flytrap" + # weibo: "#" + rss: "/atom.xml" + zhihu: "http://zhihu.com/people/flytrap" + #qq: "#" + #weixin: "俗子" + #jianshu: "#" + #douban: "#" + #segmentfault: "#" + #bilibili: "#" + #acfun: "#" + #mail: "hiddenstat@gmail.com" + #facebook: "#" + #google: "#" + #twitter: "#" + #linkedin: "#" + +rss: /atom.xml + +# 是否需要修改 root 路径 +# 如果您的网站存放在子目录中,例如 http://yoursite.com/blog, +# 请将您的 url 设为 http://yoursite.com/blog 并把 root 设为 /blog/。 +root: + +# Content + +# 文章太长,截断按钮文字 +excerpt_link: more +# 文章卡片右下角常驻链接,不需要请设置为false +show_all_link: '查看全文' +# 数学公式 +mathjax: false +# 是否在新窗口打开链接 +open_in_new: false + +# 打赏 +# 打赏type设定:0-关闭打赏; 1-文章对应的md文件里有reward:true属性,才有打赏; 2-所有文章均有打赏 +reward_type: 2 +# 打赏wording +reward_wording: '谢谢老板请我吃糖果' +# 支付宝二维码图片地址,跟你设置头像的方式一样。比如:/assets/img/alipay.jpg +alipay: /assets/img/alipay.jpg +# 微信二维码图片地址 +weixin: /assets/img/weixin.jpg + +# 目录 +# 目录设定:0-不显示目录; 1-文章对应的md文件里有toc:true属性,才有目录; 2-所有文章均显示目录 +toc: 1 +# 根据自己的习惯来设置,如果你的目录标题习惯有标号,置为true即可隐藏hexo重复的序号;否则置为false +toc_hide_index: true +# 目录为空时的提示 +toc_empty_wording: '被吓跑了…' + +# 是否有快速回到顶部的按钮 +top: true + +# Miscellaneous +baidu_analytics: '7dff3925ec6f4cb7cfcb1b21c3c82ece' +google_analytics: '' +favicon: /assets/favicon.png + +#你的头像url +avatar: /assets/img/flytrap.jpg + +#是否开启分享 +share_jia: true + +#评论:1、多说;2、网易云跟帖;3、畅言;4、Disqus 不需要使用某项,直接设置值为false,或注释掉 +#具体请参考wiki:https://github.com/litten/hexo-theme-yilia/wiki/ + +#1、多说 +duoshuo: false + +#2、网易云跟帖 +wangyiyun: false + +#3、畅言 +changyan_appid: false +changyan_conf: false + +#4、Disqus 在hexo根目录的config里也有disqus_shortname字段,优先使用yilia的 +disqus: "flytrap" + +# 样式定制 - 一般不需要修改,除非有很强的定制欲望… +style: + # 头像上面的背景颜色 + header: '#4d4d4d' + # 右滑板块背景 + slider: 'linear-gradient(200deg,#a0cfe4,#e8c37e)' + +# slider的设置 +slider: + # 是否默认展开tags板块 + showTags: false + +# 智能菜单 +# 如不需要,将该对应项置为false +# 比如 +#smart_menu: +# friends: false +smart_menu: + innerArchive: '所有文章' + friends: '友链' + aboutme: '关于我' + +friends: + 友情链接1: http://localhost:4000/ + +aboutme: 很惭愧

只做了一点微小的工作
谢谢大家 \ No newline at end of file From 82d87ca3c7cf234d9dc2a948d43a3f4d0d3eb76a Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 16 Jul 2017 22:24:07 +0800 Subject: [PATCH 13/52] Create README.md --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..48b00e0d --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# flytrap.github.io + +hexo-flytrap blog + +安装博客 +首先要安装node +``` bash +git clone http://github.com/flytrap/flytrap.github.io.git + +git fetch origin hexo-flytrap # 安装分支 +git checkout hexo-flytrap # 切换分支 +cnpm install # 安装依赖的包 + +git clone https://github.com/litten/hexo-theme-yilia.git themes/yilia + +cp yilia_config.yml themes/yilia/_config.yml + +hexo clean +hexo g +hexo server +hexo deploy From 1de24520d79adcb282ee04dd3a235c936b72bc31 Mon Sep 17 00:00:00 2001 From: gaohuaguang Date: Tue, 18 Jul 2017 19:48:04 +0800 Subject: [PATCH 14/52] chg: add cname --- _config.yml | 3 ++- source/CNAME | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 source/CNAME diff --git a/_config.yml b/_config.yml index 31bd6894..cedff4dd 100644 --- a/_config.yml +++ b/_config.yml @@ -111,7 +111,8 @@ jsonContent: tags: true org: - emacs: 'D:\tools\emacs\bin\emacs.exe' + emacs: "/usr/local/bin/emacs" + # emacs: 'D:\tools\emacs\bin\emacs.exe' # emacs: /bin/emacs common: | #+OPTIONS: toc:nil diff --git a/source/CNAME b/source/CNAME new file mode 100644 index 00000000..49767f75 --- /dev/null +++ b/source/CNAME @@ -0,0 +1 @@ +blog.flytrap.top \ No newline at end of file From 2f0680fac6f00e6d855691ddbf0c603e7f1a25e7 Mon Sep 17 00:00:00 2001 From: gaohuaguang Date: Thu, 20 Jul 2017 10:45:02 +0800 Subject: [PATCH 15/52] add docker taiga --- source/_posts/martial/pile_work.org | 8 +++ source/_posts/tech/linux/docker.org | 49 +++++++++++++++++ source/_posts/tech/python/taiga/taiga_env.org | 55 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 source/_posts/martial/pile_work.org create mode 100644 source/_posts/tech/linux/docker.org create mode 100644 source/_posts/tech/python/taiga/taiga_env.org diff --git a/source/_posts/martial/pile_work.org b/source/_posts/martial/pile_work.org new file mode 100644 index 00000000..acb2893b --- /dev/null +++ b/source/_posts/martial/pile_work.org @@ -0,0 +1,8 @@ +#+TITLE: 内家桩功之我见 +#+DATE: <2017-07-18 > +#+TAGS: 桩, +#+LAYOUT: post +#+CATEGORIES: martial + +** summary + diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org new file mode 100644 index 00000000..f1048186 --- /dev/null +++ b/source/_posts/tech/linux/docker.org @@ -0,0 +1,49 @@ +#+TITLE: Docler 常用命令, 运行使用postgresql +#+DATE: <2017-07-19> +#+TAGS: docker,linux,postgresql +#+CATEGORIES: tech + +* docker postgresql 使用 +** Summary +docker的常用命令介绍,以及使用docker运行postgresql数据库 + +** docker install +略 ... + +** pull docker images +#+begin_src bash +docker search postgresql +# info +# NAME DESCRIPTION STARS OFFICIAL AUTOMATED +# postgres The PostgreSQL object-relational database ... 3773 [OK] +# 选择一个最多的 +docker pull postgres # 拉取远程镜像 +#+end_src + +#+begin_src html + +#+end_src + +** run docker +#+begin_src bash +docker run --name ps_taiga -e POSTGRES_PASSWORD=taiga -e POSTGRES_USER=taiga -v /Users/admin/code/media/data/postgresql:/var/lib/postgresql --restart always -d -p 5432:5432 postgres + +# --name docker别名 +# -e 修改环境变量 POSTGRES_PASSWORD, 数据库密码,POSTGRES_USER 账号明 +# -d demo +# -p 端口映射 (本地: docker容器) +# -v 磁盘映射 +# --restart always 随docker一起启动 +# 需要说明的是这里的磁盘/var/lib/postgresql/data目录,数据默认是放在data里面的 + +psql -h 127.0.0.1 -U taiga # 进去试着创建一个数据库试试 +#+end_src + +** 一些常用命令 + +#+begin_src bash +docker images # 显示本地镜像列表 +docker stop ps_taiga # 停止运行容器 +docker start ps_taiga # 启动容器 +docker exec -it ps_taiga /bin/bash # 交互模式运行容器的bash, 做一些操作 +#+end_src diff --git a/source/_posts/tech/python/taiga/taiga_env.org b/source/_posts/tech/python/taiga/taiga_env.org new file mode 100644 index 00000000..32da02cd --- /dev/null +++ b/source/_posts/tech/python/taiga/taiga_env.org @@ -0,0 +1,55 @@ +#+TITLE: taiga开发环境搭建 +#+DATE: <2017-07-19 > +#+TAGS: python,django,taiga, 开源 +#+LAYOUT: post +#+CATEGORIES: tech + +* taiga env +** Summary +Taiga 是一个开源的项目管理工具,专注于解决管理工具的易用性、简洁性问题。 +学习django DRF框架使用,taiga二次开发. + +** install python3 环境 +Taiga 是使用python3写的,不兼容python2 +#+begin_src base +brew install python3 # mac 安装最新python3 +apt-get install -y python3 # debian系列 +dnf -y install python3 # 红帽系列 +arch 默认就是python3 不用装 + +# 安装虚拟环境virtualenvwrapper +mkvirtualenv -p /usr/local/bin/python3.6 taiga +workon taiga +# 切换到taiga后端代码路径 +pip install -r requirements.txt # 安装必须的包 -i 可以指定源 +#+end_src + +** 配置数据库 +#+begin_src bash +cp settings/local.py.example settings/local.py + +# 修改数据库连接 + +python manage.py migrate --noinput # 生成数据库模型 +python manage.py loaddata initial_user # 加载默认数据 +python manage.py loaddata initial_project_templates +python manage.py compilemessages # 编译语言包(国际化) +python manage.py collectstatic --noinput # 收集静态文件 +# python manage.py sample_data # 加载点儿数据,方便调试, 数据比较多,会比较慢 + +#+end_src + +** 配置文件修改 +#+begin_src bash +cp settings/local.py.example settings/local.py +# 修改数据库配置 +MEDIA_URL = "http://localhost:9000/media/" # 端口不对,记得修改 +STATIC_URL = "http://localhost:9000/static/" +还有发送邮件的邮箱服务器,消息队列redis,rabbitmq 等服务配置 +CELERY_ENABLED = True # 启动celery服务 +#+end_src + +** 运行项目 +#+begin_src bash +python manage.py runserver +#+end_src From a2be768d47b4c255cc9b5ff52464fc821e0e064a Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 23 Jul 2017 18:12:35 +0800 Subject: [PATCH 16/52] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _config.yml | 11 ++++++----- package.json | 4 ++-- source/_posts/tech/linux/docker.org | 6 +++--- source/_posts/tech/python/django/django_401.md | 5 ++++- source/_posts/tech/python/taiga/taiga_env.org | 6 +++++- yilia_config.yml | 6 +++--- 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/_config.yml b/_config.yml index cedff4dd..d07c7a33 100644 --- a/_config.yml +++ b/_config.yml @@ -1,4 +1,5 @@ -# Hexo Configuration +# Hexo +Configuration ## Docs: https://hexo.io/docs/configuration.html ## Source: https://github.com/hexojs/hexo/ @@ -29,7 +30,7 @@ i18n_dir: :lang skip_render: # Writing -new_post_name: :title.md # File name of new posts +new_post_name: :title.org # File name of new posts default_layout: post titlecase: false # Transform title into titlecase external_link: true # Open external links in new tab @@ -111,9 +112,9 @@ jsonContent: tags: true org: - emacs: "/usr/local/bin/emacs" + # emacs: "/usr/local/bin/emacs" # emacs: 'D:\tools\emacs\bin\emacs.exe' - # emacs: /bin/emacs + emacs: "/usr/bin/emacs" common: | #+OPTIONS: toc:nil #+BIND: org-html-postamble \"Last Updated %C.
Render by
hexo-renderer-org with %c\" @@ -124,4 +125,4 @@ feed: path: atom.xml limit: 20 hub: - content: \ No newline at end of file + content: diff --git a/package.json b/package.json index b3e31a21..923901f1 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "hexo": { - "version": "3.3.7" + "version": "3.3.8" }, "dependencies": { "hexo": "^3.3.7", @@ -20,4 +20,4 @@ "hexo-renderer-stylus": "^0.3.1", "hexo-server": "^0.2.0" } -} +} \ No newline at end of file diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index f1048186..eff0839f 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -1,5 +1,5 @@ #+TITLE: Docler 常用命令, 运行使用postgresql -#+DATE: <2017-07-19> +#+DATE: <2017-07-22> #+TAGS: docker,linux,postgresql #+CATEGORIES: tech @@ -20,9 +20,9 @@ docker search postgresql docker pull postgres # 拉取远程镜像 #+end_src -#+begin_src html +#+begin_html -#+end_src +#+end_html ** run docker #+begin_src bash diff --git a/source/_posts/tech/python/django/django_401.md b/source/_posts/tech/python/django/django_401.md index 7f4c0073..4147e9c1 100644 --- a/source/_posts/tech/python/django/django_401.md +++ b/source/_posts/tech/python/django/django_401.md @@ -1,6 +1,9 @@ title: 关于不需要权限访问的接口,错误token,报401的解释 date: 2017-06-25 20:10:33 -tags: django, python, token +tags: + - django + - python + - token layout: post categories: tech --- diff --git a/source/_posts/tech/python/taiga/taiga_env.org b/source/_posts/tech/python/taiga/taiga_env.org index 32da02cd..28f3ca39 100644 --- a/source/_posts/tech/python/taiga/taiga_env.org +++ b/source/_posts/tech/python/taiga/taiga_env.org @@ -1,5 +1,5 @@ #+TITLE: taiga开发环境搭建 -#+DATE: <2017-07-19 > +#+DATE: <2017-07-22> #+TAGS: python,django,taiga, 开源 #+LAYOUT: post #+CATEGORIES: tech @@ -24,6 +24,10 @@ workon taiga pip install -r requirements.txt # 安装必须的包 -i 可以指定源 #+end_src +#+begin_html + +#+end_html + ** 配置数据库 #+begin_src bash cp settings/local.py.example settings/local.py diff --git a/yilia_config.yml b/yilia_config.yml index 24070c69..74dd53ba 100644 --- a/yilia_config.yml +++ b/yilia_config.yml @@ -65,8 +65,8 @@ top: true # Miscellaneous baidu_analytics: '7dff3925ec6f4cb7cfcb1b21c3c82ece' -google_analytics: '' -favicon: /assets/favicon.png +google_analytics: 'UA-103034600-1' +favicon: /assets/favicon.ico #你的头像url avatar: /assets/img/flytrap.jpg @@ -115,4 +115,4 @@ smart_menu: friends: 友情链接1: http://localhost:4000/ -aboutme: 很惭愧

只做了一点微小的工作
谢谢大家 \ No newline at end of file +aboutme: 很惭愧

只做了一点微小的工作
谢谢大家 From 33210cf0ee184617a3503b62f736d21b5741b3da Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 23 Jul 2017 18:53:12 +0800 Subject: [PATCH 17/52] =?UTF-8?q?fix:=20=E9=85=8D=E7=BD=AE=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _config.yml | 5 ++--- package.json | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/_config.yml b/_config.yml index d07c7a33..6a987610 100644 --- a/_config.yml +++ b/_config.yml @@ -1,9 +1,8 @@ -# Hexo -Configuration +# Hexo Configuration ## Docs: https://hexo.io/docs/configuration.html ## Source: https://github.com/hexojs/hexo/ -# Site +# Site title: 俗子 subtitle: 无意之中是真意,随心而行 description: 野生程序员一枚,传统文化和前沿科技的忠实拥护者,二者并不矛盾 diff --git a/package.json b/package.json index 923901f1..410ef0b5 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "version": "3.3.8" }, "dependencies": { - "hexo": "^3.3.7", + "hexo": "^3.3.8", "hexo-deployer-git": "^0.3.0", "hexo-generator-archive": "^0.1.4", "hexo-generator-category": "^0.1.3", @@ -20,4 +20,4 @@ "hexo-renderer-stylus": "^0.3.1", "hexo-server": "^0.2.0" } -} \ No newline at end of file +} From 9857aeb03b5a61fba8d9a0cdb2a5a2584c81caea Mon Sep 17 00:00:00 2001 From: gaohuaguang Date: Mon, 24 Jul 2017 09:49:38 +0800 Subject: [PATCH 18/52] add org~ to ignore --- .gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 039326b0..c388b786 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ db.json node_modules/ hexo-org-cache/ public/ -.deploy*/ \ No newline at end of file +.deploy*/ +*.org~ + From 6340a1e5e42daac73d95dc5fd954c47a6fcc95b0 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sat, 29 Jul 2017 22:57:26 +0800 Subject: [PATCH 19/52] add send weibo --- source/_drafts/org-example.org | 5 + source/_posts/tech/linux/docker.org | 5 + source/_posts/tech/python/arch_pip_change.org | 48 ++++++ .../python/auto_tools/auto_send_weibo.org | 154 ++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 source/_drafts/org-example.org create mode 100644 source/_posts/tech/python/arch_pip_change.org create mode 100644 source/_posts/tech/python/auto_tools/auto_send_weibo.org diff --git a/source/_drafts/org-example.org b/source/_drafts/org-example.org new file mode 100644 index 00000000..c3201fbb --- /dev/null +++ b/source/_drafts/org-example.org @@ -0,0 +1,5 @@ +#+TITLE: title +#+date: <2017-07-29> +#+tags: tag1,tag2 +#+layout: post +#+categories: tech diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index eff0839f..9b115054 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -37,6 +37,11 @@ docker run --name ps_taiga -e POSTGRES_PASSWORD=taiga -e POSTGRES_USER=taiga -v # 需要说明的是这里的磁盘/var/lib/postgresql/data目录,数据默认是放在data里面的 psql -h 127.0.0.1 -U taiga # 进去试着创建一个数据库试试 + +#redis docker +docker run -p 6379:6379 --name flytrap_redis --restart always -d redis + + #+end_src ** 一些常用命令 diff --git a/source/_posts/tech/python/arch_pip_change.org b/source/_posts/tech/python/arch_pip_change.org new file mode 100644 index 00000000..aed8b469 --- /dev/null +++ b/source/_posts/tech/python/arch_pip_change.org @@ -0,0 +1,48 @@ +#+TITLE: arch linux 修改pip源 +#+date: <2017-07-24> +#+tags: arch,linux,pip,python +#+layout: post +#+categories: tech + +* Summary +arch linux 系统配置文件是综合一起放在~/config目录里的,home路径看起来就没有那么乱 + +** 创建pip.conf +#+begin_src base + +mkdir -p ~/config/pip + +vim ~/config/pip/pip.conf + +#+end_src +#+begin_html + +#+end_html + +** 添加源 +#+begin_src config +[global] +index-url = https://pypi.douban.com/simple + +#+end_src + +這裏使用的是豆瓣的源,當然你也可以使用其他的 + +** 臨時換源 +#+begin_src bash +pip install xxx -i https://pypi.douban.com/simple + +#+end_src + +** 指定文件安裝 +一般安裝包都會有一個requirements.txt文件,裏面就是python依賴包的列表 +#+begin_src bash +pip install -r requirements.txt + +#+end_src + +** 搜索指定python包 +#+begin_src bash +pip search xxx + +#+end_src diff --git a/source/_posts/tech/python/auto_tools/auto_send_weibo.org b/source/_posts/tech/python/auto_tools/auto_send_weibo.org new file mode 100644 index 00000000..9142a57a --- /dev/null +++ b/source/_posts/tech/python/auto_tools/auto_send_weibo.org @@ -0,0 +1,154 @@ +#+TITLE: python脚本自动发微博 +#+date: <2017-07-29> +#+tags: python,selenium, webdriver, 微博,sina,新浪, 自动化 +#+layout: post +#+categories: tech + +* Summary +原则是能让机器做的事情,就不要自己做了,简化一切,计算机就是拿来给我们偷懒的。 +发微博,还要打开浏览器,你out了,几十行代码搞定的事情。 + +** selenium + +模拟浏览器行为,让程序控制浏览器,看着就爽 +装一个 +#+begin_src bash +pip install selenium +#+end_src + +对了,啰嗦一句,好像是要装chromedriver来着,我用的arch linux 装chromium的时候就已经带了这东西,chromium 应该都是自带的。 +windows咋弄,自己去度娘吧,我太长时间没用过win了,懒得折腾(win的环境真的无力吐槽) + +理论上应该是下载下来就一个文件,直接就可以用的。 + +#+begin_html + +#+end_html + +** 测试selenium +#+begin_src python +from selenium import webdriver +driver = webdriver.Chrome() # 这里面可以加一个selenium的路径,如果你的环境变量里没有这个东西 +driver.get('http://www.baidu.com') # 看到自己打开一个浏览器,并且访问了百度,那就没问题了 +#+end_src + +报错了?那就慢慢找原因哈,不着急. 要不google 一下 + +** 登录发送代码 +#+begin_src python +import time +from selenium import webdriver + + +class BaseLogin(object): + index_url = '' + + def __init__(self, username, password): + self.driver = webdriver.Chrome() + self.username = username + self.password = password + self.driver.get(self.index_url) + self.login() + + def login(self): + raise Exception('Must login function') + + def input_user_and_pass(self): + self.driver.find_element_by_name('loginname').send_keys(self.username) + self.driver.find_element_by_name('password').send_keys(self.password) + + +class SinaLogin(BaseLogin): + index_url = 'http://www.sina.com.cn/' + + def login(self): + if self.check_login(): + return + self.driver.find_element_by_link_text('登录').click() + + self.input_user_and_pass() + + remember = self.driver.find_element_by_name('remember') + if remember.is_selected(): + remember.click() + self.driver.find_element_by_class_name('login_btn').click() + login_error_tips = self.driver.find_element_by_class_name('login_error_tips') + if login_error_tips.text: + raise LoginException(login_error_tips.text) + time.sleep(2) + if not self.check_login(): + self.login() + + def check_login(self): + self.driver.refresh() + time.sleep(2) + name = self.driver.find_element_by_id('SI_Top_Nick_Name') + if name.text: + print('login ok') + return True + return False + + def to_weibo(self): + self.driver.find_element_by_id('SI_Top_Weibo').find_element_by_class_name('tn-tab').click() + + def switch_window(self, num=0, window=None): + if num < len(self.driver.current_window_handle): + if window is None: + window = self.driver.window_handles[num] + self.driver.switch_to.window(window) + print('switch to: {}'.format(self.driver.title)) + return True + return False + + def send_wb(self, text): + if not self.check_login(): + return + for window in self.driver.window_handles: + if 'weibo.com' not in self.driver.current_url: + if self.switch_window(window=window): + time.sleep(2) + continue + return + break + text_body = self.driver.find_element_by_xpath('//*[@id="v6_pl_content_publishertop"]/div/div[2]/textarea') + text_body.clear() + text_body.send_keys(text) + + send_bt = self.driver.find_element_by_xpath('//*[@id="v6_pl_content_publishertop"]/div/div[3]/div[1]/a') + send_bt.click() # 发布 + +#+end_src + +** 测试代码 +#+begin_src python +class TestSinaLoin(TestCase): + def __init__(self, *args, **kwargs): + super(TestSinaLoin, self).__init__(*args, **kwargs) + self.username = SINA_USERNAME + self.password = SINA_PASSWORD + + def test_sina_login(self): + sina_login = SinaLogin(self.username, self.password) + self.assertTrue(sina_login.check_login()) + del sina_login + + def test_sina_send_weibo(self): + sina_login = SinaLogin(self.username, self.password) + sina_login.send_wb('weibo send ok') + del sina_login + +#+end_src + +** 登录 +其实看代码就很简单了,没有什么复杂性,就是先找到用户名和密码输入的地方,让后填充。 +然后找到登录按钮,点击,就登录了,其中添加了一些检查登录是否成功的代码。 + +** 发微博 +我的登录操作都是在新浪首页操作的,当然你也可以在微博那边操作 +涉及到了页签切换,没有太多技术含量。 + +** 代码下载 +代码我放github了,想要的,去拿吧,不过我这里写了一个基类,后续可能会添加一些其他的代码及操作在里面。 +敬请关注. +后续或许会其他社交网站的登录代码. +[[https://github.com/flytrap/my_spider][代码]] From 8b8cbd6c0d63809ece9943fd89ae4f2b1f06ffae Mon Sep 17 00:00:00 2001 From: flytrap Date: Sat, 16 Sep 2017 17:39:41 +0800 Subject: [PATCH 20/52] add work separation --- package.json | 4 +- source/_posts/tech/linux/work_separation.org | 62 ++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 source/_posts/tech/linux/work_separation.org diff --git a/package.json b/package.json index 410ef0b5..7f00ce15 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "hexo": { - "version": "3.3.8" + "version": "3.3.9" }, "dependencies": { "hexo": "^3.3.8", @@ -20,4 +20,4 @@ "hexo-renderer-stylus": "^0.3.1", "hexo-server": "^0.2.0" } -} +} \ No newline at end of file diff --git a/source/_posts/tech/linux/work_separation.org b/source/_posts/tech/linux/work_separation.org new file mode 100644 index 00000000..9fd5cb54 --- /dev/null +++ b/source/_posts/tech/linux/work_separation.org @@ -0,0 +1,62 @@ +#+TITLE: ssh key config 分离git工作环境 +#+date: <2017-09-16> +#+tags: ssh,ssh_config,ssh环境,git +#+layout: post +#+categories: tech + +* 分离自己的工作环境 + +** Summary +工作代码和自己写的一些代码总会混合在一起,公用一个安全key,无法完全分离自己的代码环境和工作的代码环境。 +分离的最好办法就是使用不同的ssh-key, 代码哪怕同一个仓库也是可以分开的。 + +** 添加多个ssh-key +我们的ssh-key,默认路径是~/.ssh +ssh-keygen 命令是用来生成秘钥的,刚装系统大多都没有生成,都是自己生成的。 +#+begin_src bash +ssh-keygen -t rsa -f ~/.ssh/id_rsa_new +-t 指定加密方式 +-f 指定秘钥生成路径及名字(公钥私钥对),默认会覆盖 +#+end_src + +#+begin_html + +#+end_html + +** 通过config文件对域名进行映射 +config 路径: ~/.ssh/config +格式如下(现在用到的字段就这么多,更多字段请参考文档): +#+begin_src ini +Host 别名 + HostName 主机名 + Port 端口 + User 用户名 + PubkeyAuthentication yes  #允许 Public Key(必须) + IdentityFile 密钥(私钥)文件的路径 +#+end_src +整个文件就像这样 +#+begin_src ini +Host github + HostName github.com + User git + PubkeyAuthentication yes + IdentityFile ~/.ssh/github +Host work + HostName review.cyanogenmod.org + User git + PubkeyAuthentication yes + IdentityFile ~/.ssh/work +Host * + Pubkeyauthentication no +#+end_src +举个栗子: +比如说要克隆github的代码: +#+begin_src bash +git clone https://github.com/flytrap/flytrap.github.io.git +git clone https://github/flytrap/flytrap.github.io.git +#+end_src +这样应该很明显看出区别吧,相当于是把github.com这个域名简化(映射)为github了,我现在只需要简化后的就可以了,更重要的是,我下面指定了使用的私钥. +当然,聪明的你肯定已经先把对应的公钥放到github了吧。(域名一样也是可以的哦,相当于是只是指定了私钥而已) + +最后两行是说,匹配不到就用默认的,不影响你不想动的秘钥,是不是很爽?快试试吧。 + From 43ffe5bf43b5cf201f92509208ba64cb7a5dc0e7 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 24 Sep 2017 10:27:44 +0800 Subject: [PATCH 21/52] change render org mode packge --- .gitignore | 2 ++ package.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c388b786..7537c692 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ hexo-org-cache/ public/ .deploy*/ *.org~ +*# +#* diff --git a/package.json b/package.json index 7f00ce15..05fb0967 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "hexo-generator-tag": "^0.2.0", "hexo-renderer-ejs": "^0.2.0", "hexo-renderer-marked": "^0.2.10", - "hexo-renderer-org": "https://github.com/CodeFalling/hexo-renderer-org#emacs", + "hexo-renderer-orgmode": "^1.0.1", "hexo-renderer-stylus": "^0.3.1", "hexo-server": "^0.2.0" } -} \ No newline at end of file +} From f115db47f0bd100a0c95d7ea53a3f7ee6eaa1d13 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 24 Sep 2017 10:31:07 +0800 Subject: [PATCH 22/52] fix: index unll --- yilia_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yilia_config.yml b/yilia_config.yml index 74dd53ba..ab34da67 100644 --- a/yilia_config.yml +++ b/yilia_config.yml @@ -29,7 +29,7 @@ rss: /atom.xml # 是否需要修改 root 路径 # 如果您的网站存放在子目录中,例如 http://yoursite.com/blog, # 请将您的 url 设为 http://yoursite.com/blog 并把 root 设为 /blog/。 -root: +root: / # Content From 2ccb395588bf479bb66cc33a19774f828116fd16 Mon Sep 17 00:00:00 2001 From: flytrap Date: Fri, 29 Sep 2017 22:22:07 +0800 Subject: [PATCH 23/52] fix: draft upcase; new: days.org --- source/_drafts/org-example.org | 10 ++-- source/_posts/live/days.org | 43 +++++++++++++++ source/_posts/live/liveing.org | 31 +++++++++++ source/_posts/tech/linux/work_separation.org | 8 +-- source/_posts/tech/mac/keys.org | 35 ++++++++++++ source/_posts/tech/python/arch_pip_change.org | 8 +-- .../python/auto_tools/auto_send_weibo.org | 8 +-- .../tech/python/django/content_type.org | 55 +++++++++++++++++++ 8 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 source/_posts/live/days.org create mode 100644 source/_posts/live/liveing.org create mode 100644 source/_posts/tech/mac/keys.org create mode 100644 source/_posts/tech/python/django/content_type.org diff --git a/source/_drafts/org-example.org b/source/_drafts/org-example.org index c3201fbb..f248f616 100644 --- a/source/_drafts/org-example.org +++ b/source/_drafts/org-example.org @@ -1,5 +1,5 @@ -#+TITLE: title -#+date: <2017-07-29> -#+tags: tag1,tag2 -#+layout: post -#+categories: tech +#+TITLE: title +#+DATE: <2017-07-29> +#+TAGS: tag1,tag2 +#+LAYOUT: post +#+CATEGORIES: live diff --git a/source/_posts/live/days.org b/source/_posts/live/days.org new file mode 100644 index 00000000..128b3183 --- /dev/null +++ b/source/_posts/live/days.org @@ -0,0 +1,43 @@ +#+TITLE: 一天时间安排 +#+DATE: <2017-09-29> +#+TAGS: day, 时间管理 +#+LAYOUT: post +#+CATEGORIES: live + +* 一天的安排 + +** Summary +一天时间排序,规律生活每一天, 习惯了就不存在什么坚持不坚持,不需要思考,就该这么做. + +习惯去做一件事,没有痛苦,只是随心而行,乐在其中. + +** workday + +*** 1 2 4 + +| 7:00 | 7:30-8:30 | 8:40-9:30 | 9:30-20:30 | 20:40-21:20 | 22:00-23:00 | +|-----------+-------------+----------------------+------------+---------------------+-------------------| +| 起床-洗漱 | 练拳-读经典 | 地铁-听新闻,经典启发 | 正常上班 | 地铁-读英语,背单词 | 练拳-思考,静下来 | + + +*** 3 5 + +| 7:00 | 7:30-8:30 | 8:40-9:30 | 9:30-18:30 | 19:00-19:40 | 20:00-21:50 | 22:00-23:00 | +|-----------+-------------+----------------------+------------+---------------------+-----------------------------------+-------------------| +| 起床-洗漱 | 练拳-读经典 | 地铁-听新闻,经典启发 | 正常上班 | 地铁-读英语,背单词 | 吃饭,书,github,写点乱七八糟的东西 | 练拳-思考,静下来 | + +#+begin_html + +#+end_html + +** weekend + +| 7:20 | 7:30-8:30 | morning | afternoon | 21:30-23:00 | +|-----------+----------------------+------------------------+------------------------+----------------| +| 起床-洗漱 | 练拳-读经典,不开电脑 | 不定(一般技术研究为主) | 不定(一般技术研究为主) | 放空-练拳-入定 | + + +** remark +清晰知晓自己每天都做了什么,避免浑浑噩噩,共勉. + +梦在心里,萌芽成长。goog luck. diff --git a/source/_posts/live/liveing.org b/source/_posts/live/liveing.org new file mode 100644 index 00000000..43f4b05d --- /dev/null +++ b/source/_posts/live/liveing.org @@ -0,0 +1,31 @@ +#+TITLE: 无题 +#+DATE: <2017-07-29> +#+TAGS: tag1,tag2 +#+LAYOUT: post +#+CATEGORIES: live + +* 一些思考 + +** 活着 + +“人为财死,鸟为食亡”,更古不变的真理,为权为利,兄弟相争,同胞反目。到头来,空留骂名,终归黄土一剖。 +难道这就是活着的意义,佛道两教本所追求的终极修行大道,本为无为不争之境界,奈何多少人为达目的而不择手段,我想终归还是背离了核心宗旨。 +修行,生活中无处不在,与世无争或许只是空谈理想境界。 + + +** 学拳 +不妨把这个过程,当作是修行的一个途径, + + +** 看破 +世事万千,皆看破,或许只是自己的妄念,太重果,反而求之不得。 +自认为,看破世间万千因果,到头来,却被周身琐事所纷繁缠绕,无法自拔。任其百家思想,诸子学术,皆从有为中修行无为。 +有无之间,是非之间,对错之间,一时一地,所想所思而已。《庄子》齐物论,便是此种思想之精髓所在,老子无为,思想堪称发挥淋漓尽致。 +在看《逍遥游》,尺度决定见地,“子非鱼安知鱼之乐”实乃经典中的经典,达不到那个位置,永远无法理解其所思所想,有人说“人生成长的过程,其实就是不断承认自己是傻逼的过程”,怕是与庄子的论调有异曲同工之秒吧. +没有经历过,脑补出的结果,终归于笑谈。眼界达不到,就不可能想到,正所谓:“人无远虑,必有近忧”,不同阶层也都有不同的忧虑,庄子说“无待才能真逍遥”,确实如此,最大的问题就是生存问题,是呢,我又站在我的角度去思考了,可以达到“无待”之境,早已达到至人境界,生死业已看破,何须如此顾虑。 + +期望有朝一日真的能够看破,又谈何容易,处在社会最底层,所思所虑都还停留在温饱问题上,又何德何能,有何资格去思虑看破的高度,身边琐事都搞不定,都能让你心无旁骛,彻底沦陷。最简单的一关都无法通过呀。 + +常有感慨,世间万物,皆归于自然,我于自然自然于我,又何分彼此,百年之后,诞生之前,终归于自然,不过是再正常不过物质转化而已。万千烦恼,化归千万银丝,究竟是何种力量引我前行,凡此种种,皆有定数,道家说“这是自然规律”,佛家说“这是因果报应”,其实呢,我总结为“世事之间影响,一件事的发生,必然伴随另一物质的改变”这就是“道”,古人常说“识阴阳之造化,便可预知未来之变化”,不就是看破自然规律,掌握物质之间的联系,一通而白通? + +** 回归 diff --git a/source/_posts/tech/linux/work_separation.org b/source/_posts/tech/linux/work_separation.org index 9fd5cb54..81e2be3a 100644 --- a/source/_posts/tech/linux/work_separation.org +++ b/source/_posts/tech/linux/work_separation.org @@ -1,8 +1,8 @@ #+TITLE: ssh key config 分离git工作环境 -#+date: <2017-09-16> -#+tags: ssh,ssh_config,ssh环境,git -#+layout: post -#+categories: tech +#+DATE: <2017-09-16> +#+TAGS: ssh,ssh_config,ssh环境,git +#+LAYOUT: post +#+CATEGORIES: tech * 分离自己的工作环境 diff --git a/source/_posts/tech/mac/keys.org b/source/_posts/tech/mac/keys.org new file mode 100644 index 00000000..56f2d2cf --- /dev/null +++ b/source/_posts/tech/mac/keys.org @@ -0,0 +1,35 @@ +#+TITLE: mac keys +#+DATE: <2017-09-29> +#+TAGS: mac,key +#+LAYOUT: post +#+CATEGORIES: tech + +** summary +mac 快捷键的一些奇淫异巧 + +*** 1 +| key | 用途 | +| command + control + space | 使用emoji键盘 | +| command + space | spotlight(搜索) | +| command + delete | 放入回收站 | +| fn + delete | 反向删除 | +| control + 👆 | 显示窗口的打开的程序 | + +*** finder +| shift + command + g | 文件夹跳转 | +| command + o | 打开文件 | +| command + z | 撤销 | +| command + x | 剪切 | +| command + c | 复制 | +| command + v | 粘贴 | +| command + a | 全选 | +| command + s | 保存 | +| command + f | 查找 | + + +*** system +| command + shift + 4 | 截取所选屏幕区域到一个文件 | +| command + shift + 3 | 截取全部屏幕到文件 | +| command + shift + control + 3 | 截取全部屏幕到剪贴板 | + + diff --git a/source/_posts/tech/python/arch_pip_change.org b/source/_posts/tech/python/arch_pip_change.org index aed8b469..e168f07c 100644 --- a/source/_posts/tech/python/arch_pip_change.org +++ b/source/_posts/tech/python/arch_pip_change.org @@ -1,8 +1,8 @@ #+TITLE: arch linux 修改pip源 -#+date: <2017-07-24> -#+tags: arch,linux,pip,python -#+layout: post -#+categories: tech +#+DATE: <2017-07-24> +#+TAGS: arch,linux,pip,python +#+LAYOUT: post +#+CATEGORIES: tech * Summary arch linux 系统配置文件是综合一起放在~/config目录里的,home路径看起来就没有那么乱 diff --git a/source/_posts/tech/python/auto_tools/auto_send_weibo.org b/source/_posts/tech/python/auto_tools/auto_send_weibo.org index 9142a57a..2486427f 100644 --- a/source/_posts/tech/python/auto_tools/auto_send_weibo.org +++ b/source/_posts/tech/python/auto_tools/auto_send_weibo.org @@ -1,8 +1,8 @@ #+TITLE: python脚本自动发微博 -#+date: <2017-07-29> -#+tags: python,selenium, webdriver, 微博,sina,新浪, 自动化 -#+layout: post -#+categories: tech +#+DATE: <2017-07-29> +#+TAGS: python,selenium, webdriver, 微博,sina,新浪, 自动化 +#+LAYOUT: post +#+CATEGORIES: tech * Summary 原则是能让机器做的事情,就不要自己做了,简化一切,计算机就是拿来给我们偷懒的。 diff --git a/source/_posts/tech/python/django/content_type.org b/source/_posts/tech/python/django/content_type.org new file mode 100644 index 00000000..a2cb4cbc --- /dev/null +++ b/source/_posts/tech/python/django/content_type.org @@ -0,0 +1,55 @@ +#+TITLE: django content type +#+DATE: <2017-10-15> +#+TAGS: django,python,orm +#+LAYOUT: post +#+CATEGORIES: live + +* Django content_type 精妙之处 + +** Summary +有点儿Django经验的人应该都遇到过这种问题:有一个通用的模型,需要根据不同的类型,去关联对应的模型。 +通常的做法是:模型中有个类型的枚举字段,然后再搞个relate_id来存储相关联的模型id,然后通过逻辑,再去获取相关数据. +其实使用Django 自带的content type来解决这个问题,是非常容易的。 + +** content type +这个模型很简单,但是很好的一个东西 +#+begin_python +@python_2_unicode_compatible +class ContentType(models.Model): + app_label = models.CharField(max_length=100) + model = models.CharField(_('python model class name'), max_length=100) +#+end_python +数据库里看看呗 +你可以发现你项目里的所有模型,都在这个里面能找到,就这个就够了。 + +#+begin_html + +#+end_html + +** Use +来看看taiga里是怎么用的? + +#+begin_python +class Like(models.Model): + content_type = models.ForeignKey("contenttypes.ContentType") + object_id = models.PositiveIntegerField() + content_object = GenericForeignKey("content_type", "object_id") + user = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, blank=False, + related_name="likes", verbose_name=_("user")) + created_date = models.DateTimeField(null=False, blank=False, auto_now_add=True, + verbose_name=_("created date")) +#+end_python +创建一条数据: +#+begin_src python +obj = Blog.objects.first() +user = User.objects.first() +like = Like.objects.create(user=user, content_object=obj) +#+end_src +其实这个时候你打开数据库会发现,object_id,已经帮你存好了,content_type 也帮你存好咯。 +用的时候,直接把content_object 取出来就可以用.无关乎类型. + +** end +总结一下,这个东西秒就秒在Django本身就把这些事情帮你做好了,你不需要关心具体喜欢的东西是什么,这是一个通用模型,DRY原则的忠实践行。 + + +希望对你有帮助. From 2d59e0b809dd48e1afcbcac2f977ce539dc266dc Mon Sep 17 00:00:00 2001 From: flytrap Date: Wed, 8 Nov 2017 16:38:45 +0800 Subject: [PATCH 24/52] change content_type.org --- source/_posts/tech/python/django/content_type.org | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/_posts/tech/python/django/content_type.org b/source/_posts/tech/python/django/content_type.org index a2cb4cbc..6976a284 100644 --- a/source/_posts/tech/python/django/content_type.org +++ b/source/_posts/tech/python/django/content_type.org @@ -13,12 +13,12 @@ ** content type 这个模型很简单,但是很好的一个东西 -#+begin_python +#+begin_src python @python_2_unicode_compatible class ContentType(models.Model): app_label = models.CharField(max_length=100) model = models.CharField(_('python model class name'), max_length=100) -#+end_python +#+end_src 数据库里看看呗 你可以发现你项目里的所有模型,都在这个里面能找到,就这个就够了。 @@ -29,7 +29,7 @@ class ContentType(models.Model): ** Use 来看看taiga里是怎么用的? -#+begin_python +#+begin_src python class Like(models.Model): content_type = models.ForeignKey("contenttypes.ContentType") object_id = models.PositiveIntegerField() @@ -38,12 +38,16 @@ class Like(models.Model): related_name="likes", verbose_name=_("user")) created_date = models.DateTimeField(null=False, blank=False, auto_now_add=True, verbose_name=_("created date")) -#+end_python +#+end_src 创建一条数据: #+begin_src python obj = Blog.objects.first() user = User.objects.first() like = Like.objects.create(user=user, content_object=obj) + +# 通过content_type_id 和object_id获取content type对象 +content_type = ContentType.objects.filter(id=content_type_id).first() +obj = content_type.get_object_for_this_type(pk=object_id) #+end_src 其实这个时候你打开数据库会发现,object_id,已经帮你存好了,content_type 也帮你存好咯。 用的时候,直接把content_object 取出来就可以用.无关乎类型. From 6a94093af39c17c8cf4545baf5e351e88f13aad9 Mon Sep 17 00:00:00 2001 From: flytrap Date: Fri, 1 Dec 2017 22:39:57 +0800 Subject: [PATCH 25/52] t --- source/_posts/live/using.org | 30 +++++++++++++++++++++++++++ source/_posts/tech/mac/crack_rec.org | 23 ++++++++++++++++++++ source/_posts/tech/mac/git_errors.org | 16 ++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 source/_posts/live/using.org create mode 100644 source/_posts/tech/mac/crack_rec.org create mode 100644 source/_posts/tech/mac/git_errors.org diff --git a/source/_posts/live/using.org b/source/_posts/live/using.org new file mode 100644 index 00000000..ff776a8a --- /dev/null +++ b/source/_posts/live/using.org @@ -0,0 +1,30 @@ +#+TITLE: 中体西用-今解 +#+DATE: <2017-11-26> +#+TAGS: 国术,国学,武术,中医,形意,传统 +#+LAYOUT: post +#+CATEGORIES: live + +* 中学为体,西学为用-古学今用 + 当年洋务运动时张之洞提出“中体西用,想要在不改变国基的基础上,师以夷技以制夷,终以失败告终,以国家计,兹事体大,难以运转,事终难成。 + 时过境迁,细似之,其必有可取之道。“修身治家齐天下”,古之治国之道,吾辈不敢苟同,查吾今日之道路,却有异曲同工之妙。 + +** 体用之道 +*** 体者 + 根本也,立身之本,终世践行,不可偏废也,所谓本事是也。 +*** 用者 + 生存之道,活命之源也,顺合时势,以求安身立命,所谓技能,技术,能力,乃外在表现而。 +*** 入世 + 二者不可偏废,无体则人如行尸,空有皮囊一副,枉来人事,信仰全无,空守根本(原则),不懂变通,终难得一席之地,难活于世也。 + 世人多本末难辨,以用为体,斯为苟活于世,而空乏本质,大道难明。 +**** example:传统武术 + 空有花架,而无内涵者多,明人观之,空有架势,华而不实者多。哗众取宠,重架而不重功,老来一场空。 + +#+BEGIN_HTML + +#+END_HTML + +** 渊源 +*** 国术 + 国术者,涵盖较广,中医,传统拳术,诸子百家,上下几千年文化,兴衰更迭,读之明智而可体用也,以哲学为代表,儒释道为切入点。 +*** 西方科学 + 所谓科学,自由其一套科学体系论述,现代设施,高楼大厦都渊源基本物理学的支撑,方便的互联网,计算机科学,无一例外来自于西方科学,“可证伪”的规律是也。 diff --git a/source/_posts/tech/mac/crack_rec.org b/source/_posts/tech/mac/crack_rec.org new file mode 100644 index 00000000..9c4c5e6b --- /dev/null +++ b/source/_posts/tech/mac/crack_rec.org @@ -0,0 +1,23 @@ +#+TITLE: 一些mac下软件的使用技巧 +#+DATE: <2017-11-28> +#+TAGS: mac,os,UltraEdit +#+LAYOUT: post +#+CATEGORIES: tech + +* mac os软件激活方式 +** UltraEdit + :LOGBOOK: + CLOCK: [2017-11-28 二 10:49]--[2017-11-28 二 11:14] => 0:25 + :END: +修改启动文件。 +打补丁 +#+begin_src bash +printf '\x31\xC0\xFF\xC0\xC3\x90' | dd seek=$((0x92D370)) conv=notrunc bs=1 of=/Applications/UltraEdit.app/Contents/MacOS/UltraEdit +#+end_src +我用的版本是官方最新 16.10.0.22,亲测可用。 + +** 来自身份不明的开发者 +关闭安全策略(将会绕过mac安全检查,慎重) +#+begin_src bash +sudo spctl --master-disable +#+end_src diff --git a/source/_posts/tech/mac/git_errors.org b/source/_posts/tech/mac/git_errors.org new file mode 100644 index 00000000..bd5895c9 --- /dev/null +++ b/source/_posts/tech/mac/git_errors.org @@ -0,0 +1,16 @@ +#+TITLE: error: RPC failed; curl 18 transfer closed with outstanding read data remaining +#+DATE: <2017-11-08> +#+TAGS: git,mac,error +#+LAYOUT: post +#+CATEGORIES: live + +* Summary + git clone 报错如下: + error: RPC failed; curl 18 transfer closed with outstanding read data remaining + + +* Function +解决方案,设置推送大小限制 +#begin_src base +git config --global http.postBuffer 524288000 # 500M应该足够了 +#end_src From 73f8ab5c40a4fbb3aa622c74d30a60c2f4308c34 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 10 Dec 2017 10:36:05 +0800 Subject: [PATCH 26/52] change docker --- source/_posts/tech/linux/docker.org | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index 9b115054..edfa9cea 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -52,3 +52,13 @@ docker stop ps_taiga # 停止运行容器 docker start ps_taiga # 启动容器 docker exec -it ps_taiga /bin/bash # 交互模式运行容器的bash, 做一些操作 #+end_src + +* 例子 +** 安装mysql +开机自动启动 --restart always +设置root密码 -e MYSQL\_ROOT\_PASSWORD=root # _需要转义 +#+begin_bash +docker search mysql +docker pull mysql +docker run --name mysql1 -p 3306:3306 -e MYSQL\_ROOT\_PASSWORD=root -v /home/flytrap/data/mysql:/var/lib/mysql --restart always -d mysql +#+end_bash From 0476febbed1b78596b641d72855a1773c5c35c0b Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 10 Dec 2017 23:20:03 +0800 Subject: [PATCH 27/52] add pi --- source/_posts/live/pi.org | 113 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 source/_posts/live/pi.org diff --git a/source/_posts/live/pi.org b/source/_posts/live/pi.org new file mode 100644 index 00000000..33ece262 --- /dev/null +++ b/source/_posts/live/pi.org @@ -0,0 +1,113 @@ +#+TITLE: 形意-劈拳 +#+DATE: <2017-12-10> +#+TAGS: 形意,劈拳,劈,肺 +#+LAYOUT: post +#+CATEGORIES: live + +* 劈拳 +** 古谱 +*** 形意拳谱 +劈拳性属金,是阴阳连环成一气之起落也,气之一静,故形象太极。 + +气之一动而生物,其名为横,横属土,土生万物,故内包四拳,其五行循环之理。 + +土生金,故先练劈拳,上下运用,有劈物之意,其形像斧,故名劈拳。 + +所诸身内则为肺,劲顺则气合,劲拗则肺气乖。 + +夫人以气为主,气合则体壮,气乖则体弱,故学者不可大意也。 + +上步初势曰:两手紧握,同变阴拳,左拳落出,肘顺胸前,高不过肩,力垂左肩,右手靠脐,肘至肋边,眼平舌卷,气降丹田。 + +*** 劈拳讲义 +劈拳性属金,是阴阳连环一气之起落也。 + +气之一静,故形象太极;气之一动而生物,其名为横。 + +横属土,土生万物,故内包四拳。 + +按其五行循环之理,土生金,故先练劈拳,上下运用,有劈物之意,其形似斧,故名劈拳,所诸身内则为肺,劲顺则肺气和,劲谬则肺气乖。 + +夫人以气为主,气和则体壮,气乖则体弱,故学者不可大意也。 + +上步初势曰:两手紧握,同变阴拳,左拳落出,肘顺胸前,高不过肩,力垂左肩;右手靠脐,肘至肋边,眼平舌卷,气降丹田。 + +换步歌:左足既开,右足大进,手足齐落,推挽两迅,左足斜跟,右足仍顺,指开心齐,后手肋近,手足与鼻,列成直阵。 + +转身歌:起势钻,落势翻,行如槐虫,起如挑担,若遇人多,三摇两旋,正是转身之谓也。 + + + +*** 歌诀 +劈拳之形似斧,性属金,崩拳之形似箭,性属木。 + +双榻双钻气相连,起吸落呼莫等闲。易骨易筋加洗髓,脚踩手劈一气传。 + +*** 打法 +拳打三节不见形,如见形影不为能。 + +能在一思进,莫在一思存。能在一气先,莫在一气后。 + +肘打去意占胸膛,起手好似虎扑羊;头打落意随足走,起而未起占中央;脚踏中门抢地位,就是神仙也难防。 + +肩打一阴反一阳,两手只在洞中藏;左右全凭盖他意,束展二字一命亡。 + + +** 练法 +顶、扣、圆、毒、抱、垂、曲、挺。 + +三顶:头上顶,有冲天之雄,手外顶,有推山之功,舌上顶,有吼狮吞象容。 + +三扣:肩扣,则气力到肘,膝胯扣则全身气凑,手足指掌扣,则周身力厚。 + +三圆:脊背圆,其力摧身,前胸圆,则两肘力全,虎口圆,则勇猛外宣。 + +三毒:心毒如怒狸攫鼠,眼毒知观兔之饥鹰,手毒如扑羊之饿虎。 + +三抱:(另一说为三敏即心敏、眼敏、手敏是也。)丹田抱气,气不外散,胆量抱身,临事不怯,两肘抱肋,出入不乱。 + +三垂:气垂则气降丹田,肩垂则肩能摧肘,肘垂则肘能摧手。 + +三曲:两肱宜曲,曲则力富,两股宜曲,曲则力凑,手腕宜曲,曲则力厚。 + +三挺:颈挺则精气实顶,腰挺则力达四肢,膝挺则有弹力。 + +*** 拳法 +起钻落翻,要点:虎口成员,力达指尖,钻为辅,劈为主; + +切记:拳要劈,而非推,手掌摊开,意到力到。 +*** 身法 +身体下坐,拧腰送胯,身起拳落。 + +*** 发力 +力量传递:腰为主宰,心到意到气到力到,力量传递沿着督脉一条线,拧腰,坐胯,一伸一缩之间,力量瞬间而至,劲整。 + +力源在丹田,腰胯(中节),上下两个力,下传于足,上达于指(梢节)。 + +力量往下,继而向上反弹一个力,或者说力从脚起,至尾椎,经督脉,到达指尖。 + +要点:要想力整,如何?力不可中断,怎样才能保证不中断呢,就一个字“松”,当然也不可完全松下来,该送的松,凡是适度为要,力量传递过程中,一旦僵硬,则力被阻。 +*** 呼吸 +初学者应以一呼一动为主,钻吸劈呼。呼吸自然,不可憋气。 + + +** 打法 +"束展二字一命亡", 关键在于舒展二字,一收一缩之间,伴随身体整体的移动,产生瞬间爆炸力,身体像一个炮弹似的,一下出去,缩成一团,瞬间炸开,力可想而知。 + +钻而近身,“劈”,近身发力. + + +** 医理 +劈拳属金,练肺,归肺。 + +《灵枢·经脉》: + + “肺手太阴之脉,起于中焦,下络大肠,还循胃口,上膈属肺,从肺系横出腋下,下循臑内,行少阴、心主之前,下肘中,循臂内上骨下廉,入寸口,上鱼,循鱼际,出大指之端:其支者,从腕后,直出次指内廉,出其端。” + +*** 歌诀 +手太阴肺十一穴,中府云门天府诀,侠白尺泽孔最存,列缺经渠太渊涉,鱼际少商如韭叶,左右二十二孔穴。流注线:此一经起于中府,终于少商。 + +督脉行脉之中行,二十八穴始长强.腰俞阳关入命门,悬枢脊中中枢长.筋缩至阳归灵台,神道身柱陶道开.大椎哑门连风府,脑户强间后顶排.百会前顶通囟会,上星神庭素髎对.水沟兑端在唇上,龈交上齿缝之内. + +*** 行功 +肺与大肠想表里,主司呼吸,故气力合,声应拳而出. From 672cfc48f769cf8d7add2158827cd40975e9c1fe Mon Sep 17 00:00:00 2001 From: flytrap Date: Mon, 8 Jan 2018 21:37:59 +0800 Subject: [PATCH 28/52] add sql pro --- source/_posts/tech/mac/crack_rec.org | 18 +++++ .../_posts/tech/python/django/manytomany.org | 74 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 source/_posts/tech/python/django/manytomany.org diff --git a/source/_posts/tech/mac/crack_rec.org b/source/_posts/tech/mac/crack_rec.org index 9c4c5e6b..a67299cd 100644 --- a/source/_posts/tech/mac/crack_rec.org +++ b/source/_posts/tech/mac/crack_rec.org @@ -16,6 +16,24 @@ printf '\x31\xC0\xFF\xC0\xC3\x90' | dd seek=$((0x92D370)) conv=notrunc bs=1 of=/ #+end_src 我用的版本是官方最新 16.10.0.22,亲测可用。 + +#+begin_html + +#+end_html +** Axure RP 8 + +激活码: + +被授权人(Licensee): +#+begin_src bash +University of Science and Technology of China (CLASSROOM) +#+end_src + +授权秘钥(Key): +#+begin_src bash +DTXRAnPn1P65Rt0xB4eTQ+4bF5IUF0gu0X9XBEUhM4QxY0DRFJxYEmgh4nyh7RtL +#+end_src + ** 来自身份不明的开发者 关闭安全策略(将会绕过mac安全检查,慎重) #+begin_src bash diff --git a/source/_posts/tech/python/django/manytomany.org b/source/_posts/tech/python/django/manytomany.org new file mode 100644 index 00000000..682110a1 --- /dev/null +++ b/source/_posts/tech/python/django/manytomany.org @@ -0,0 +1,74 @@ +#+TITLE: ManyToManyField 双向关联 +#+DATE: <2018-01-07> +#+TAGS: python,django,ManyToManyField,单向,双向,数据关联 +#+LAYOUT: post +#+CATEGORIES: tech + +* Django ManyToManyField 字段数据关联 + +** 表结构 +先看一段代码 +#+begin_src python +class People(models.Model): + user = models.ForeignKey(User, verbose_name='系统关联', on_delete=False, null=True, blank=True) + birth_death = models.CharField('生卒', max_length=32, default='') + name = models.CharField('姓名', max_length=64) + address = models.CharField('地址', max_length=256, default='') + desc = models.TextField('介绍', null=True, blank=True) + childes = models.ManyToManyField('self', verbose_name='后辈') + class Meta: + verbose_name = '门人' +#+end_src +** 讨论的主要字段就一个childes +多对多数据,像多对多这个属性,在关系型数据库中的应用应该还是比较多的,平时使用应该比较少使用多对多自己的情况。 +然而我这里用到了,遇到一些问题,供大家参考 +*** 测试一下 +#+begin_src python +p1 = People.objects.create(name='p1') +p2 = People.objects.create(name='p2') +p2.childes.add(p1) +p2.childes.all() # ]> ....... 1 +p1.childes.all() # ]> ....... 2 +#+end_src +#+begin_html + +#+end_html +看到....1的位置,发现我们成功添加一条数据到p2中,嗯,没毛病 +继续往下看,p1的数据,我们并没有往p1中添加数据,然而,这里却多了一条数据,这就是毛病了。 + +*** 看看数据库 +| id | from_people_id | to_people_id | +| 1 | 2 | 1 | +| 2 | 1 | 2 | +看到问题了吧? + +*** 看看官方文档 +#+begin_src code +ManyToManyField.symmetrical¶ +Only used in the definition of ManyToManyFields on self. Consider the following model: + +from django.db import models + +class Person(models.Model): + friends = models.ManyToManyField("self") +When Django processes this model, it identifies that it has a ManyToManyField on itself, and as a result, it doesn’t add a person_set attribute to the Person class. Instead, the ManyToManyField is assumed to be symmetrical – that is, if I am your friend, then you are my friend. + +If you do not want symmetry in many-to-many relationships with self, set symmetrical to False. This will force Django to add the descriptor for the reverse relationship, allowing ManyToManyField relationships to be non-symmetrical. +#+end_src +对了,看官应该看到了“symmetrical”对称的数据,布尔值 + + +** 修改后的代码 +#+begin_src python +childes = models.ManyToManyField('self', symmetrical=False, verbose_name='后辈') +#+end_src python + +*** 测一下 +#+begin_src python +p1.childes.all() # +#+end_src +没有数据了,只有一边数据了, 对,这就是我们要的结果 + +** 总结 +ManyToManyField 字段,选项symmetrical 默认为True,双向关联,导致数据产生逆向关联。 +ps: 有问题,找官方文档最靠谱 From 6c94935496263af356fee4cb2ca17744ffab5f6d Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 25 Feb 2018 22:57:25 +0800 Subject: [PATCH 29/52] add sumaary-2017 --- source/_posts/live/summary-2017.org | 100 +++++++++++++++++ source/_posts/tech/java/spring_sentry.org | 124 ++++++++++++++++++++++ source/_posts/tech/python/py3_2_diff.org | 24 +++++ 3 files changed, 248 insertions(+) create mode 100644 source/_posts/live/summary-2017.org create mode 100644 source/_posts/tech/java/spring_sentry.org diff --git a/source/_posts/live/summary-2017.org b/source/_posts/live/summary-2017.org new file mode 100644 index 00000000..f1a07c8f --- /dev/null +++ b/source/_posts/live/summary-2017.org @@ -0,0 +1,100 @@ +#+TITLE:flytrap 2017 +#+DATE: <2018-02-20> +#+TAGS: coder, 形意, read, book, 生活 +#+LAYOUT: post +#+CATEGORIES: live + +* 恍惚2017 +** 读了几本不错的书 +*** 技术类: +- 程序员的生存之道 +- 领域驱动开发 +- Django 设计模式与最佳实践 +- ... + +*** 人物/历史: +- 逝去的武林 +- 未来简史 +- 三体 +- 庄子 +- 武人琴音 + +*** 总结一下 +感觉阅读量明显减少(虽然读过的肯定远不止这些,感觉比较重要的也就这么多了),今年一定补回来. + +** 新的语言 +- swift --可以说基本入门吧,搞个简单的app应该问题不大,看了不少开源的项目. +- typescript -- 前端,学习了angularjs框架,做了个比较丑的前端页面,一直想着优化来着,太懒了,今年一定做. +- java(spring) 用spring 做了两个web项目,算是曾经学过的用上了吧 +- python3 这个其实不算新语言,不过使用python3新启了几个项目,感觉项目感强了不少,3的变化还是不少,先写这儿吧 + +#+BEGIN_HTML + +#+END_HTML + +** 总结一下 +正如"福哥"(当年带我上路的老司机,对我来说挺重要的)说的一样,程序员是不应局限于语言的, +都是程序,各种虽有差别,上手难度不同而已,目的都是为了解决问题,仅此而已,选择合适的就好,不可拘泥。 + +** 源码 +*** python +- drf 读了不少,有些东西不看源码,真的很难搞懂。 +- django-rest-swagger 代码不多,收获不大,核心在引用包里,不在这里 +- taiga python3 写的django项目管理工具,挺优秀的代码,学到不少django的技巧,还是挺有收获的. +- ... + +*** java +- spring 项目,看了不少,就不一一列举了,都是为了解决问题而读 + +*** typescript +- 都是一些入门学习的代码,如用户管理代码,图表展示代码等等 + +*** swift +- 主要以ios为主,一些app的代码如(hack-news)好简洁,有木有? + +*** 总结一下 +大型框架没有那么多的时间去理解,阅读,只能抓其要点,略而读之,GitHub代码何其多也,吾生也有涯,点到为止,扼其要道,清楚自己想要什么才好。 + +** 结缘形意 +*** 形意门 +形意--仰慕已久的拳种,大学期间经济,认知等局限,一直无缘学习,实乃生平一大憾事。 +毕业久矣,忙着生存,而无余力,拖至今日,实在羞愧呀. +三大内家拳(太极,八卦)之一,民国曾风靡一时,和平年代不显不露,弟子门人遍布世界。 +对武术的认知有了不少的提升,一位好的师父,一个好的门派,有幸结识,实乃贵人得遇呀。 +契合中医经络理论,阴阳五行,所谓"武医"本为一体,内家拳的内涵之妙在于此,同时道出了力之本源--劲. + +似乎找到了,心目中的拳种,十几年了,得偿所愿, 必须好好练,我就说嘛“不要天天做白日梦,一不小心就成真的了”,哈哈. + +得到:练武-写代码,本来是没有半毛钱关系的事情。却有很多想通之处.正所谓"一通则百通",可见凡事皆有其规律,重点是发现规律的方法。 +打拳的感觉对了,很爽,写代码感觉对了,一样很爽,关键是能不能找到感觉。。。 +世事多相通,跨界思考,会有不一样的体验,更有意外的收获。 + +** 收获 +- python3 django 这些可以说是生存基石,理解深刻不少,使用也更加得心应手,同时看到了技术的局限,瓶颈估计为时不多矣. +- java 用不到的技术很容易消退,用起来才会有各种问题,才能进步. +- 运维部署 多了不少实践经验,小公司的好处就是可以从整体看待整个项目,代码部署,服务器都要理解,都要自己动手,对整个研发的认知提升是非常有好处的. +- 认知 应该每年都有提升,只是今年感觉特别明显,事物看待有一种透彻之感,挺好的感觉,想明白了很多事情,可能得单独写一篇心得了. +- 工程感,就是一种感觉,指引做事的感觉. +- mac 高效率的程序员必备工具,感觉性价比是很高的(必须高配呀),程序员的时间,必须宝贵. +- 形意门 前辈的谆谆教诲,不止拳脚,生存法则,还有更多. +- hexo 重新排列blog,维护. +- 搜索 见识了ES 的强大,其实搜索引擎还是挺有趣的 +- 微信小程序 赶个时髦,了解了一下微信小程序,确实挺强大的. +- 大数据展示,搞了个形意门门人家谱树状展示图,有点儿丑,还没上线 +- 买了台服务器(基础版),部署了论坛,一点儿服务,nginx,多玩玩吧,还买了一些域名 + +** 展望一下 +今年要做的事儿 +- 全栈 从大前端到后端到运维,都应该了解,并能够解决问题,不一定特别精通,但必须得能做 +- 形意门官网,今年这个已经提上日程,自己维护(包括门人结构树) +- AI 这个东西不能拉下,可能不会太深入,应用还是应该搞一下 +- 区块链 据说今年会很火,不想跟风,了解一下再说吧 +- 抓点儿门人咨询,搞个搜索出来,没有一个好的入口,这件事我来做吧 +- 今年明显感觉有了不小的惰性,这个得改,还有很多事情等着做呢 +- 多读点儿书,不局限 +- 看点儿好电影,多个角度看世界吧 +- 还有 帮师父把书出了,这个事情也很重要 +- 该出去走走了,今年都没怎么出去,差不多该规划一下了,读万卷书,不如行万里路,嗯,还是找感觉 +- 还有余力的话,还是看看python3的源码吧,深入理解,这是核心技能,不能丢,得深入 +- 还有一件-- 作息 练拳-学习-工作 时间必须斟酌了,[--早起--] +- 太多了,从简,就不写那么多了. diff --git a/source/_posts/tech/java/spring_sentry.org b/source/_posts/tech/java/spring_sentry.org new file mode 100644 index 00000000..32f4d12b --- /dev/null +++ b/source/_posts/tech/java/spring_sentry.org @@ -0,0 +1,124 @@ +#+TITLE: spring boot 添加sentry +#+DATE: <2017-12-13> +#+TAGS: spring,sentry +#+LAYOUT: post +#+CATEGORIES: tech + +* spring boot 添加sentry +** 官方spring 方案 +#+begin_src url +https://docs.sentry.io/clients/java/modules/spring/ +#+end_src +没成功: Couldn't find a suitable DSN,应该是没有配置对,没有找到成功使用案例 + +配置如下: +pom.xml +#+begin_src xml + + io.sentry + sentry-spring + 1.6.3 + +#+end_src +config +#+begin_src java +@Bean +public HandlerExceptionResolver sentryExceptionResolver() { + return new io.sentry.spring.SentryExceptionResolver(); +} + +@Bean +public ServletContextInitializer sentryServletContextInitializer() { + return new io.sentry.spring.SentryServletContextInitializer(); +} +#+end_src +application.properties +#+begin_src properties +dsn=http://cbbc57cc8f7975750:2d9@sentry.io/24 +#+end_src +提供出来,以供参考,有知道的记得告诉我一声,谢谢. + +#+begin_html + +#+end_html> +** raven-logback 亲测可用 +pom.xml +#+begin_src xml + + com.getsentry.raven + raven-logback + 8.0.3 + +#+end_src +logback.xml +#+begin_src xml + + + + + http://cbbc57cc8f7975750:41a8850708e5dc1159@sentry.io/24 + tag1:cpa,tag2:admin + + ERROR + + + + + + + + +#+end_src +统一封装异常处理 +#+begin_src java +import com.getsentry.raven.DefaultRavenFactory; +import com.getsentry.raven.Raven; +import com.getsentry.raven.dsn.Dsn; +import lombok.extern.log4j.Log4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; + +@Log4j +@ControllerAdvice +public class GlobalExceptionHandler { + @Value("${dsn}") + String dsnUrl; + + @ExceptionHandler(value = Exception.class) + @ResponseBody + public Result defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { + sendSentry(e); + // 统计结果类 + Result result = new Result(); + return result.setStatus("error").setMessage(e.getMessage()); + } + + /** + * 异常发送至sentry + * @param e + */ + private void sendSentry(Exception e) { + Dsn dsn = new Dsn(dsnUrl); + Raven raven = (new DefaultRavenFactory()).createRavenInstance(dsn); + + Throwable throwable = new Throwable(e.getMessage(), e.getCause()); + throwable.setStackTrace(e.getStackTrace()); + raven.sendException(throwable); + } +} +#+end_src +就这三个地方,其中dsn是在配置文件中的变量,以访问sentry +*** 应用 +#+begin_src java +import lombok.extern.log4j.Log4j; +@Log4j +public class Test{ + public void test(){ + log.error("pp"); + } +} +#+end_src diff --git a/source/_posts/tech/python/py3_2_diff.org b/source/_posts/tech/python/py3_2_diff.org index 12aa5aa0..43b5b6d3 100644 --- a/source/_posts/tech/python/py3_2_diff.org +++ b/source/_posts/tech/python/py3_2_diff.org @@ -24,3 +24,27 @@ urllib2. #+begin_src python urllib. #+end_src + +** HTTPServer +*** python2 +#+begin_src python2 +python2 -m SimpleHTTPServer +#+end_src + +*** python3 +#+begin_src python3 +python3 -m http.server +#+end_src + +* 语法语义的不同 +** 字典特性 +*** python2 +无序 +*** python3 +有序,不需要单独导入有序字典包 + +** 遍历删除元素 +*** python2 +可迭代可修改对象,循环过程中允许删除 +*** python3 +可迭代对象,迭代过程中不允许删除操作,增加了安全性,同时也变得不python了 From db31c3e3ca257b7c898c7911eb0729ce81b0c872 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 25 Feb 2018 22:59:15 +0800 Subject: [PATCH 30/52] fix docker.org code bug --- source/_posts/tech/linux/docker.org | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index edfa9cea..54da4d7c 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -57,8 +57,8 @@ docker exec -it ps_taiga /bin/bash # 交互模式运行容器的bash, 做一些 ** 安装mysql 开机自动启动 --restart always 设置root密码 -e MYSQL\_ROOT\_PASSWORD=root # _需要转义 -#+begin_bash +#+begin_src bash docker search mysql docker pull mysql docker run --name mysql1 -p 3306:3306 -e MYSQL\_ROOT\_PASSWORD=root -v /home/flytrap/data/mysql:/var/lib/mysql --restart always -d mysql -#+end_bash +#+end_src From 84bd342335f293dbbf7988aac689fa9515eecec1 Mon Sep 17 00:00:00 2001 From: flytrap Date: Tue, 5 Jun 2018 17:43:19 +0800 Subject: [PATCH 31/52] new: add friends robot --- .../deploy/unavailable_modifier_requested.org | 44 +++++++++++++++++++ source/_posts/tech/linux/docker.org | 3 +- source/_posts/tech/linux/proxychains.org | 5 ++- source/_posts/tech/mac/keys.org | 2 + yilia_config.yml | 2 +- 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 source/_posts/tech/linux/deploy/unavailable_modifier_requested.org diff --git a/source/_posts/tech/linux/deploy/unavailable_modifier_requested.org b/source/_posts/tech/linux/deploy/unavailable_modifier_requested.org new file mode 100644 index 00000000..fc68e14a --- /dev/null +++ b/source/_posts/tech/linux/deploy/unavailable_modifier_requested.org @@ -0,0 +1,44 @@ +#+TITLE: -- unavailable modifier requested: 0 -- 解决方案 +#+DATE: <2018-03-09> +#+TAGS: nginx,uwsgi,django +#+LAYOUT: post +#+CATEGORIES: tech + +* uwsgi 遇到比较多的一个问题 + +** 错误信息 +#+begin_src bash +*** Operational MODE: single process *** +*** no app loaded. going in full dynamic mode *** +*** uWSGI is running in multiple interpreter mode *** +spawned uWSGI master process (pid: 14105) +spawned uWSGI worker 1 (pid: 14108, cores: 1) +-- unavailable modifier requested: 0 -- +-- unavailable modifier requested: 0 -- +#+end_src +以上是当我访问nginx服务的时候,uwsgi给出的错误信息 +每次访问都是一个: "-- unavailable modifier requested: 0 --" + +#+begin_html + +#+end_html + +** 错误分析 +这个其实是因为python映射的问题,加一个插件就好了 + +** 解决方案 +#+begin_src bash +apt-get install uwsgi-plugin-python3 # python3 +apt-get install uwsgi-plugin-python #python2 +#+end_src +uwsgi 配置文件添加如下代码: +#+begin_src ini +plugin = python3 # python3 +plugin = python # python +#+end_src +命令行启动 +#+begin_src bash +uwsgi --plugin python3 uwsgi.ini # python3 +uwsgi --plugin python uwsgi.ini # python2 +#+end_src + diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index 54da4d7c..de452190 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -1,4 +1,4 @@ -#+TITLE: Docler 常用命令, 运行使用postgresql +#+TITLE: Docker 常用命令, 运行使用postgresql #+DATE: <2017-07-22> #+TAGS: docker,linux,postgresql #+CATEGORIES: tech @@ -56,6 +56,7 @@ docker exec -it ps_taiga /bin/bash # 交互模式运行容器的bash, 做一些 * 例子 ** 安装mysql 开机自动启动 --restart always + 设置root密码 -e MYSQL\_ROOT\_PASSWORD=root # _需要转义 #+begin_src bash docker search mysql diff --git a/source/_posts/tech/linux/proxychains.org b/source/_posts/tech/linux/proxychains.org index 7b53df6e..b992dea8 100644 --- a/source/_posts/tech/linux/proxychains.org +++ b/source/_posts/tech/linux/proxychains.org @@ -25,14 +25,15 @@ yum/dnf install proxychains # redhat, centos, fedora ** proxychains setting #+begin_src bash vim + /etc/proxychains.conf - +#+end_src +#+begin_src ini [ProxyList] http 0.0.0.0 80 socks4 0.0.0.0 4444 socks5 0.0.0.0 5555 +#+end_src # 只要一行,選擇自己的代理類型,修改之. 格式:代理類型 ip 端口 -#+end_src ** proxychains use #+begin_src bash proxychains command # proxychains 後面跟上你的命令就行咯. diff --git a/source/_posts/tech/mac/keys.org b/source/_posts/tech/mac/keys.org index 56f2d2cf..538ddf7a 100644 --- a/source/_posts/tech/mac/keys.org +++ b/source/_posts/tech/mac/keys.org @@ -16,6 +16,7 @@ mac 快捷键的一些奇淫异巧 | control + 👆 | 显示窗口的打开的程序 | *** finder +| key | 用途 | | shift + command + g | 文件夹跳转 | | command + o | 打开文件 | | command + z | 撤销 | @@ -28,6 +29,7 @@ mac 快捷键的一些奇淫异巧 *** system +| key | 用途 | | command + shift + 4 | 截取所选屏幕区域到一个文件 | | command + shift + 3 | 截取全部屏幕到文件 | | command + shift + control + 3 | 截取全部屏幕到剪贴板 | diff --git a/yilia_config.yml b/yilia_config.yml index ab34da67..8c22321c 100644 --- a/yilia_config.yml +++ b/yilia_config.yml @@ -113,6 +113,6 @@ smart_menu: aboutme: '关于我' friends: - 友情链接1: http://localhost:4000/ + 木制robot: http://woodenrobot.me/ aboutme: 很惭愧

只做了一点微小的工作
谢谢大家 From f4080d0ec4d722f0b77c08b41d45e9dc3393da49 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 10 Jun 2018 19:20:08 +0800 Subject: [PATCH 32/52] chg: post.md new: add blog ettercap --- _config.yml | 4 +- scaffolds/post.md | 4 + source/_drafts/gitlab.org | 9 + .../_posts/tech/front/msword_content_type.org | 47 ++++ source/_posts/tech/hacker/ettercap.md | 247 ++++++++++++++++++ 5 files changed, 309 insertions(+), 2 deletions(-) create mode 100644 source/_drafts/gitlab.org create mode 100644 source/_posts/tech/front/msword_content_type.org create mode 100644 source/_posts/tech/hacker/ettercap.md diff --git a/_config.yml b/_config.yml index 6a987610..863de439 100644 --- a/_config.yml +++ b/_config.yml @@ -9,7 +9,7 @@ description: 野生程序员一枚,传统文化和前沿科技的忠实拥护 author: 俗子 language: timezone: -keywords: "django,后端,python,linux,程序员,形意,易,中医" +keywords: "django,后端,python,linux,程序员,形意,易,中医,信息安全" # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' @@ -29,7 +29,7 @@ i18n_dir: :lang skip_render: # Writing -new_post_name: :title.org # File name of new posts +new_post_name: :title.md # File name of new posts default_layout: post titlecase: false # Transform title into titlecase external_link: true # Open external links in new tab diff --git a/scaffolds/post.md b/scaffolds/post.md index 1f9b9a46..80b08830 100644 --- a/scaffolds/post.md +++ b/scaffolds/post.md @@ -1,5 +1,9 @@ --- title: {{ title }} +author: flytrap date: {{ date }} +categories: +- tech tags: +- tech --- diff --git a/source/_drafts/gitlab.org b/source/_drafts/gitlab.org new file mode 100644 index 00000000..4d7d82d8 --- /dev/null +++ b/source/_drafts/gitlab.org @@ -0,0 +1,9 @@ +#+TITLE: gitlab 服务搭建 +#+DATE: <2018-03-14> +#+TAGS: gitlab,docker,linux,link +#+LAYOUT: post +#+CATEGORIES: tech + +* gitlab 服务搭建 + + diff --git a/source/_posts/tech/front/msword_content_type.org b/source/_posts/tech/front/msword_content_type.org new file mode 100644 index 00000000..9a5456c8 --- /dev/null +++ b/source/_posts/tech/front/msword_content_type.org @@ -0,0 +1,47 @@ +#+TITLE: Microsoft Office MIME types for HTTP Content Streaming +#+DATE: <2018-06-09> +#+TAGS: msword,office,conten_type,doc,docx,xls +#+LAYOUT: post +#+CATEGORIES: tech + + +* Microsoft Office MIME types for HTTP Content Streaming + +microsoft file stream 'Content-Type' + +#+begin_src bash +Extension MIME Type +.doc application/msword +.dot application/msword + +.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document +.dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template +.docm application/vnd.ms-word.document.macroEnabled.12 +.dotm application/vnd.ms-word.template.macroEnabled.12 + +.xls application/vnd.ms-excel +.xlt application/vnd.ms-excel +.xla application/vnd.ms-excel + +.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet +.xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template +.xlsm application/vnd.ms-excel.sheet.macroEnabled.12 +.xltm application/vnd.ms-excel.template.macroEnabled.12 +.xlam application/vnd.ms-excel.addin.macroEnabled.12 +.xlsb application/vnd.ms-excel.sheet.binary.macroEnabled.12 + +.ppt application/vnd.ms-powerpoint +.pot application/vnd.ms-powerpoint +.pps application/vnd.ms-powerpoint +.ppa application/vnd.ms-powerpoint + +.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation +.potx application/vnd.openxmlformats-officedocument.presentationml.template +.ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow +.ppam application/vnd.ms-powerpoint.addin.macroEnabled.12 +.pptm application/vnd.ms-powerpoint.presentation.macroEnabled.12 +.potm application/vnd.ms-powerpoint.template.macroEnabled.12 +.ppsm application/vnd.ms-powerpoint.slideshow.macroEnabled.12 + +.mdb application/vnd.ms-access +#+end_src diff --git a/source/_posts/tech/hacker/ettercap.md b/source/_posts/tech/hacker/ettercap.md new file mode 100644 index 00000000..5cf7f1f6 --- /dev/null +++ b/source/_posts/tech/hacker/ettercap.md @@ -0,0 +1,247 @@ +--- +title: 安全工具系列之ettercap +author: flytrap +date: 2018-06-10 09:45:35 + +categories: +- tech +tags: +- hacker +- linux +- ettercap +- 内网 +- 渗透测试 +- kali +- 安全 + +--- + +简单介绍一下,挺早就想写一下这一系列比较好用的工具了,只是太懒了。 +现在抽周末,慢慢地完成这一想法吧,算是一个系列. +主要以一些功能介绍,是常用命令为主,原理层面的话,可能不会特别深。毕竟还是需要比较专业的术语来说明,就太复杂了。 + +回到正题,就从内网渗透神器ettercap开始吧,最近用到了这个工具。也是我众多喜爱工具中感觉比较好用的一款。 + +简单介绍一下ettercap这款工具,内网渗透,这款工具用好了,差不多内网你就可以横着走了。 + +什么叫内网?通俗一点,就是局域网,连的同一个路由器。这样说我觉得挺通俗了,如果觉得不好,欢迎随意批评订正。 + + +## 安装 +安装比较简单 +``` bash +apt-get install ettercap # debian/ubuntu系列 +pacman -S ettercap # arch 系 +dnf install ettercap # centos系列 +brew install ettercap # mac +``` +### 配置文件 +一般在以下几个,找找看咯 + +- /etc/ettercap +- /usr/local/etc/ettercap + +如有遗漏,欢迎补充 + +## 功能介绍 +官方文档如是说: + +``` doc +Ettercap is a comprehensive suite for man in the middle attacks. +It features sniffing of live connections, content filtering on the fly and many other interesting tricks. +It supports active and passive dissection of many protocols and includes many features for network and host analysis. +``` + +解释一下,就是说这是一个很牛逼的中间人攻击套件,嗅探监听修改过滤分析内网数据包等等. + +## 常见用法 +废话终于说完了,到正题了,来看看怎么个牛逼法、 + +``` bash +ettercap -Tq -i en0 -M arp /// /// +``` +解释一下 + +``` comment +-T text 文本模式,对应的另外一个-G,图形界面模式(不推荐,体验不好,给你两个理由,一个是可能会卡死,第二个,没有命令行酷,哈哈),当然还有一个C,终端里的界面比图形化好不少。 +-q 安静模式,不然很多没必要的信息会被输出。可以用空格切换。 +-i 指定网卡接口 +-M MITM attack 中间人攻击,就是干这个得,选项(arp|icmp|dhcp|port|ndp)等等,常用的就是arp咯 +-P 加载插件 +-F 加载过滤器自带了一些,可以自己写,这才是杀手锏 +/// 分割mac, ip, port 要欺骗的ip,不写就是所有的 +``` +### more-还是文档说的好,自行参考咯 +``` bash + ettercap -Tp + + Use the console interface and do not put the interface in promisc mode. You will see only your traffic. + + ettercap -Tzq + + Use the console interface, do not ARP scan the net and be quiet. The packet content will not be displayed, but user and passwords, as well as other messages, will be displayed. + + ettercap -T -j /tmp/victims -M arp /10.0.0.1-7/ /10.0.0.10-20/ + + Will load the hosts list from /tmp/victims and perform an ARP poisoning attack against the two target. The list will be joined with the target and the resulting list is used for ARP poisoning. + + ettercap -T -M arp // // + + Perform the ARP poisoning attack against all the hosts in the LAN. BE CAREFUL !! + + ettercap -T -M arp:remote /192.168.1.1/ /192.168.1.2-10/ + + Perform the ARP poisoning against the gateway and the host in the lan between 2 and 10. The 'remote' option is needed to be able to sniff the remote traffic the hosts make through the gateway. + + ettercap -Tzq //110 + + Sniff only the pop3 protocol from every hosts. + + ettercap -Tzq /10.0.0.1/21,22,23 + + Sniff telnet, ftp and ssh connections to 10.0.0.1. + + ettercap -P list + + Prints the list of all available plugins +``` + +## 关于插件 +看看都有哪些插件: + +``` bash +-> ettercap -P list +Available plugins : + + arp_cop 1.1 Report suspicious ARP activity + autoadd 1.2 Automatically add new victims in the target range + chk_poison 1.1 Check if the poisoning had success + dns_spoof 1.2 Sends spoofed dns replies + dos_attack 1.0 Run a d.o.s. attack against an IP address + dummy 3.0 A plugin template (for developers) + find_conn 1.0 Search connections on a switched LAN + find_ettercap 2.0 Try to find ettercap activity + find_ip 1.0 Search an unused IP address in the subnet + finger 1.6 Fingerprint a remote host + finger_submit 1.0 Submit a fingerprint to ettercap's website + fraggle_attack 1.0 Run a fraggle attack against hosts of target one + gre_relay 1.0 Tunnel broker for redirected GRE tunnels + gw_discover 1.0 Try to find the LAN gateway + isolate 1.0 Isolate an host from the lan + link_type 1.0 Check the link type (hub/switch) + mdns_spoof 1.0 Sends spoofed mDNS replies + nbns_spoof 1.1 Sends spoof NBNS replies & sends SMB challenges with custom challenge + pptp_chapms1 1.0 PPTP: Forces chapms-v1 from chapms-v2 + pptp_clear 1.0 PPTP: Tries to force cleartext tunnel + pptp_pap 1.0 PPTP: Forces PAP authentication + pptp_reneg 1.0 PPTP: Forces tunnel re-negotiation + rand_flood 1.0 Flood the LAN with random MAC addresses + remote_browser 1.2 Sends visited URLs to the browser + reply_arp 1.0 Simple arp responder + repoison_arp 1.0 Repoison after broadcast ARP + scan_poisoner 1.0 Actively search other poisoners + search_promisc 1.2 Search promisc NICs in the LAN + smb_clear 1.0 Tries to force SMB cleartext auth + smb_down 1.0 Tries to force SMB to not use NTLM2 key auth + smurf_attack 1.0 Run a smurf attack against specified hosts + sslstrip 1.1 SSLStrip plugin + stp_mangler 1.0 Become root of a switches spanning tree +``` +这是我所安装的版本所带的插件 +### 说点儿常用的 + +- dns_spoof : dns洪水攻击,配置文件"etter.dn",配置一下IP和域名对应关系即可,不知道dns?那自行解决吧,不再赘述; +- sslstrip : ssl 剥除攻击,降维打击,告诉服务器你需要http请求而非https; +- dos_attack:dos攻击,这个懂点儿安全应该都知道,就不科普了,自行度娘; +- find_ettercap: 检测是否有人开启ettercap,用于行为检测 + +这里就简单介绍介个,更多详细内容,请找男人吧 + +``` bash +-> man 8 ettercap_plugins +``` + + +## 过滤器 +``` filter +if (ip.proto == TCP && tcp.dst == 80) { + if (search(DATA.data, "Accept-Encoding")) { + replace("Accept-Encoding", "Accept-Rubbish!"); + msg("[*] Sucked Accept-Encoding!\n"); + } +} + +# log all traffic except http +if (ip.proto == TCP && tcp.src != 80 && tcp.dst != 80) { + log(DATA.data, "./logfile.log"); +} +``` +逻辑比较简单,就是一些简单的条件判断,然后就是数据包内容的替换 + +举个例子: + +- 正则匹配数据包中的用户名密码,然后存储下来,对应的网站也存储下来。 +- 不同协议,正则不同,替换包中数据,插入js,执行脚本。杀伤力自行脑补。 + +### 文档 +``` bash +-> man etterfilter + The etterfilter utility is used to compile source filter files into binary filter + files that can be interpreted by the JIT interpreter in the ettercap(8) filter + engine. You have to compile your filter scripts in order to use them in ettercap. + All syntax/parse errors will be checked at compile time, so you will be sure to + produce a correct binary filter for ettercap. +... +``` + +## 简单说一下攻防原理 +简单说一下,现在通用局域网组织架构: +简单来说,你连接这个网络的原理: + +- 需要一个网卡,网卡有一个标志,我们叫他mac 地址,不是mac电脑的mac哈。 +- 但是呢,都知道我们上网是通过ip的,所以,就需要分配一个ip,ip哪儿来的?DHCP服务可以帮你。当然本质上,其实就是维护了一个"mac-ip"对应表(路由表)。 +- 还有一个叫做网关的东西,当然了,也会一个ip,就特殊在它是路由器的ip,网络数据包需要通过他才能找到服务器。 +- 怎么找到服务器?DNS,就是一个域名和ip对应的列表维护者。 +- OK,梳理一下: 本机mac获取一个ip,通过ip连接路由ip,然后路由器把你的数据转运出去 +- 问题来了,你怎么确定路由器的身份,而路由器又如何确定你的身份呢?对咯,就是靠路由表(mac-ip对应表) +- 聪明的你,应该知道我们要做什么了。 + +### DNS欺骗 +DNS解析,原理就是ip-域名列表伪造 +### ARP 欺骗 +说白了,就是伪造arp路由表. + +每个可以访问的ip都必须匹配一个mac地址,更多的时候呢,匹配到路由器就找到目标了。 +具体还是参考一下内网图谱图和通信原理图吧。 + +内网ip确认都是靠的广播来传播数据的,不然确认目标受到没有,就只能不停的广播,当然会有很多隐患。所以就给了攻击者机会。 +``` bash +arp -a # 查看一下本机缓存的arp表 +``` +真有兴趣甚至可以去读一下《TCP/IP详解》 + +## 题外话 +说了半天都没有说,这东西牛逼哪儿了。 +你可以修改局域网的任意包,监听任意包。 +### 高级用法 +- metsploit: 配合使用,提取主机最高权限,各种exp +- beef: 浏览器里的王者 +- ... + + +## 更多参考 +``` bash +SEE ALSO + etter.conf(5) ettercap_curses(8) ettercap_plugins(8) etterlog(8) etterfilter(8) ettercap-pkexec(8) +``` +解释一下, 需要点儿Linux基础知识 + +``` bash +man 5 etter.conf +man 8 ettercap_curses +man 8 ettercap_plugins +man 8 etterlog +... +``` + +有什么见解?欢迎批评指正。 \ No newline at end of file From 3b37dcb03881f945c7c95acb3a7709bc45035d04 Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 22 Jul 2018 07:38:20 +0800 Subject: [PATCH 33/52] add oneplus_6 and ettercap --- source/_posts/tech/hacker/ettercap.md | 7 ++++ source/_posts/tech/hacker/oneplus_6_root.md | 37 +++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 source/_posts/tech/hacker/oneplus_6_root.md diff --git a/source/_posts/tech/hacker/ettercap.md b/source/_posts/tech/hacker/ettercap.md index 5cf7f1f6..63c976bd 100644 --- a/source/_posts/tech/hacker/ettercap.md +++ b/source/_posts/tech/hacker/ettercap.md @@ -183,6 +183,13 @@ if (ip.proto == TCP && tcp.src != 80 && tcp.dst != 80) { - 正则匹配数据包中的用户名密码,然后存储下来,对应的网站也存储下来。 - 不同协议,正则不同,替换包中数据,插入js,执行脚本。杀伤力自行脑补。 +使用过滤脚本 + +``` bash +-> etterfilter test.filter -o test.ef ## 编译(filter文件是源文件,ef是目标文件) +-> ettercap -F test.ef ## 引用 +``` + ### 文档 ``` bash -> man etterfilter diff --git a/source/_posts/tech/hacker/oneplus_6_root.md b/source/_posts/tech/hacker/oneplus_6_root.md new file mode 100644 index 00000000..7999ee7a --- /dev/null +++ b/source/_posts/tech/hacker/oneplus_6_root.md @@ -0,0 +1,37 @@ +# 一加6 获取root权限 + +## 下载相关文件 +- twrp: [https://twrp.me/](https://twrp.me/) + +TeamWin Recovery Project: 全触屏操作的第三方Recovery, 支持多国语言,很强大 + +- magisk: [https://github.com/topjohnwu/Magisk/releases/](https://github.com/topjohnwu/Magisk/releases/) +集成 root(MagiskSU) + +## 推送文件到手机 +``` bash +gpg --verify twrp-3.2.2-0-enchilada.img.asc twrp-3.2.2-0-enchilada.img # 引导文件校验 +gpg --verify twrp-installer-enchilada-3.2.2-0.zip.asc twrp-installer-enchilada-3.2.2-0.zip # 安装包校验 +adb push twrp-installer-enchilada-3.2.2-0.zip /sdcard/ +adb push Magisk-v16.0.zip /sdcard/ +``` + +## 解锁BootLoader +- 此升级方式会清空手机内所有内容,请务必先备份。 +- 设置 -> 系统 -> 关于手机 -> 高级 -> 连续点击“版本号”7次打开开发者选项 +- 设置 -> 系统 -> 开发者选项 -> 打开“OEM 解锁” -> 打开"高级重启" +- 关机 -> 进入fastboot + +``` bash +adb reboot bootloader # 进入刷机状态 +fastboot oem unlock # 选择unlock the bootloader ->确认 +``` + + +## 刷入twrp, Magisk包 +``` bash +adb reboot bootloader # 进入到BootLoader +fastboot boot twrp-3.2.2-0-enchilada.img # 从twrp启动 +## 点击install 选择/sdcard/下的zip包安装, 有两个(twrp-installer-enchilada-3.2.2-0.zip)是更改系统recovery, (Magisk-v16.0.zip)是root管理包 +adb reboot recovery # 进入twrp +``` From 6e0134e3eec0dee4b332b597b15d5b3f1a0661ba Mon Sep 17 00:00:00 2001 From: flytrap Date: Thu, 26 Jul 2018 22:48:59 +0800 Subject: [PATCH 34/52] add reverse command --- source/_posts/tech/hacker/oneplus_6_root.md | 17 ++++++++++++++++- .../tech/hacker/reverse/reverse-command.md | 10 ++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 source/_posts/tech/hacker/reverse/reverse-command.md diff --git a/source/_posts/tech/hacker/oneplus_6_root.md b/source/_posts/tech/hacker/oneplus_6_root.md index 7999ee7a..431b29ca 100644 --- a/source/_posts/tech/hacker/oneplus_6_root.md +++ b/source/_posts/tech/hacker/oneplus_6_root.md @@ -1,3 +1,17 @@ +--- +title: 一加6 获取root权限 +author: flytrap +date: 2018-07-08 09:45:35 + +categories: +- tech +tags: +- hacker +- oneplus +- 安全 + +--- + # 一加6 获取root权限 ## 下载相关文件 @@ -32,6 +46,7 @@ fastboot oem unlock # 选择unlock the bootloader ->确认 ``` bash adb reboot bootloader # 进入到BootLoader fastboot boot twrp-3.2.2-0-enchilada.img # 从twrp启动 -## 点击install 选择/sdcard/下的zip包安装, 有两个(twrp-installer-enchilada-3.2.2-0.zip)是更改系统recovery, (Magisk-v16.0.zip)是root管理包 +## 点击install 选择/sdcard/下的zip包安装, 有两个(twrp-installer-enchilada-3.2.2-0.zip)是更改系统recovery, (Magisk-v16.0.zip)是root管理包, 安装完重启 +## 重启就可以看到root管理工具了 adb reboot recovery # 进入twrp ``` diff --git a/source/_posts/tech/hacker/reverse/reverse-command.md b/source/_posts/tech/hacker/reverse/reverse-command.md new file mode 100644 index 00000000..b50f4984 --- /dev/null +++ b/source/_posts/tech/hacker/reverse/reverse-command.md @@ -0,0 +1,10 @@ +## 逆向工具命令: +- ldd: 依赖链接库查看(mac 参考otool -L) +- objdump: 依赖libbfd, 提取各种信息 +- otool: 解析OS X 二进制文件 +- dumpbin: 微软提取pe文件信息 +- nm: display name list (symbol table) +- c++filt: C++,java程序重载函数还原(nm test |grep func|c++filt) +- strings: 字符串搜索 + +- ndisasm|diSorm: 流式反汇编器 From a3966e5c819df3c7574c2907a63c347184339e6a Mon Sep 17 00:00:00 2001 From: flytrap Date: Thu, 2 Aug 2018 19:56:32 +0800 Subject: [PATCH 35/52] add alsamixer org --- source/_posts/tech/linux/alsamixer.org | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 source/_posts/tech/linux/alsamixer.org diff --git a/source/_posts/tech/linux/alsamixer.org b/source/_posts/tech/linux/alsamixer.org new file mode 100644 index 00000000..0269742e --- /dev/null +++ b/source/_posts/tech/linux/alsamixer.org @@ -0,0 +1,46 @@ +#+TITLE: alsamixer 控制音量 +#+DATE: <2018-07-29> +#+TAGS: alasmixer,amixer,linux,arch,i3 +#+LAYOUT: post +#+CATEGORIES: live + +* alsamixer + +** alsamixer 终端交互式设置音量 +#+begin_src bash +F6 选择网卡 +F2 显示系统信息,可以看到系统中已有网卡信息 +Esc 后退 + +M 静音状态切换 +Q,W,E 增大 左,右,通道 的音量 +Z,X,C 减小 左,右,通道 的音量 +#+end_src + +** amixer 命令行控制系统声音 +#+begin_src bash +cat /proc/asound/cards # 查看系统声卡 +#+end_src +输出如下 +#+begin_src bash +0 [HDMI ]: HDA-Intel - HDA Intel HDMI +1 [PCH ]: HDA-Intel - HDA Intel PCH +#+end_src +设置声音 +#+begin_src bash +amixer -c 1 -q set Master 2dB+ unmute +#+end_src + +#+begin_src bash +-c 制定声卡id, 默认为0 +-q 安静模式,不输出结果 +#+end_src + + +** i3wm 快捷键配置 + +#+begin_src bash +bindsym XF86AudioRaiseVolume exec --no-startup-id amixer -c 1 -q set Master 2dB+ unmute +bindsym XF86AudioLowerVolume exec --no-startup-id amixer -c 1 -q set Master 2dB- unmute +bindsym XF86AudioMute exec --no-startup-id amixer -c 1 -q set Master toggle set Headphone toggle +#+end_src From cf30b946730a3b3ccb8ba4a68bcaaff0ea10c331 Mon Sep 17 00:00:00 2001 From: flytrap Date: Mon, 22 Oct 2018 17:50:02 +0800 Subject: [PATCH 36/52] add sub_dns_tools --- .gitignore | 1 + package.json | 4 ++-- source/_posts/tech/hacker/sub_dns_tools.org | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 source/_posts/tech/hacker/sub_dns_tools.org diff --git a/.gitignore b/.gitignore index 7537c692..70d5ec27 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ public/ *.org~ *# #* +package-lock.json diff --git a/package.json b/package.json index 05fb0967..d78a5155 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "hexo": { - "version": "3.3.9" + "version": "3.7.1" }, "dependencies": { "hexo": "^3.3.8", @@ -20,4 +20,4 @@ "hexo-renderer-stylus": "^0.3.1", "hexo-server": "^0.2.0" } -} +} \ No newline at end of file diff --git a/source/_posts/tech/hacker/sub_dns_tools.org b/source/_posts/tech/hacker/sub_dns_tools.org new file mode 100644 index 00000000..4b7d391f --- /dev/null +++ b/source/_posts/tech/hacker/sub_dns_tools.org @@ -0,0 +1,18 @@ +#+TITLE: 子域名信息收集工具 +#+DATE: <2018-08-27> +#+TAGS: dns,sub +#+LAYOUT: post +#+CATEGORIES: live + +** virustotal +https://www.virustotal.com + + +** DNSdumpster +https://dnsdumpster.com/ + +** Sublist3r +这个应该是最好用的 +比较全面 + + From 0ed2b56ed19440b01efcbaedb631cfcd5b5fbde2 Mon Sep 17 00:00:00 2001 From: flytrap Date: Tue, 23 Oct 2018 18:03:16 +0800 Subject: [PATCH 37/52] new: add redis info --- source/_posts/tech/linux/docker.org | 8 +- source/_posts/tech/redis/redis-info.org | 173 ++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 source/_posts/tech/redis/redis-info.org diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index de452190..0772f1eb 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -13,10 +13,10 @@ docker的常用命令介绍,以及使用docker运行postgresql数据库 ** pull docker images #+begin_src bash docker search postgresql -# info -# NAME DESCRIPTION STARS OFFICIAL AUTOMATED -# postgres The PostgreSQL object-relational database ... 3773 [OK] -# 选择一个最多的 +info +NAME DESCRIPTION STARS OFFICIAL AUTOMATED +postgres The PostgreSQL object-relational database ... 3773 [OK] +// 选择一个最多的 docker pull postgres # 拉取远程镜像 #+end_src diff --git a/source/_posts/tech/redis/redis-info.org b/source/_posts/tech/redis/redis-info.org new file mode 100644 index 00000000..52fad9e1 --- /dev/null +++ b/source/_posts/tech/redis/redis-info.org @@ -0,0 +1,173 @@ +#+TITLE: redis拾遗-性能指标 +#+DATE: <2018-10-23> +#+TAGS: redis,info +#+LAYOUT: post +#+CATEGORIES: tech + +* redis 性能指标(info命令使用) + +** Summary +Info 指令显示的信息量非常大,可以分为9大块: +- Server 服务器运行的环境参数 +- Clients 客户端相关信息 +- Memory 服务器运行内存统计数据 +- Persistence 持久化信息 +- Stats 通用统计数据 +- Replication 主从复制相关信息 +- CPU CPU 使用情况 +- Cluster 集群信息 +- KeySpace 键值对统计数量信息... + +#+begin_html + +#+end_html + +** 基本使用 +#+begin_src bash +// 慢日志相关 +>slowlog [get|len|reset] +#+end_src + +#+begin_src bash +// 显示所有信息 +>info +#+end_src +#+begin_src bash +// 内存相关信息,依次类推,9个模块都可以 +>info memory +\# Memory +used_memory:888952 +used_memory_human:868.12K +used_memory_rss:5832704 +used_memory_rss_human:5.56M +used_memory_peak:1031608 +used_memory_peak_human:1007.43K +used_memory_peak_perc:86.17% +used_memory_overhead:842206 +used_memory_startup:790648 +used_memory_dataset:46746 +used_memory_dataset_perc:47.55% +total_system_memory:8049872896 +total_system_memory_human:7.50G +used_memory_lua:37888 +used_memory_lua_human:37.00K +maxmemory:0 +maxmemory_human:0B +maxmemory_policy:noeviction +mem_fragmentation_ratio:6.56 +mem_allocator:jemalloc-5.1.0 +active_defrag_running:0 +lazyfree_pending_objects:0 +#+end_src + +#+begin_src bash +>info stats +\# Stats +total_connections_received:10 +total_commands_processed:147 +instantaneous_ops_per_sec:0 +total_net_input_bytes:15473 +total_net_output_bytes:22212 +instantaneous_input_kbps:0.00 +instantaneous_output_kbps:0.00 +rejected_connections:0 +sync_full:0 +sync_partial_ok:0 +sync_partial_err:0 +expired_keys:0 +expired_stale_perc:0.00 +expired_time_cap_reached_count:0 +evicted_keys:0 +keyspace_hits:53 +keyspace_misses:15 +pubsub_channels:0 +pubsub_patterns:0 +latest_fork_usec:511 +migrate_cached_sockets:0 +slave_expires_tracked_keys:0 +active_defrag_hits:0 +active_defrag_misses:0 +active_defrag_key_hits:0 +active_defrag_key_misses:0 +#+end_src + +** 一些重要的指标 +主要看两部分:(memory和stats) +详细数据,上面已经给出 +*** Clients +| 参数 | 解释 | +| connected_clients | 连接的客户端数量 | +| blocked_clients | 等待阻塞命令的客户端的数量 | + + +*** memory + +| 参数 | 解释 | +| used_memory | 内存使用率 | +| used_memory_human | 人性化显示 | +| used_memory_rss | 已分配的内存总量 | +| mem_fragmentation_ratio | 内存碎片率 | +| used_memory_peak | Redis 的内存消耗峰值 | + +*** stats + +| 参数 | 解释 | +| total_connections_received | 服务器已接受的连接请求数量 | +| total_commands_processed | 命令处理数 | +| instantaneous_ops_per_sec | 当前qps,每日秒执行命令数 | +| instantaneous_input_kbps | redis网络入口kps | +| instantaneous_output_kbps | redis网络出口kps | +| rejected_connections | 最大客户端数量限制而被拒绝的连接请求数量 | +| expired_keys | 过期而被自动删除的键数量 | +| evicted_keys | 最大内存容量限制而被驱逐的键数量 | +| keyspace_hits | 查找键成功的次数 | +| keyspace_misses | 查找键失败的次数 | + +** 性能测试 + 一些主要命令的测试 +#+begin_src bash +>redis-benchmark -q + +PING_INLINE: 87412.59 requests per second +PING_BULK: 87489.06 requests per second +SET: 80000.00 requests per second +GET: 82508.25 requests per second +INCR: 89686.10 requests per second +LPUSH: 88731.15 requests per second +RPUSH: 81499.59 requests per second +LPOP: 87489.06 requests per second +RPOP: 86058.52 requests per second +SADD: 90009.01 requests per second +HSET: 80000.00 requests per second +SPOP: 86281.27 requests per second +LPUSH (needed to benchmark LRANGE): 86880.97 requests per second +LRANGE_100 (first 100 elements): 53850.30 requests per second +LRANGE_300 (first 300 elements): 20399.84 requests per second +LRANGE_500 (first 450 elements): 14577.26 requests per second +LRANGE_600 (first 600 elements): 11630.61 requests per second +MSET (10 keys): 78308.54 requests per second +#+end_src + +指定命令,添加管道 +#+begin_src bash +>redis-benchmark -t get -q -P 100 +GET: 1388889.00 requests per second +#+end_src + +| 选项 | 描述 | 默认值 | +| -h | 指定服务器主机名 | 127.0.0.1 | +| -p | 指定服务器端口 | 6379 | +| -s | 指定服务器 | socket | +| -c | 指定并发连接数 | 50 | +| -n | 指定请求数 | 10000 | +| -d | 以字节的形式指定SET/GET 值的数据大小 | 2 | +| -k | 1=keep alive 0=reconnect | 1 | +| -r | SET/GET/INCR 使用随机 key, SADD 使用随机值 | | +| -P | 通过管道传输 请求 | 1 | +| -q | 强制退出 redis。仅显示 query/sec 值 | | +| --csv | 以 CSV 格式输出 | | +| -l | 生成循环,永久执行测试 | | +| -t | 仅运行以逗号分隔的测试命令列表。 | | +| -I | Idle 模式,仅打开 N 个 idle 连接并等待 | | + + From 1d73cf7d1e1e2b7d73188277bfb1b6bca024593c Mon Sep 17 00:00:00 2001 From: flytrap Date: Wed, 24 Oct 2018 12:29:37 +0800 Subject: [PATCH 38/52] fix taiga env enter --- source/_posts/tech/python/taiga/taiga_env.org | 53 +++++++++++++------ 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/source/_posts/tech/python/taiga/taiga_env.org b/source/_posts/tech/python/taiga/taiga_env.org index 28f3ca39..487000d0 100644 --- a/source/_posts/tech/python/taiga/taiga_env.org +++ b/source/_posts/tech/python/taiga/taiga_env.org @@ -11,16 +11,21 @@ Taiga 是一个开源的项目管理工具,专注于解决管理工具的易 ** install python3 环境 Taiga 是使用python3写的,不兼容python2 -#+begin_src base +#+begin_src bash brew install python3 # mac 安装最新python3 apt-get install -y python3 # debian系列 dnf -y install python3 # 红帽系列 -arch 默认就是python3 不用装 +#+end_src +arch不需要, 默认就是python3 -# 安装虚拟环境virtualenvwrapper +#+begin_src bash +// 安装虚拟环境virtualenvwrapper mkvirtualenv -p /usr/local/bin/python3.6 taiga workon taiga -# 切换到taiga后端代码路径 +// 后端代码拉取 +git clone https://github.com/flytrap/taiga-back.git +git checkout weekly # 最新分支 +// 切换到taiga后端代码路径 pip install -r requirements.txt # 安装必须的包 -i 可以指定源 #+end_src @@ -29,30 +34,44 @@ pip install -r requirements.txt # 安装必须的包 -i 可以指定源 #+end_html ** 配置数据库 -#+begin_src bash +#+begin_src python +// 修改数据库连接 cp settings/local.py.example settings/local.py - -# 修改数据库连接 - -python manage.py migrate --noinput # 生成数据库模型 -python manage.py loaddata initial_user # 加载默认数据 +// 升级数据库表结构 +python manage.py migrate --noinput +// 加载默认数据 +python manage.py loaddata initial_user python manage.py loaddata initial_project_templates -python manage.py compilemessages # 编译语言包(国际化) -python manage.py collectstatic --noinput # 收集静态文件 -# python manage.py sample_data # 加载点儿数据,方便调试, 数据比较多,会比较慢 - +// 编译语言包(国际化) +python manage.py compilemessages +// 收集静态文件 +python manage.py collectstatic --noinput +// 加载点儿数据,方便调试, 数据比较多,会比较慢 +python manage.py sample_data #+end_src ** 配置文件修改 #+begin_src bash +// 修改数据库配置 cp settings/local.py.example settings/local.py -# 修改数据库配置 -MEDIA_URL = "http://localhost:9000/media/" # 端口不对,记得修改 +// 端口不对,记得修改 +MEDIA_URL = "http://localhost:9000/media/" STATIC_URL = "http://localhost:9000/static/" -还有发送邮件的邮箱服务器,消息队列redis,rabbitmq 等服务配置 +// 还有发送邮件的邮箱服务器,消息队列redis,rabbitmq 等服务配置 CELERY_ENABLED = True # 启动celery服务 #+end_src +** 前端开发环境运行 +#+begin_src bash +git clone https://github.com/flytrap/taiga-front.git +git checkout weekly +npm install -g gulp +npm install +gulp +#+end_src +编译好的taiga前端代码参考: +[[https://github.com/flytrap/taiga-front-dist][编译好的taiga前端代码参考]] + ** 运行项目 #+begin_src bash python manage.py runserver From 0c06cf265caca38d9e90b60039aa116ed1a1448a Mon Sep 17 00:00:00 2001 From: flytrap Date: Wed, 24 Oct 2018 15:56:56 +0800 Subject: [PATCH 39/52] fix redis info <> --- source/_posts/tech/redis/redis-info.org | 1 - 1 file changed, 1 deletion(-) diff --git a/source/_posts/tech/redis/redis-info.org b/source/_posts/tech/redis/redis-info.org index 52fad9e1..fb51e92a 100644 --- a/source/_posts/tech/redis/redis-info.org +++ b/source/_posts/tech/redis/redis-info.org @@ -127,7 +127,6 @@ active_defrag_key_misses:0 一些主要命令的测试 #+begin_src bash >redis-benchmark -q - PING_INLINE: 87412.59 requests per second PING_BULK: 87489.06 requests per second SET: 80000.00 requests per second From 42e452367399fb3edd8eaf66b06a01f6eb1b05ab Mon Sep 17 00:00:00 2001 From: flytrap Date: Thu, 22 Nov 2018 20:17:57 +0800 Subject: [PATCH 40/52] new: add ssh port forward --- package.json | 2 +- .../tech/hacker/reverse/reverse-command.md | 9 +++ source/_posts/tech/linux/alsamixer.org | 2 + .../tech/linux/ssh/ssh_port_forward.org | 76 +++++++++++++++++++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 source/_posts/tech/linux/ssh/ssh_port_forward.org diff --git a/package.json b/package.json index d78a5155..046ffa36 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "hexo": { - "version": "3.7.1" + "version": "3.8.0" }, "dependencies": { "hexo": "^3.3.8", diff --git a/source/_posts/tech/hacker/reverse/reverse-command.md b/source/_posts/tech/hacker/reverse/reverse-command.md index b50f4984..1424d3b9 100644 --- a/source/_posts/tech/hacker/reverse/reverse-command.md +++ b/source/_posts/tech/hacker/reverse/reverse-command.md @@ -1,3 +1,12 @@ +title: 逆向工具 +date: 2018-10-20 20:10:33 +tags: + - hacker + - reverse +layout: post +categories: tech +--- + ## 逆向工具命令: - ldd: 依赖链接库查看(mac 参考otool -L) - objdump: 依赖libbfd, 提取各种信息 diff --git a/source/_posts/tech/linux/alsamixer.org b/source/_posts/tech/linux/alsamixer.org index 0269742e..1a34b4ae 100644 --- a/source/_posts/tech/linux/alsamixer.org +++ b/source/_posts/tech/linux/alsamixer.org @@ -11,7 +11,9 @@ F6 选择网卡 F2 显示系统信息,可以看到系统中已有网卡信息 Esc 后退 +#+end_src +#+begin_src bash M 静音状态切换 Q,W,E 增大 左,右,通道 的音量 Z,X,C 减小 左,右,通道 的音量 diff --git a/source/_posts/tech/linux/ssh/ssh_port_forward.org b/source/_posts/tech/linux/ssh/ssh_port_forward.org new file mode 100644 index 00000000..2e08125d --- /dev/null +++ b/source/_posts/tech/linux/ssh/ssh_port_forward.org @@ -0,0 +1,76 @@ +#+TITLE: ssh port forward +#+DATE: <2018-11-22> +#+TAGS: ssh,port,forward,hacker +#+LAYOUT: post +#+CATEGORIES: tech + +* Summary +通过公网连接不同的局域网,使其就像同一个局域网内部访问一般。 + +** 一些额外参数 +#+begin_src bash +-f 通常和-N连用,不登录到远程主机,就是后台执行的意思 +-N 不执行脚本或命令,通常与-f连用 +-g 在-L/-R/-D参数中,允许远程主机连接到建立的转发的端口,如果不加这个参数,只允许本地主机建立连接 +-q quiet模式,忽视大部分的警告和诊断信息 +-T 禁用tty分配 +-n 重定向stdin为/dev/null,用于配合-f后台任务 +#+end_src + +** 建立专门的linux账号用户用于端口转发(考虑安全性) +不让该账户执行命令 +#+begin_src bash +useradd -m tunnel +passwd tunnel +chsh -s /bin/false tunnel +#+end_src + +** 绑定本地端口(-D)(socket5代理) +转发本地端口流量至指定主机 + +#+begin_src bash +ssh -D 8888 user@host +#+end_src + +这样所有来到本地8888端口的流量都有发送到host主机,就是远程主机 +应用场景:数据过滤,限制指定主机上网,代理,等等. +#+begin_html + +#+end_html +** 本地端口转发(-L) +两个不同的局域网通信,对,两台要通信的机器都没有公网ip,只能借助以中间人(拥有公网ip的机制)进行通信. + +#+begin_src bash +-L 本地网卡地址:本地端口:目标地址:目标端口 +ssh -L 2121:host2:21 user@host3 +#+end_src +访问本地2121 就相当于访问host2的21端口 +对于确定的两个内网环境,这是一个挺不错的选择. +** 远程端口转发(-R) + +#+begin_src bash +-R 远程网卡地址:远程端口:目标地址:目标端口 +ssh -qTfNn -R 4567:localhost:3456 user@remote_host +#+end_src + +将目标地址机器的目标端口映射到远程机器的远程端口上 + +通过不确定的主机去访问确定的主机 + +场景:反弹式后门瞬间通畅, 在家里连接工作电脑. + + +这里说明一下,第一个地址是可以忽略的 +** 遇到的一些问题 +*** 远程主机的端口监听的是127.0.0.1 +解决方法 +#+begin_src bash +vim /etc/ssh/sshd_config +#+end_src +#+begin_src ini +GatewayPorts yes +#+end_src +找到GatewayPorts这个选项,并改为yes,默认是注释的. +然后重启sshd服务 + +重试一下ssh连接看. From 2cf3033aaa9ca6f27416a7651d074a1c4e14415d Mon Sep 17 00:00:00 2001 From: flytrap Date: Thu, 10 Jan 2019 18:02:27 +0800 Subject: [PATCH 41/52] new: add dns related command --- source/_posts/tech/hacker/dns.org | 59 +++++++++++++++++++++ source/_posts/tech/hacker/sub_dns_tools.org | 12 ++++- 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 source/_posts/tech/hacker/dns.org diff --git a/source/_posts/tech/hacker/dns.org b/source/_posts/tech/hacker/dns.org new file mode 100644 index 00000000..c34d5877 --- /dev/null +++ b/source/_posts/tech/hacker/dns.org @@ -0,0 +1,59 @@ +#+TITLE: 域名信息收集工具 +#+DATE: <2019-01-10> +#+TAGS: dns,nslookup,dig +#+LAYOUT: post +#+CATEGORIES: tech + +** nslookup +非交互模式 +#+begin_src bash +nslookup www.baidu.com +nslookup -type=ns www.baidu.com 8.8.8.8 +#+end_src + +交互模式 +#+begin_src bash +nslookup +>www.baidu.com # 查询指定域名 +>server 8.8.8.8 # 设置dns服务器 +>set type=ns # 设置记录类型 +#+end_src + +整个查询过程一般会有多个步骤,从根一级级查询回来,回来的记录可能还是一个域名,继续查询,最终得到ip。 +当然,这个过程自动完成,想看细节,最好抓包去看。 +#+begin_html + +#+end_html +** dig +通过dns(8.8.8.8)查询www.baidu.com 的mx记录,得到了cname记录,意味着域名指向了域名 +#+begin_src bash +dig @8.8.8.8 www.baidu.com mx +www.baidu.com. 1094 IN CNAME www.a.shifen.com. +www.a.shifen.com. 48 IN CNAME www.wshifen.com. +#+end_src + +反向查询,加个精简参数 +#+begin_src bash +dig +short -x 8.8.8.8 +google-public-dns-a.google.com. +#+end_src + +查询bind版本信息,获取所有记录的最佳策略 +#+begin_src bash +dig +noall +answer txt chaos VERSION.BIND @ns3.dnsv4.com +VERSION.BIND. 0 CH TXT "1.1.1711.01" +#+end_src + +区域传输,相当于是同步数据,很多都不接受,接受的话就可以拿到所有子域名. +通过百度的dns服务器去获取 +#+begin_src bash +dig @ns4.baidu.com baidu.com axfr +; Transfer failed. +host -T -l baidu.com ns4.baidu.com # 关键参数[-l]执行axfr的全区域差异传输,-T表示时间 +Host baidu.com not found: 5(REFUSED) +#+end_src + +查询过程追踪,获取整个查询路径,访问到的所有dns服务器. +#+begin_src bash +dig +trace www.baidu.com +#+end_src diff --git a/source/_posts/tech/hacker/sub_dns_tools.org b/source/_posts/tech/hacker/sub_dns_tools.org index 4b7d391f..0631fc20 100644 --- a/source/_posts/tech/hacker/sub_dns_tools.org +++ b/source/_posts/tech/hacker/sub_dns_tools.org @@ -2,7 +2,7 @@ #+DATE: <2018-08-27> #+TAGS: dns,sub #+LAYOUT: post -#+CATEGORIES: live +#+CATEGORIES: tech ** virustotal https://www.virustotal.com @@ -15,4 +15,12 @@ https://dnsdumpster.com/ 这个应该是最好用的 比较全面 - +** 暴力破解 +#+begin_src bash +fierce -dnsserver 8.8.8.8 -dns sina.com.cn -wordlist a.txt +dnsdict6 -d4 -t 16 -x sina.com +dnsenum -f dnsbig.txt -dnsserver 8.8.8.8 sina.com -o sina.xml +dnsmap sina.com -w dns.txt +dnsrecon -d sina.com --lifetime 10 -t brt -D dnsbig.txt +dnsrecon -t std -d sina.com +#+end_src From af2666a1996ec0945aef41cb1572ff47d0ba62df Mon Sep 17 00:00:00 2001 From: flytrap Date: Mon, 4 Mar 2019 12:13:58 +0800 Subject: [PATCH 42/52] fix: html tag error --- source/_posts/tech/java/spring_sentry.org | 1 - 1 file changed, 1 deletion(-) diff --git a/source/_posts/tech/java/spring_sentry.org b/source/_posts/tech/java/spring_sentry.org index 32f4d12b..2df4838e 100644 --- a/source/_posts/tech/java/spring_sentry.org +++ b/source/_posts/tech/java/spring_sentry.org @@ -26,7 +26,6 @@ config public HandlerExceptionResolver sentryExceptionResolver() { return new io.sentry.spring.SentryExceptionResolver(); } - @Bean public ServletContextInitializer sentryServletContextInitializer() { return new io.sentry.spring.SentryServletContextInitializer(); From e5c5e1801270609eb213a8e104f2f556297f34ca Mon Sep 17 00:00:00 2001 From: flytrap Date: Mon, 4 Mar 2019 12:18:46 +0800 Subject: [PATCH 43/52] chg: change text --- yilia_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yilia_config.yml b/yilia_config.yml index 8c22321c..6325aa49 100644 --- a/yilia_config.yml +++ b/yilia_config.yml @@ -108,7 +108,7 @@ slider: #smart_menu: # friends: false smart_menu: - innerArchive: '所有文章' + innerArchive: '搜索文章' friends: '友链' aboutme: '关于我' From 351ae3da7743ca6f9a89457684ed58c246b8607f Mon Sep 17 00:00:00 2001 From: flytrap Date: Mon, 25 Mar 2019 15:47:55 +0800 Subject: [PATCH 44/52] new: add mysql nginx --- source/_posts/tech/java/spring_sentry.org | 1 - source/_posts/tech/linux/deploy/nginx.org | 87 ++++++++++++++++++++++ source/_posts/tech/linux/mysql.org | 48 ++++++++++++ source/_posts/tech/linux/ssh/ssh_login.org | 56 ++++++++++++++ 4 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 source/_posts/tech/linux/deploy/nginx.org create mode 100644 source/_posts/tech/linux/mysql.org create mode 100644 source/_posts/tech/linux/ssh/ssh_login.org diff --git a/source/_posts/tech/java/spring_sentry.org b/source/_posts/tech/java/spring_sentry.org index 2df4838e..1bcf4ddd 100644 --- a/source/_posts/tech/java/spring_sentry.org +++ b/source/_posts/tech/java/spring_sentry.org @@ -103,7 +103,6 @@ public class GlobalExceptionHandler { private void sendSentry(Exception e) { Dsn dsn = new Dsn(dsnUrl); Raven raven = (new DefaultRavenFactory()).createRavenInstance(dsn); - Throwable throwable = new Throwable(e.getMessage(), e.getCause()); throwable.setStackTrace(e.getStackTrace()); raven.sendException(throwable); diff --git a/source/_posts/tech/linux/deploy/nginx.org b/source/_posts/tech/linux/deploy/nginx.org new file mode 100644 index 00000000..9fe865a5 --- /dev/null +++ b/source/_posts/tech/linux/deploy/nginx.org @@ -0,0 +1,87 @@ +#+TITLE: nginx 日常 +#+DATE: <2019-03-13> +#+TAGS: nginx,linux,deploy +#+LAYOUT: post +#+CATEGORIES: tech + + +** 遇到的一些问题 +- 大文件无法上传 + +#+begin_src bash +server{ + client_max_body_size 30m; # 默认是1m + ... +} +#+end_src + +#+begin_html + +#+end_html + +** 常用配置 +#+begin_src config +server { + listen 80; + server_name hostname.com; + location / { + if ($request_method = GET) { + rewrite ^ https://$host$request_uri? permanent; # http强制跳转 + } + return 405; + } + access_log /var/log/nginx/hostname/hostname.log main; +} +server { + listen 443; + server_name hostname.com; + client_max_body_size 10m; + ssl on; + ssl_certificate /etc/nginx/ssl/hostname.com.crt; # ssl证书 + ssl_certificate_key /etc/nginx/ssl/hostname.com.key; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_redirect off; + # keepalive + raven.js is a disaster + keepalive_timeout 0; + location / { + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $host; + proxy_pass http://localhost:8000; + add_header Strict-Transport-Security "max-age=31536000"; + } + access_log /var/log/nginx/hostname/hostname_ssl.log main; + error_log /var/log/nginx/hostname/hostname_ssl_error.log; +} +#+end_src + +** 正则配置 +- 等号(=):表示完全匹配规则才执行操作 + +#+begin_src config +location = / {} +#+end_src +- 波浪号(~):表示执行正则匹配,但区分大小写 + +#+begin_src config +location ~ /page/\d{1,3} {} +#+end_src +- 波浪号与星号(~*):表示执行正则匹配,但不 区分大小写 + +#+begin_src config +location ~* /\.(jpg|jpeg|gif) {} +#+end_src +- 脱字符与波浪号(^~):表示普通字符匹配,前缀匹配有效,配置生效 + +#+begin_src config +location ^~ /images/ {} # http://{hostname}/images/test +#+end_src +- @ :定义一个location,用于处理内部重定向 + +#+begin_src config +location @error { + proxy_pass http://error; +} +error_page 404 @error; +#+end_src diff --git a/source/_posts/tech/linux/mysql.org b/source/_posts/tech/linux/mysql.org new file mode 100644 index 00000000..44100c9d --- /dev/null +++ b/source/_posts/tech/linux/mysql.org @@ -0,0 +1,48 @@ +#+TITLE: mysql记录 +#+DATE: <2019-03-14> +#+TAGS: linux,server,mysql +#+LAYOUT: post +#+CATEGORIES: tech + + +** 配置相关 +- 监听公网ip,修改端口 + +#+begin_src bash +sudo vim /etc/mysql/my.cnf +# 修改内容如下 +port=3389 +bind-address='0.0.0.0' +#+end_src + +#+begin_html + +#+end_html + +** 权限相关 +- 创建host + +#+begin_src sql +select user,host from user; +update user set host='%' where user='root'; +flush privileges; +#+end_src +- 授权root用户所有人可以登录 + +#+begin_src sql +GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Password' WITH GRANT OPTION; +flush privileges; +#+end_src +- 允许指定用户(user),ip(192.168.1.1)访问 + +#+begin_src sql +GRANT ALL PRIVILEGES ON *.* TO 'user'@'192.168.1.1' IDENTIFIED BY 'mypwd' WITH GRANT OPTION; +flush privileges; +#+end_src + +** 初始化密码获取 +mysql 5.7 会初始化密码,之前版本没有密码就可以直接登录,5.7必须要用密码了 +#+begin_src bash +cat /var/log/mysqld.log |grep password # 一般都是在第一行 +mysql -u root -p # 输入刚才获取的密码就可以登录了 +#+end_src diff --git a/source/_posts/tech/linux/ssh/ssh_login.org b/source/_posts/tech/linux/ssh/ssh_login.org new file mode 100644 index 00000000..308016f5 --- /dev/null +++ b/source/_posts/tech/linux/ssh/ssh_login.org @@ -0,0 +1,56 @@ +#+TITLE: 服务器ssh登录配置 +#+DATE: <2019-03-13> +#+TAGS: ssh,login +#+LAYOUT: post +#+CATEGORIES: tech + +* 服务器ssh登录配置 + +** Summary +服务器的安全问题,务必要认真对待。 +安全策略: +- 不允许root登录 +- 不允许密码登录,key +- 修改ssh监听端口 +- 只允许指定ip 访问,就是白名单 + +** 配置文件 +#+begin_src bash +vim /etc/ssh/sshd_config +# 修改内容如下: +Port 22 # 取消注释,修改监听端口 +StrictModes yes # 用户权限鉴定的,建议设置 +RSAAuthentication yes # RSA 公钥鉴定 +PubkeyAuthentication yes # 允许key的方式登录 +PermitRootLogin no # 不允许root登录 +PasswordAuthentication no # 不允许密码登录 +# 添加ssh 公钥到 +vim ~/.ssh/authorized_keys # 这个文件每一行代表一个公共key +chmod 600 ~/.ssh/authorized_keys +chmod 700 ~/.ssh +# 重启sshd服务 +systemctl restart sshd +#+end_src + +#+begin_html + +#+end_html + +** 生成ssh 秘钥对,并添加 +#+begin_src bash +# 本地生成ssh +ssh-keygen -t rsa -f ~/.ssh/id_rsa_key +scp -P 22 ~/.ssh/id_rsa user@hostname:/tmp +# 进入服务器 +cat /tmp/id_rsa_test >> ~/.ssh/authorized_keys # 追加key过去 +#+end_src + +这样scp命令,ssh命令就可以不输入密码了. + + +** 白名单 +#+begin_src bash +vim /etc/ssh/sshd_config +添加AllowUsers字段 +AllowUsers deploy@192.168.1.1 # 用户名deploy ip 192.168.1.1 +#+end_src From 5a0934a60fb128c73c4e736b70256fed8bbb66ad Mon Sep 17 00:00:00 2001 From: flytrap Date: Sun, 2 Jun 2019 12:15:40 +0800 Subject: [PATCH 45/52] =?UTF-8?q?new:=20=E6=96=B0=E5=A2=9Exrandr=20?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/tech/linux/xrandr.org | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 source/_posts/tech/linux/xrandr.org diff --git a/source/_posts/tech/linux/xrandr.org b/source/_posts/tech/linux/xrandr.org new file mode 100644 index 00000000..889d62de --- /dev/null +++ b/source/_posts/tech/linux/xrandr.org @@ -0,0 +1,85 @@ +#+TITLE: linux 多显示器管理 +#+DATE: <2019-06-02> +#+TAGS: xrandr,linux,i3wm +#+LAYOUT: post +#+CATEGORIES: tech + +* linux 通过命令行控制左面显示 + +** Summary +我这里使用的i3wm 窗口管理器. +所以,操作的话,基本是靠命令来完成的 +现在我需要使用多个显示器,就用到了xrandr这个工具 + +** 可用显示器展示 +#+begin_src bash +> xrandr +eDP-1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 276mm x 155mm + 1366x768 60.11*+ + 1280x720 60.00 59.99 59.86 59.74 + 1024x768 60.04 60.00 + 960x720 60.00 + 928x696 60.05 + 896x672 60.01 + 1024x576 59.95 59.96 59.90 59.82 + 960x600 59.93 60.00 + 960x540 59.96 59.99 59.63 59.82 + 800x600 60.00 60.32 56.25 + 840x525 60.01 59.88 + 864x486 59.92 59.57 + 700x525 59.98 + 800x450 59.95 59.82 + 640x512 60.02 + 700x450 59.96 59.88 + 640x480 60.00 59.94 + 720x405 59.51 58.99 + 684x384 59.88 59.85 + 640x400 59.88 59.98 + 640x360 59.86 59.83 59.84 59.32 + 512x384 60.00 + 512x288 60.00 59.92 + 480x270 59.63 59.82 + 400x300 60.32 56.34 + 432x243 59.92 59.57 + 320x240 60.05 + 360x202 59.51 59.13 + 320x180 59.84 59.32 +DP-1 disconnected primary (normal left inverted right x axis y axis) +HDMI-1 disconnected (normal left inverted right x axis y axis) +DP-2 connected 1024x768+0+0 (normal left inverted right x axis y axis) 0mm x 0mm + 1024x768 60.00* + 800x600 60.32 56.25 + 848x480 60.00 + 640x480 59.94 +#+end_src +#+begin_html + +#+end_html +可以看到我这里有两个显示器,一个叫eDP-1, 还有一个叫DP-2 + +多显示器使用无非两种,一种镜像复制,还有就是扩展 + +** 镜像 +#+begin_src bash +xrandr --output eDP-1 --output DP-2 --same-as eDP-1 --auto +#+end_src +解释一下: 意思就是通过eDP-1 复制一个一样的DP-2 分辨率自动最大 +当然也可以制定分辨率 + +** 扩展 +一般来说扩展用的比较多一点儿,所以多说几句 +#+begin_src bash +xrandr --output eDP-1 --output DP-2 --right-of eDP-1 +#+end_src +意思是在eDP-1的右边扩展一个显示器DP-2,当然这里也可以指定位置 +--pos指定坐标,显示器可能不一样大 +--left-of: 左边(上下左右都可以),这里就不一一列举了(man xrandr) + +** 最后 +推荐 i3wm 窗口管理器 +有三点好处: +#+begin_src markdown +1,启动快,轻量级,可塑性强,非常方便定制. +2,逼格够,看起来就是一个纯命令使用环境,你懂得,所有软件的开启都是命令. +3,使用方便,其他桌面环境(如gnome)可以使用的软件,一个也不少的都可以使用,非常符合,linux命令操作思想 +#+end_src From 7121d502a4e994148a996710c9625322662f882d Mon Sep 17 00:00:00 2001 From: flytrap Date: Tue, 18 Jun 2019 11:31:04 +0800 Subject: [PATCH 46/52] =?UTF-8?q?fix:=20=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/tech/linux/docker.org | 11 +++++++++++ source/_posts/tech/linux/xrandr.org | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/source/_posts/tech/linux/docker.org b/source/_posts/tech/linux/docker.org index 0772f1eb..b1a2afc0 100644 --- a/source/_posts/tech/linux/docker.org +++ b/source/_posts/tech/linux/docker.org @@ -63,3 +63,14 @@ docker search mysql docker pull mysql docker run --name mysql1 -p 3306:3306 -e MYSQL\_ROOT\_PASSWORD=root -v /home/flytrap/data/mysql:/var/lib/mysql --restart always -d mysql #+end_src + +* 普通用户添加操作权限 +#+begin_src bash +docker ps # 报错 +Got permission denied while trying to connect to the Docker daemon socket ... +# 添加普通用户权限 +sudo groupadd docker # 添加docker用户组,已存在,就不会添加,一般安装完docker就已经存在了 +sudo gpasswd -a $USER docker # 将登陆用户加入到docker用户组中 +newgrp docker # 更新用户组 +docker ps # 测试一下 +#+end_src diff --git a/source/_posts/tech/linux/xrandr.org b/source/_posts/tech/linux/xrandr.org index 889d62de..9e37364a 100644 --- a/source/_posts/tech/linux/xrandr.org +++ b/source/_posts/tech/linux/xrandr.org @@ -4,7 +4,7 @@ #+LAYOUT: post #+CATEGORIES: tech -* linux 通过命令行控制左面显示 +* linux 通过命令行控制桌面显示 ** Summary 我这里使用的i3wm 窗口管理器. From 3f0e91b038d7d490de0ba1e26646a8f23b226105 Mon Sep 17 00:00:00 2001 From: Gaohg Date: Fri, 12 Apr 2024 18:44:09 +0800 Subject: [PATCH 47/52] =?UTF-8?q?new:=20=E5=A2=9E=E5=8A=A0env?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- package.json | 35 +- source/_posts/tech/env/gitlab.md | 44 +++ source/_posts/tech/env/jenkins.md | 247 +++++++++++++ source/_posts/tech/env/k8s.md | 490 +++++++++++++++++++++++++ source/_posts/tech/env/k8s_problems.md | 77 ++++ 6 files changed, 880 insertions(+), 15 deletions(-) create mode 100644 source/_posts/tech/env/gitlab.md create mode 100644 source/_posts/tech/env/jenkins.md create mode 100644 source/_posts/tech/env/k8s.md create mode 100644 source/_posts/tech/env/k8s_problems.md diff --git a/.gitignore b/.gitignore index 70d5ec27..48a33105 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ public/ *# #* package-lock.json - +themes/ diff --git a/package.json b/package.json index 046ffa36..b8737dbc 100644 --- a/package.json +++ b/package.json @@ -2,22 +2,29 @@ "name": "hexo-site", "version": "0.0.0", "private": true, + "scripts": { + "build": "hexo generate", + "clean": "hexo clean", + "deploy": "hexo deploy", + "server": "hexo server" + }, "hexo": { - "version": "3.8.0" + "version": "6.3.0" }, "dependencies": { - "hexo": "^3.3.8", - "hexo-deployer-git": "^0.3.0", - "hexo-generator-archive": "^0.1.4", - "hexo-generator-category": "^0.1.3", - "hexo-generator-feed": "^1.2.0", - "hexo-generator-index": "^0.2.0", - "hexo-generator-json-content": "^3.0.1", - "hexo-generator-tag": "^0.2.0", - "hexo-renderer-ejs": "^0.2.0", - "hexo-renderer-marked": "^0.2.10", - "hexo-renderer-orgmode": "^1.0.1", - "hexo-renderer-stylus": "^0.3.1", - "hexo-server": "^0.2.0" + "hexo": "^6.3.0", + "hexo-generator-archive": "^2.0.0", + "hexo-generator-category": "^2.0.0", + "hexo-generator-index": "^3.0.0", + "hexo-generator-tag": "^2.0.0", + "hexo-renderer-ejs": "^2.0.0", + "hexo-renderer-marked": "^6.0.0", + "hexo-renderer-stylus": "^3.0.1", + "hexo-server": "^3.0.0", + "hexo-theme-landscape": "^1.0.0", + "hexo-deployer-git": "^4.0.0", + "hexo-generator-feed": "^3.0.0", + "hexo-generator-json-content": "^4.2.3", + "hexo-renderer-orgmode": "^1.0.1" } } \ No newline at end of file diff --git a/source/_posts/tech/env/gitlab.md b/source/_posts/tech/env/gitlab.md new file mode 100644 index 00000000..03de8da7 --- /dev/null +++ b/source/_posts/tech/env/gitlab.md @@ -0,0 +1,44 @@ +--- +title: gitlab +author: flytrap +categories: + - tech +tags: + - tech + - gitlab + - docker-compose +date: 2024-04-12 10:04:28 +--- + +GitLab 是由 GitLab 公司开发的、基于 Git 的集成软件开发平台。另外,GitLab 且具有 wiki 以及在线编辑、issue 跟踪功能、CI/CD 等功能。 +[官网: https://gitlab.com](https://about.gitlab.com) + + + +## 部署 + +建议使用 docker 容器化部署,此处给出常用 docker-compose 配置文件 + +```bash +version: '3.9' +services: + gitlab: + image: 'gitlab/gitlab-ce:latest' + container_name: "gitlab" + restart: always + privileged: true + hostname: 'gitlab' + environment: + TZ: 'Asia/Shanghai' + GITLAB_OMNIBUS_CONFIG: | + external_url 'http://192.168.1.12' + ports: + - '3000:80' + - '80:80' + - '443:443' + - '22:22' + volumes: + - './etc:/etc/gitlab' + - './log:/var/log/gitlab' + - './opt:/var/opt/gitlab' +``` diff --git a/source/_posts/tech/env/jenkins.md b/source/_posts/tech/env/jenkins.md new file mode 100644 index 00000000..38529d1d --- /dev/null +++ b/source/_posts/tech/env/jenkins.md @@ -0,0 +1,247 @@ +--- +title: jenkins +author: flytrap +categories: + - tech +tags: + - tech + - jenkins + - jenkins2 + - pipeline + - docker-compose +date: 2024-04-11 10:04:28 +--- + +Jenkins 提供了软件开发的持续集成服务。它运行在 Servlet 容器中(例如 Apache Tomcat)。它支持软件配置管理(SCM)工具(包括 AccuRev SCM、CVS、Subversion、Git、Perforce、Clearcase 和 RTC),可以执行基于 Apache Ant 和 Apache Maven 的项目,以及任意的 Shell 脚本和 Windows 批处理命令。 +[官网: https://www.jenkins.io](https://www.jenkins.io) + + + +## 部署 + +建议使用 docker 容器化部署,此处给出常用 docker-compose 配置文件 + +```bash +version: '3.9' +services: + jenkins: + image: jenkins/jenkins:2.440.1 + container_name: jenkins + # 重启策略:除非手动停止,否则出错会无限重启 + restart: unless-stopped + privileged: true + ports: + # 8080 为 Jenkins 的 Web 端口 + - 8080:8080 + # 50000 为代理节点与主服务器的通信端口? + - 50000:50000 + volumes: + # 同步宿主机的时间 + - /etc/timezone:/etc/timezone + - /usr/local/bin/helm:/usr/local/bin/helm + - /etc/localtime:/etc/localtime + # Jenkins 数据目录映射出来,方面操作和备份 + - ./jenkins_home:/var/jenkins_home + # 把宿主机的 docker 和 docker-compose 给 Jenkins 使用,这样可以直接在 Jenkins 内部打镜像,并直>接操作容器 + - /usr/bin/docker:/usr/bin/docker + - /var/run/docker.sock:/var/run/docker.sock + - /usr/bin/docker-compose:/usr/bin/docker-compose +``` + +当然也可以在容器页面上直接添加容器 + +访问 :8080 即可打开 Jenkins +此处可以看到初始化密码路径, 就在 jenkins_home/secrets 目录下面 + +登录之后创建管理员账号 + +## 插件安装 + +界面打开: 系统管理-> 插件管理 (/manage/pluginManager/) + +- Workspace Cleanup Plugin # 构建完成后清理 +- Timestamper # 日志事件显示 +- Build Timeout # 构建时间统计 +- SSH server # 远程执行 +- Pipeline # 流水线 +- Localization: Chinese (Simplified) # 汉化(可选) +- Kubernetes CLI Plugin # k8s 命令调用插件(可选) +- GitLab Plugin # gitlab 插件 +- Git Parameter Plug-In # 参数构建 +- Active Choices # 参数选择 + +## 流水线基础配置 + +### 前置配置 + +1. 添加 gitlab 秘钥 +2. “系统管理” -> “系统设置“ -> “Gitlab” 填写 gitlab 信息 +3. 添加 k8s 秘钥 +4. 添加 docker 秘钥 + +### 新建任务 + +1. 新建任务 +2. 输入任务名称 +3. 选择流水线类型任务 +4. GitLab Connection 选择 gitlab Credential +5. 勾选不允许并发构建 +6. 选择构建触发器, 获取 webhook 地址 以及 Secret token +7. 填入必要的构建选项, 一般只需要 push event 即可, 也可以定时构建 +8. 填入 pipeline 代码 + +## pipeline 编写 + +### 构建需求 + +1. 通过 git tag 标记版本号 +2. 推送 tag 触发构建 +3. 构建过程中生成版本镜像,helm 并推送至对应仓库 +4. 发布 helm 到 k8s 环境中 + +### 示例代码 + +```groovy +// helm 发布 +def helmDeploy(Map args) { + // Helm 尝试部署 + if (args.dry_run) { + println '尝试 Helm 部署,验证是否能正常部署' + sh 'helm repo update' + sh "helm upgrade --install ${args.name} --version ${args.version} --set image.repository=${args.repository} --set image.tag=${args.version} chartmuseum/${args.name} --dry-run --debug" + } + // Helm 正式部署 + else { + println '正式 Helm 部署' + sh 'helm repo update' + sh "helm upgrade --install ${args.name} --version ${args.version} --set image.repository=${args.repository} --set image.tag=${args.version} chartmuseum/${args.name}" + } +} + +def noticeRtx(String ids, String info) {} + +pipeline { + agent any + parameters { + string(name: 'project_name', defaultValue: 'rbac-service', description: '项目名称') + string(name: 'repo_url', defaultValue: 'git@192.168.1.28:Web/rbac-service.git', description: 'git 仓库') + // Git Parameter + gitParameter(name: 'tag_name', + type: 'PT_TAG', + branchFilter: 'origin/(.*)', + defaultValue: '0.0.1', + selectedValue: 'DEFAULT', + sortMode: 'DESCENDING_SMART', + useRepository: env.repo_url, + description: 'git 标签') + } + + stages { + stage('Init') { + steps { + sh 'printenv' + script { + if (env.gitlabSourceRepoSshUrl) { + env.repo_url = env.gitlabSourceRepoSshUrl + } + if (env.gitlabSourceRepoName) { + env.project_name = env.gitlabSourceRepoName + } + if (env.gitlabSourceBranch) { + env.tag_name = env.gitlabSourceBranch.split('/')[-1] + } + } + buildName "#${BUILD_NUMBER}-${project_name}-${tag_name}" + } + } + + stage('Source') { + steps { + checkout([$class: 'GitSCM', branches: [[name: "refs/tags/${tag_name}"]], userRemoteConfigs: [[url: "${repo_url}"]]]) + script { + env.imagePath = project_name + env.repository = env.imagePath + ':' + env.tag_name + env.commitInfo = sh(script:'git log --oneline --no-merges|head -1', returnStdout: true) + } + echo 'repository: ' + env.repository + } + } + + stage('Build') { + steps { + echo 'build repository: ' + env.repository + script { + docker.withRegistry('https://hub.docker.com') { + def customImage = docker.build(repository) + customImage.push() + + sh 'docker images | grep citest | awk \'{print $1":"$2}\' | xargs docker rmi -f || true' + sh 'docker rmi -f `docker images | grep \'\' | awk \'{print $3}\'` || true' + } + } + } + } + + stage('PackageHelm') { + steps { + echo 'package helm' + sh 'helm package ' + 'chart/' + project_name + ' --app-version ' + env.tag_name + ' --version ' + env.tag_name + echo 'push helm' + sh 'helm cm-push ' + env.project_name + '-' + env.tag_name + '.tgz chartmuseum -f' + } + } + + stage('Deploy') { + steps { + withKubeConfig([credentialsId: 'k8s 密钥id', serverUrl: 'k8s地址']) { + // 执行 Helm 方法 + echo 'Helm 执行部署测试' + helmDeploy(dry_run: true ,name: env.project_name , repository: env.imagePath , version: env.tag_name) + echo 'Helm 执行正式部署' + helmDeploy(dry_run: false, name: env.project_name, repository: env.imagePath, version: env.tag_name) + } + } + } + + stage('Clean') { + steps { + cleanWs( + cleanWhenAborted: true, + cleanWhenFailure: true, + cleanWhenNotBuilt: true, + cleanWhenSuccess: true, + cleanWhenUnstable: true, + cleanupMatrixParent: true, + disableDeferredWipeout: true, + deleteDirs: true + ) + } + } + } + + post { + always { + echo env.project_name + ': 项目构建完成' + } + success { + echo env.project_name + ': 构建成功' + noticeRtx("", env.user + '成功构建了: ' + env.project_name + '\n版本号: ' + env.tag_name + '\n更新内容: \n' + env.commitInfo) + } + unstable { + echo env.project_name + ': 构建过程报错' + noticeRtx("", env.user + '构建: ' + env.project_name + '失败了 \n版本号: ' + env.tag_name + '\n更新内容: \n' + env.commitInfo) + } + failure { + echo env.project_name + ': 构建失败' + noticeRtx("", env.user + '构建: ' + env.project_name + '失败了 \n版本号: ' + env.tag_name + '\n更新内容: \n' + env.commitInfo) + } + } +} + +``` + +### 脚本说明 + +1. 脚本分六个阶段构建 +2. 初始化,拉取代码,构建镜像,构建 helm,发布到 k8s,清理 +3. 构建完成通知 diff --git a/source/_posts/tech/env/k8s.md b/source/_posts/tech/env/k8s.md new file mode 100644 index 00000000..74463cee --- /dev/null +++ b/source/_posts/tech/env/k8s.md @@ -0,0 +1,490 @@ +--- +title: k8s 部署 +author: flytrap +categories: + - tech +tags: + - tech + - k8s + - kubernetes +date: 2024-03-16 10:00:00 +--- + +Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。 +Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。K8s 这个缩写是因为 K 和 s 之间有 8 个字符的关系。 Google 在 2014 年开源了 Kubernetes 项目。 Kubernetes 建立在 Google 大规模运行生产工作负载十几年经验的基础上, 结合了社区中最优秀的想法和实践。 +[官网: https://kubernetes.io](https://kubernetes.io) + +主要记录官网的安装部署实践, 以及一些遇到的问题 + + + +## 初始化服务器状态(所有节点) + +1. 首先修改 init-config.sh 中的主节点 ip 信息,和 node 节点 ip 信息 + +```bash +# 初始化配置文件 +#! /bin/bash +master_ips=(192.168.1.101 192.168.1.102 192.168.1.103) +node_ips=(192.168.1.104 192.168.1.105) +vip=192.168.1.151 # ip高可用 +ethname=ens160 # 网卡名称 + +cp conf/hosts.tpl hosts # 需要准备一份host对应关系 + +haproxy_nodes="" +hostname="" +hostip=$(ip addr show $ethname | grep -w inet | awk '{print $2}' | cut -d'/' -f1) + +# 写入hosts +echo "write master hosts" +for ((i=1; i<=${#master_ips[@]}; i++)) +do + # 获取IP地址和索引 + ip="${master_ips[$i-1]}" + index="$i" + if [ "$ip" = "$hostip" ]; then + hostname=master$index + fi + + # 根据IP创建hosts格式的条目,并追加到文件 + echo "$ip master$index" >> hosts + haproxy_nodes="${haproxy_nodes}server master$index $ip:6443 check\n " +done + +echo "write node hosts" +for ((i=1; i<=${#node_ips[@]}; i++)) +do + # 获取IP地址和索引 + ip="${node_ips[$i-1]}" + index="$i" + + if [ "$ip" = "$hostip" ]; then + hostname=node$index + fi + + # 根据IP创建hosts格式的条目,并追加到文件 + echo "$ip node$index" >> hosts +done + +echo "product haproxy.cfg" +sed "s/{{nodes}}/$haproxy_nodes/g" conf/haproxy.cfg.tpl > haproxy.cfg + +echo "product keepalived.conf" +sed "s/{{vip}}/$vip/g" conf/keepalived.conf.tpl > keepalived.conf + +echo "product kubeadm-config.yaml" +sed "s/{{vip}}/$vip/g; s/{{hostname}}/$hostname/g; s/{{hostip}}/$hostip/g" conf/kubeadm-config.yaml.tpl > kubeadm-config.yaml + +sudo hostnamectl set-hostname "${hostname}" + +``` + +### haproxy.cfg.tpl + +```bash +global + log /dev/log local0 + log /dev/log local1 notice + log 127.0.0.1 local0 err + chroot /var/lib/haproxy + stats socket /run/haproxy/admin.sock mode 660 level admin + stats timeout 30s + user haproxy + group haproxy + maxconn 2000 + ulimit-n 16384 + daemon + + # Default SSL material locations + ca-base /etc/ssl/certs + crt-base /etc/ssl/private + + # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate + ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 + ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets + +defaults + log global + mode http + option httplog + option dontlognull + timeout connect 5000 + timeout client 50000 + timeout server 50000 + timeout http-request 15s + timeout http-keep-alive 15s + errorfile 400 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http + +frontend monitor-in + bind *:33305 + mode http + option httplog + monitor-uri /monitor + +frontend k8s-master + bind 0.0.0.0:16443 + bind 127.0.0.1:16443 + mode tcp + option tcplog + tcp-request inspect-delay 5s + default_backend k8s-master + +backend k8s-master + mode tcp + option tcplog + option tcp-check + balance roundrobin + default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100 + {{nodes}} + +``` + +### keepalived.conf.tpl + +```bash +! Configuration File for keepalived + +global_defs { + router_id LVS_DEVEL #虚拟路由名称 + script_user root + enable_script_security +} + +# HAProxy健康检查配置 +vrrp_script chk_haproxy { + script "/usr/bin/killall -0 haproxy" + interval 5 # 脚本运行周期 + weight -5 # 每次检查的加权权重值 + fall 2 + rise 1 +} + +# 虚拟路由配置 +vrrp_instance VI_1 { + state BACKUP #本机实例状态,MASTER/BACKUP,备机配置文件中请写BACKUP + interface ens160 #本机网卡名称,使用ifconfig命令查看 + virtual_router_id 51 #虚拟路由编号,主备机保持一致 + priority 101 #本机初始权重,备机请填写小于主机的值(例如100) + advert_int 2 #争抢虚地址的周期,秒 + authentication { + auth_type PASS + auth_pass 123456 + } + virtual_ipaddress { + {{vip}}/24 # 虚地址IP,主备机保持一致 + } + track_script { + chk_haproxy # 对应的健康检查配置 + } +} +``` + +### kubeadm-config.yaml + +```bash +apiVersion: kubeadm.k8s.io/v1beta3 +bootstrapTokens: + - description: default kubeadm bootstrap token + groups: + - system:bootstrappers:kubeadm:default-node-token + token: n258e9.63nk1rcbcu6422c4 + ttl: 0s + usages: + - signing + - authentication +kind: InitConfiguration +localAPIEndpoint: + advertiseAddress: {{hostip}} + bindPort: 6443 +nodeRegistration: + criSocket: unix:///var/run/cri-dockerd.sock + imagePullPolicy: IfNotPresent + name: {{hostname}} + taints: + - effect: NoSchedule + key: node-role.kubernetes.io/master +--- +apiServer: + certSANs: + - {{vip}} + extraArgs: + default-watch-cache-size: "500" + max-mutating-requests-inflight: "500" + max-requests-inflight: "1000" + watch-cache-sizes: persistentvolumeclaims#1000,persistentvolumes#1000 + timeoutForControlPlane: 4m0s +apiVersion: kubeadm.k8s.io/v1beta3 +certificatesDir: /etc/kubernetes/pki +clusterName: kubernetes +controlPlaneEndpoint: {{vip}}:16443 +dns: {} +etcd: + local: + dataDir: /var/lib/etcd +imageRepository: registry.k8s.io +kind: ClusterConfiguration +kubernetesVersion: v1.29.2 +networking: + dnsDomain: cluster.local + podSubnet: 10.244.0.0/16 + serviceSubnet: 10.96.0.0/12 +scheduler: {} + +``` + +```bash +# 唯一参数,主机名称(必不可少) +bash install.sh +``` + +### install.sh + +```bash +#!/bin/bash + +set -e +hostname=$(hostname) +echo $hostname + +# 设置主机名 +echo "set host" +# sudo hostnamectl set-hostname "${hostname}" + +sudo cp hosts /etc/hosts + +# 配置SELINUX +echo "set selinux" +if type setenforce &>/dev/null; then + sudo setenforce 0 || : +fi + +if [ -f /etc/selinux/config ]; then + sudo sed -i 's/^SELINUX=enforcing$/SELINUX=disable/' /etc/selinux/config +fi + +# 禁用内存交换 +echo "set swap" +sudo swapoff -a +sudo sed -ir 's/^[^#].*swap.*/#&/' /etc/fstab + +# 关闭防火墙 +echo "set firewall" +if type ufw &>/dev/null; then + sudo ufw disable +else + sudo systemctl stop firewalld.service + sudo systemctl disable firewalld.service +fi + +# 开起网桥 +echo "set bridge" + +if [ ! -f /etc/sysctl.d/k8s.conf ]; then +cat <> auth +kubectl -n longhorn-system create secret generic basic-auth --from-file=auth + +``` + +## 安装 istio + +```bash +wget https://github.com/istio/istio/releases/download/1.21.1/istio-1.21.1-linux-amd64.tar.gz +tar -xzvf istio-1.20.3-linux-amd64.tar.gz +cd istio-1.20.3 +export PATH=$PWD/bin:$PATH +istioctl install -y # 安装 +kubectl label namespace default istio-injection=enabled # 开启自动代理 +# 添加网关资源 +kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0" | kubectl apply -f -; } + +``` diff --git a/source/_posts/tech/env/k8s_problems.md b/source/_posts/tech/env/k8s_problems.md new file mode 100644 index 00000000..8c116449 --- /dev/null +++ b/source/_posts/tech/env/k8s_problems.md @@ -0,0 +1,77 @@ +--- +title: k8s 问题集锦 +author: flytrap +categories: + - tech +tags: + - tech + - k8s + - problems +date: 2024-04-12 11:35:25 +--- + +收录一些 k8s 使用过程中遇到比较常见的问题,以及解决办法 + + + +## k8s 部分节点不调度 + +### 示例(集群安装完毕,主节点不调度) + +获取 node 状态,都是 ok 的 + +```bash +kubectl get nodes +NAME STATUS ROLES +master1 Ready control-plane +master2 Ready control-plane +master3 Ready control-plane +worker1 Ready +worker2 Ready +``` + +### 查看节点角色及是否支持 schedule, 此处以 master1 为例 + +```bash +kubectl describe nodes master1 |grep -E '(Roles|Taints)' +``` + +发现有 NoSchedule Taints +起始就是由于主节点被添加了污点(k8s 的默认行为),只需要移除污点既可解决调度问题 +node-role.kubernetes.io/master:NoSchedule +node-role.kubernetes.io/control-plane:NoSchedule + +### 移除污点 + +```bash +# 如果角色是master +kubectl taint nodes master1 node-role.kubernetes.io/master- +# 如果角色是control-plane +kubectl taint nodes master2 node-role.kubernetes.io/control-plane- +``` + +### 添加污点 + +```bash +kubectl taint nodes master1 node-role.kubernetes.io/master=:NoSchedule +# 或者 +kubectl taint nodes master2 node-role.kubernetes.io/control-plane=:NoSchedule +``` + +### 知识点(k8s 污点和容忍度) + +- 污点(Taints):定义在节点上,用于拒绝 Pod 调度到此节点,除非该 Pod 具有该节点上的污点容忍度。被标记有 Taints 的节点并不是故障节点。 +- 容忍度(Tolerations):定义在 Pod 上,用于配置 Pod 可容忍的节点污点,K8S 调度器只能将 Pod 调度到该 Pod 能够容忍的污点的节点上。 + +污点和容忍度(Toleration)相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod, 是不会被该节点接受的。 + +#### 排斥等级 + +- NoSchedule:没有配置此污点容忍度的新 Pod 不能调度到此节点,节点上现存的 Pod 不受影响。 +- PreferNoSchedule:没有配置此污点容忍度的新 Pod 尽量不要调度到此节点,如果找不到合适的节点,依然会调度到此节点。 +- NoExecute:没有配置此污点容忍度的新 Pod 对象不能调度到此节点,节点上现存的 Pod 会被驱逐。 + +#### 容忍度操作符 + +- Equal:容忍度与污点必须在 key、value 和 effect 三者完全匹配。 +- Exists:容忍度与污点必须在 key 和 effect 二者完全匹配,容忍度中的 value 字段要使用空值。 From eb1c8a226dcb3d8b06da2ffcdaf509156526d22d Mon Sep 17 00:00:00 2001 From: Gaohg Date: Fri, 19 Apr 2024 18:59:35 +0800 Subject: [PATCH 48/52] new: chrony --- source/_posts/tech/env/chrony.md | 134 +++++++++++++++++++++++++++++++ themes/yilia | 2 +- 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 source/_posts/tech/env/chrony.md diff --git a/source/_posts/tech/env/chrony.md b/source/_posts/tech/env/chrony.md new file mode 100644 index 00000000..766d6bf1 --- /dev/null +++ b/source/_posts/tech/env/chrony.md @@ -0,0 +1,134 @@ +--- +title: chrony 时间同步 +author: flytrap +categories: + - tech +tags: + - tech + - chrony + - ntp + - 时间同步 +date: 2024-04-17 10:04:28 +--- + +Chrony 是一个开源自由的网络时间协议 NTP 的客户端和服务器软软件。它能让计算机保持系统时钟与时钟服务器(NTP)同步,因此让你的计算机保持精确的时间,Chrony 也可以作为服务端软件为其他计算机提供时间同步服务。 + +Chrony 由两个程序组成,分别是 chronyd 和 chronyc + +chronyd 是一个后台运行的守护进程,用于调整内核中运行的系统时钟和时钟服务器同步。它确定计算机增减时间的比率,并对此进行补偿。 +chronyc 提供了一个用户界面,用于监控性能并进行多样化的配置。它可以在 chronyd 实例控制的计算机上工作,也可以在一台不同的远程计算机上工作。 + +NTP 是网络时间协议(Network Time Protocol)的简称,通过 udp 123 端口进行网络时钟同步。 +RHEL7 中默认使用 chrony 作为时间服务器,也支持 NTP,需要额外安装。 +NTP 与 chrony 不能同时存在,只能用其中一个,并将另一个 mask 掉。 + + + +## NTP 协议简介 + +- NTP(Network Time Protocol,网络时间协议) +- NTP 是用来使网络中的各个计算机时间同步的一种协议 +- 可以使用 nepdate 命令来向服务同步时间 + +## 安装 + +```bash +sudo apt install chrony -y # Ubuntu系列 +sudo yum install chrony -y # centos系列 +systemctl enable chronyd +systemctl start chronyd +``` + +## 服务器端 + +需要添加如下配置 + +```bash +local stratum 8 # 即使自己未能通过网络时间服务器同步到时间,也允许将本地时间作为标准时间授时给其它客户端 +manual +allow 192.168.0.0/16 # 允许使用的网段 + +timedatectl status # 查看事件同步状态 +timedatectl set-ntp true # 开启网络事件同步 + +# System clock synchronized: yes 开启同步 +# NTP service: active +``` + +### 监听的端口 + +- 123/udp:兼容 ntp 服务监听在 udp 的 123 端口上 +- 323/udp:chrony 服务本身监听在 udp 的 323 端口上 + +## 客户端 + +```bash +server local.ntp.server iburst +``` + +local.ntp.server 为服务器端地址 + +## 命令 + +### chronyc 命令 + +```bash +chronyc sources -v # 查看连接的时间服务器*是正常状态 +chronyc sourcestats -v # 查看当前时间同步是否正常 +chronyc tracking -v # 校准时间服务器 +chronyc activity -v # ntp servers 是否在线 +chronyc -a makestep # 强制同步系统时刻 +``` + +### timedatectl 命令 + +```bash +timedatectl list-timezones +timedatectl list-timezones | grep -E "Asia/S.*" # 查看时区 + +timedatectl set-timezone Asia/Shanghai # 修改为上海时区 +timedatectl set-ntp true/flase # 是否开启ntp +``` + +## chronyc sources 输出结果解析 + +### M + +这表示信号源的模式。^表示服务器,=表示对等方,#表示本地连接的参考时钟。 + +### S + +```bash +* 表示chronyd当前同步到的源。 ++ 表示可接受的信号源,与选定的信号源组合在一起。 +- 表示被合并算法排除的可接受源。 +? 指示已失去连接性或其数据包未通过所有测试的源。它也显示在启动时,直到从中至少收集了3个样本为止(临时状态)。 +x 表示chronyd认为是虚假行情的时钟(即,其时间与大多数其他来源不一致)。 +〜 表示时间似乎具有太多可变性的来源。 +``` + +### Name/IP address + +这显示了源的名称或 IP 地址,或参考时钟的参考 ID。 + +### Stratum + +这显示了来源的层,如其最近收到的样本中所报告的那样。层 1 表示一台具有本地连接的参考时钟的计算机。与第 1 层计算机同步的计算机位于第 2 层。与第 2 层计算机同步的计算机位于第 3 层,依此类推。 + +### Poll + +这显示轮询源的速率,以秒为单位的时间间隔的以 2 为底的对数。因此,值为 6 表示每 64 秒进行一次测量。**chronyd 会**根据当前情况自动**更改**轮询速率。 + +### Reach + +这显示了源的可达性寄存器以八进制数字打印。寄存器有 8 位,并在每个从源接收或丢失的数据包上更新。值 377 表示从最后八次传输中收到了对所有用户的有效答复。 + +### LastRx + +此列显示多长时间前从来源接收到了最后一个好的样本(在下一列中显示)。未通过某些测试的测量将被忽略。通常以秒为单位。字母*m*,_h_,*d*或*y*表示分钟,小时,天或年。 + +### Last sample + +此列显示上次测量时本地时钟与源之间的偏移。方括号中的数字表示实际测得的偏移量。可以用*ns*(表示纳秒),*us* (表示微秒),_ms_(表示毫秒)或*s*(表示秒)作为后缀。方括号左侧的数字表示原始测量值,已调整为允许此后施加于本地时钟的任何摆度。 + +*+/-*指示器后面的数字表示测量中的误差范围。正偏移表示本地时钟位于源时钟之前 diff --git a/themes/yilia b/themes/yilia index 4b889f5d..5cd9ba5a 160000 --- a/themes/yilia +++ b/themes/yilia @@ -1 +1 @@ -Subproject commit 4b889f5d00f3d8b74dfda3217179ad55b2e44a2b +Subproject commit 5cd9ba5a98fa4aad18a82e2344390dab1aae7685 From 4cbf13cc947e7a7b7cfa8941ec3b294511a9839d Mon Sep 17 00:00:00 2001 From: Gaohg Date: Fri, 10 May 2024 17:05:00 +0800 Subject: [PATCH 49/52] =?UTF-8?q?new:=20=E5=A2=9E=E5=8A=A0=20seafile=20?= =?UTF-8?q?=E5=92=8Cverdaccio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/tech/env/chrony.md | 2 + source/_posts/tech/env/k8s.md | 64 +++++++++++- source/_posts/tech/env/seafile.md | 155 ++++++++++++++++++++++++++++ source/_posts/tech/env/verdaccio.md | 140 +++++++++++++++++++++++++ 4 files changed, 358 insertions(+), 3 deletions(-) create mode 100644 source/_posts/tech/env/seafile.md create mode 100644 source/_posts/tech/env/verdaccio.md diff --git a/source/_posts/tech/env/chrony.md b/source/_posts/tech/env/chrony.md index 766d6bf1..edbfc99e 100644 --- a/source/_posts/tech/env/chrony.md +++ b/source/_posts/tech/env/chrony.md @@ -64,6 +64,8 @@ timedatectl set-ntp true # 开启网络事件同步 ```bash server local.ntp.server iburst + +allow 192.168.0.0/16 # 允许使用的网段 ``` local.ntp.server 为服务器端地址 diff --git a/source/_posts/tech/env/k8s.md b/source/_posts/tech/env/k8s.md index 74463cee..6a7ce63f 100644 --- a/source/_posts/tech/env/k8s.md +++ b/source/_posts/tech/env/k8s.md @@ -7,6 +7,7 @@ tags: - tech - k8s - kubernetes + - 集群 date: 2024-03-16 10:00:00 --- @@ -419,6 +420,16 @@ wget https://github.com/projectcalico/calico/blob/master/manifests/calico.yaml kubectl apply -f conf/calico.yaml ``` +## 安装集群指标插件 + +```bash +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +helm install kube-state-metrics prometheus-community/kube-state-metrics -n kube-system +kubectl top node # 测试命令,查看节点资源使用情况 +kubectl top pod # 查看pod资源使用情况 +``` + 到此为止,集群已经安装完成 ## 安装 dashboard @@ -462,7 +473,40 @@ subjects: namespace: kubernetes-dashboard ``` -## 安装 longhorn +## 安装 nfs(存储可选) + +### 安装服务端 + +```bash +# sudo apt install nfs-kernel-server ## 服务器端需要安装 +sudo mkdir -p /data/nfs +sudo chmod 777 /data/nfs +sudo chown lbjy:lbjy /data/nfs +sudo vim /etc/exports +# 添加配置 +# /data/nfs *(rw,sync,no_root_squash) +sudo systemctl restart nfs-kernel-server.service +``` + +## 安装 rook-ceph(分布式存储,可选) + +```bash +helm repo add lbjy http://192.168.1.143:8080 +helm repo add rook-release https://charts.rook.io/release +helm install --create-namespace --namespace rook-ceph rook-ceph rook-release/rook-ceph -f conf/rook-ceph.yaml + +helm install --create-namespace --namespace rook-ceph rook-ceph-cluster --set operatorNamespace=rook-ceph rook-release/rook-ceph-cluster -f conf/rook-ceph-cluster.yaml +# 获取密码 +kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo +# 测试工具 +kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash +ceph status +ceph osd status +ceph df +rados df +``` + +## 安装 longhorn(分布式存储,可选) ```bash sudo apt install nfs-common -y @@ -475,7 +519,9 @@ kubectl -n longhorn-system create secret generic basic-auth --from-file=auth ``` -## 安装 istio +## 安装 istio(网格,可选) + +网格服务,服务治理,好东西,推荐安装 ```bash wget https://github.com/istio/istio/releases/download/1.21.1/istio-1.21.1-linux-amd64.tar.gz @@ -484,7 +530,19 @@ cd istio-1.20.3 export PATH=$PWD/bin:$PATH istioctl install -y # 安装 kubectl label namespace default istio-injection=enabled # 开启自动代理 + +kubectl apply -f samples/addons -n istio-system # 部署loki, Kiali 仪表板、 以及 Prometheus、 Grafana、 还有 Jaeger插件 + +# 开启访问日志收集 +istioctl install -f samples/open-telemetry/loki/iop.yaml --skip-confirmation +kubectl apply -f samples/addons/loki.yaml -n istio-system +kubectl apply -f samples/open-telemetry/loki/otel.yaml -n istio-system + +# 开启容器日志收集 +helm repo add grafana https://grafana.github.io/helm-charts +helm install promtail grafana/promtail -n istio-system --set config.clients[0].url=http://loki-headless.istio-system/loki/api/v1/push + # 添加网关资源 -kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0" | kubectl apply -f -; } +# kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0" | kubectl apply -f -; } ``` diff --git a/source/_posts/tech/env/seafile.md b/source/_posts/tech/env/seafile.md new file mode 100644 index 00000000..b2799649 --- /dev/null +++ b/source/_posts/tech/env/seafile.md @@ -0,0 +1,155 @@ +--- +title: SeaFile 网盘 +author: flytrap +categories: + - tech +tags: + - tech + - SeaFile + - docker-compose + - 网盘 + - 私有网盘 +date: 2024-05-11 10:10:00 +--- + +Seafile 是一款开源的企业云盘,注重可靠性和性能,支持全平台客户端。Seafile 内置协同文档 SeaDoc ,让协作撰写、管理和发布文档更便捷。 +Seafile 提供全面的网盘功能,用户可以在 Seafile 中存储、管理和共享文件。支持多种文件类型。支持全平台客户端,包括 Windows、Mac、Linux、iOS、Android 多种操作系统以及移动设备,可以在任何设备上轻松访问和管理文件,体验更为统一。 +Seafile 的协作功能超越了简单的文件共享。它支持多人协同在线编辑、文档编辑锁定,同时提供权限管理、版本控制和事件通知等功能,使得团队协作更加流畅、可控和高效。 + +(官网)[https://www.seafile.com/] + + + +## 部署 + +建议使用 docker 容器化部署,此处给出常用 docker-compose 配置文件 + +```bash +version: '3.6' + +services: + db: + image: mariadb:10.11 + container_name: seafile-mysql + restart: unless-stopped + environment: + - MYSQL_ROOT_PASSWORD=password + - MYSQL_LOG_CONSOLE=true + volumes: + - ./data/db:/var/lib/mysql + ports: + - 3306:3306 + networks: + - seafile-net + logging: + options: + max-size: "10m" + max-file: "3" + + memcached: + image: memcached:1.6 + container_name: seafile-memcached + restart: unless-stopped + entrypoint: memcached -m 256 + networks: + - seafile-net + logging: + options: + max-size: "10m" + max-file: "3" + + seafile: + # image: seafileltd/seafile-mc:latest + image: seafileltd/seafile-mc:11.0.5 + container_name: seafile + privileged: true + restart: unless-stopped + ports: + - "80:80" + - "8000:8000" + volumes: + - ./data/seafile:/shared + environment: + - SEAFILE_ADMIN_PASSWORD=password@admin.com + - DB_HOST=db + - DB_ROOT_PASSWD=password + - SEAFILE_ADMIN_EMAIL=admin@admin.com + - SEAFILE_SERVER_HOSTNAME=ip + - SEAFILE_SERVER_LEFSENCRYPT=false + depends_on: + - memcached + - db + - sdoc-server + - onlyoffice-documentserver + networks: + - seafile-net + - ldap-net # Remove this network if LDAP is not used + logging: + options: + max-size: "10m" + max-file: "3" + + # Remove this section if you do not want to use only office integration + onlyoffice-documentserver: + image: onlyoffice/documentserver:8.0.1 + restart: unless-stopped + container_name: onlyoffice + privileged: true + environment: + - JWT_ENABLED=true + - JWT_SECRET=seafile + + ports: + - "8889:80" + volumes: + # Optional: see https://manual.seafile.com/deploy/only_office/ + - ./data/onlyoffice/log:/var/log/onlyoffice + - ./data/onlyoffice/data:/var/www/onlyoffice/Data + - ./data/onlyoffice/lib:/var/lib/onlyoffice + - ./data/onlyoffice/db:/var/lib/postgresql + # - ./data/onlyoffice/local.json:/etc/onlyoffice/documentserver/local.json + networks: + - seafile-net + # logging: + # options: + # max-size: "10m" + # max-file: "3" + sdoc-server: + image: seafileltd/sdoc-server:0.5.0 + container_name: sdoc-server + restart: unless-stopped + ports: + # - 8888:80 + # - 443:443 + - 7070:7070 + - 8888:8888 + volumes: + - ./data/seafile/sdoc-data/:/shared + networks: + - seafile-net + environment: + - DB_HOST=db + - DB_PORT=3306 + - DB_USER=root + - DB_PASSWD=password # Requested, password of MySQL service. + - DB_NAME=sdoc_db + - TIME_ZONE=Asia/Shanghai + - SDOC_SERVER_LETSENCRYPT=false # Whether to use https or not. + - SEAHUB_SERVICE_URL=http://ip + +networks: + seafile-net: + name: seafile-net + ipam: + driver: default + config: + - subnet: 172.31.0.0/16 + ldap-net: # Remove this network if LDAP is not used + external: true + name: ldap-net +``` + +## 使用 + +参考官方文档 +https://cloud.seafile.com/published/seafile-user-manual/ diff --git a/source/_posts/tech/env/verdaccio.md b/source/_posts/tech/env/verdaccio.md new file mode 100644 index 00000000..bb9b0aed --- /dev/null +++ b/source/_posts/tech/env/verdaccio.md @@ -0,0 +1,140 @@ +--- +title: verdaccio 前端私有源 +author: flytrap +categories: + - tech +tags: + - tech + - verdaccio + - docker-compose + - 前端私有源 +date: 2024-05-10 15:10:00 +--- + +我们平时使用 npm publish 进行发布时,上传的仓库默认地址是 npm,公司内部包的管理并不希望发布到公网去,所以需要发布到自己的私有仓库, 之前都是用的 cnpmjs, 由于没有维护了,太老了,所以改用 Verdaccio。 通过 Verdaccio 工具在本地新建一个仓库地址,再把本地的默认上传仓库地址切换到本地仓库地址即可。当 npm install 时没有找到本地的仓库,则 Verdaccio 默认配置中会从 npm 中央仓库下载。 + + + +## 部署 + +建议使用 docker 容器化部署,此处给出常用 docker-compose 配置文件 + +```bash +version: '3.1' + +services: + verdaccio: + image: verdaccio/verdaccio:5.29 + container_name: verdaccio + networks: + - node-network + environment: + - VERDACCIO_PORT=4873 + ports: + - '4873:4873' + volumes: + - './storage:/verdaccio/storage' + - './config:/verdaccio/conf' + - './plugins:/verdaccio/plugins' +networks: + node-network: + driver: bridge +``` + +- storage: 包存储路径 +- config: 配置文件路径 +- plugins: 插件路径 + +## 配置文件调整 + +config/config.yaml + +```bash +# https://verdaccio.org/docs/configuration#uplinks +# A list of other known repositories we can talk to +uplinks: + npmjs: + url: https://registry.npmjs.org/ + yarn: + url: https://registry.yarnpkg.com/ + taobao: + url: https://registry.npmmirror.com/ + +# Learn how to protect your packages +# https://verdaccio.org/docs/protect-your-dependencies/ +# https://verdaccio.org/docs/configuration#packages +packages: + '@*/*': + # scoped packages + access: $all + publish: $authenticated + unpublish: $authenticated + proxy: taobao + + '**': + # Allow all users (including non-authenticated users) to read and + # publish all packages + # + # You can specify usernames/groupnames (depending on your auth plugin) + # and three keywords: "$all", "$anonymous", "$authenticated" + access: $all + + # Allow all known users to publish/unpublish packages + # (anyone can register by default, remember?) + publish: $authenticated + unpublish: $authenticated + + # if package is not available locally, proxy requests to 'npmjs' registry + proxy: taobao +# To improve your security configuration and avoid dependency confusion +# consider removing the proxy property for private packages +# https://verdaccio.org/docs/best#remove-proxy-to-increase-security-at-private-packages + +# https://verdaccio.org/docs/configuration#server +# You can specify the HTTP/1.1 server keep alive timeout in seconds for incoming connections. +# A value of 0 makes the http server behave similarly to Node.js versions prior to 8.0.0, which did not have a +# keep-alive timeout. +# WORKAROUND: Through given configuration you can work around the following issue: +# https://github.com/verdaccio/verdaccio/issues/301. Set to 0 in case 60 is not enough. +server: + keepAliveTimeout: 60 + # The pluginPrefix replaces the default plugins prefix which is `verdaccio`, please don't include `-`. If `something` is provided + # the resolve package will be `something-xxxx`. + # pluginPrefix: something + # A regex for the password validation /.{3}$/ (3 characters min) + # An example to limit to 10 characters minimum + # passwordValidationRegex: /.{10}$/ + # Allow `req.ip` to resolve properly when Verdaccio is behind a proxy or load-balancer + # See: https://expressjs.com/en/guide/behind-proxies.html + # trustProxy: '127.0.0.1' + +# https://verdaccio.org/docs/configuration#offline-publish +publish: + allow_offline: true +``` + +贴出部分配置文件,需要注意的地方有两个 + +1. 上游源, 我这里添加了一个淘宝源,并指定 npm 代理到淘宝源 +2. 发布配置 allow_offline: 允许离线发布, 否则发布会向上游同步 + +## 使用私有源 + +```bash +npm install -g nrm --registry http://ip:4873 # 安装nrm +nrm add local http://ip:4873 # 添加本地的npm镜像地址 +nrm use local # 使用本地npm地址 + +# npm set registry http://localhost:4873/ +npm i test +``` + +## 发布 + +```bash +npm adduser # 添加用户 +npm login --registry http://ip:4873 # 登录 +npm publish --registry http://ip:4873/ +``` + +浏览器访问: http://ip:4873/ 就可以看到我们发布上去的包了 From c9affa210ef58bccebd87d125c5e59bf66672394 Mon Sep 17 00:00:00 2001 From: Gaohg Date: Tue, 14 May 2024 16:49:29 +0800 Subject: [PATCH 50/52] =?UTF-8?q?new:=20=E5=A2=9E=E5=8A=A0dns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _config.yml | 2 +- source/_posts/tech/env/chrony.md | 1 + source/_posts/tech/env/dns.md | 89 ++++++++++++++++++++++++++ source/_posts/tech/env/golang_repo.md | 20 ++++++ source/_posts/tech/env/k8s_problems.md | 5 ++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 source/_posts/tech/env/dns.md create mode 100644 source/_posts/tech/env/golang_repo.md diff --git a/_config.yml b/_config.yml index 863de439..86b6a497 100644 --- a/_config.yml +++ b/_config.yml @@ -88,7 +88,7 @@ theme: yilia deploy: type: git repository: git@github.com:flytrap/flytrap.github.io.git - branch: master + branch: main jsonContent: diff --git a/source/_posts/tech/env/chrony.md b/source/_posts/tech/env/chrony.md index edbfc99e..c296edf7 100644 --- a/source/_posts/tech/env/chrony.md +++ b/source/_posts/tech/env/chrony.md @@ -79,6 +79,7 @@ chronyc sources -v # 查看连接的时间服务器*是正常状态 chronyc sourcestats -v # 查看当前时间同步是否正常 chronyc tracking -v # 校准时间服务器 chronyc activity -v # ntp servers 是否在线 +chronyc accheck ip # 检测dns服务是否可用 chronyc -a makestep # 强制同步系统时刻 ``` diff --git a/source/_posts/tech/env/dns.md b/source/_posts/tech/env/dns.md new file mode 100644 index 00000000..241794da --- /dev/null +++ b/source/_posts/tech/env/dns.md @@ -0,0 +1,89 @@ +--- +title: dns 私有服务器 +author: flytrap +categories: + - tech +tags: + - tech + - dns + - 域名解析 + - docker-compose +date: 2024-05-13 14:00:01 +--- + +DNS 服务器是(Domain Name System 或者 Domain Name Service)域名系统或者域名服务,域名系统为 Internet 上的主机分配域名地址和 IP 地址。 +公司内部通过域名访问内部服务器,但是域名解析又无法访问到内网, 所以内部 dns 解析服务是最好的解决方案 + + + +## 部署 + +建议使用 docker 容器化部署,此处给出常用 docker-compose 配置文件 + +```bash +version: '3' + +services: + bind: + container_name: dns + restart: always + image: sameersbn/bind:9.16.1-20200524 + ports: + - "53:53/udp" # 绑定容器53端口到宿主机的53端口,DNS默认端口 + - "53:53/tcp" + - "10000:10000/tcp" # 图形化界面管理器端口; + volumes: + - ./bind:/data # 挂载本地目录作为dns配置存储 +``` + +```bash +lsof -i:53 # 确认端口占用 +``` + +## ubuntu 端口占用 + +```bash +sudo systemctl stop systemd-resolved +sudo systemctl disable systemd-resolved +vim /etc/resolv.conf # 只保留nameserver 一行, 改为127.0.0.1即可 +``` + +## 管理 + +访问地址: https://localhost:10000 +使用 https 访问哦 +默认账户和密码 root/password, 进去可以修改 + +## 调整默认配置 + +菜单路径如下 + +```bash +Servers -> BINBIND DNS Server -> Zone Defaults +``` + +找到: Default zone settings + +Allow transfers from: 输入框添加 any, 选项改为 Listed.. +Allow queries from: 输入框添加 any, 选项改为 Listed.. + +保存重启, 不改无法查询公网解析 + +## 添加自己的正向解析 + +菜单路径如下 + +```bash +Servers -> BINBIND DNS Server -> Create Master Zone +``` + +- Domain name: 写你的名字 +- Master server: localhost +- Email address: 看这写 + +其他默认就好了 + +返回后 Existing DNS Zones 中选择你刚才添加的名字, 进去选择 Address +输入 Name: 域名, Address: ip , 点击 Create 就可以了 + +完了记得重启哦 diff --git a/source/_posts/tech/env/golang_repo.md b/source/_posts/tech/env/golang_repo.md new file mode 100644 index 00000000..dc47ea47 --- /dev/null +++ b/source/_posts/tech/env/golang_repo.md @@ -0,0 +1,20 @@ +--- +title: golang 私有包 +author: flytrap +categories: + - tech +tags: + - tech + - golang + - 私有源 + - gitlab + - mod +date: 2024-05-10 15:10:00 +--- + +```bash +RUN go env -w GOPRIVATE="gitlabIp" +RUN go env -w GONOPROXY="gitlabIp" +RUN go env -w GOINSECURE="gitlabIp" +RUN go env -w GONOSUMDB="gitlabIp" +``` diff --git a/source/_posts/tech/env/k8s_problems.md b/source/_posts/tech/env/k8s_problems.md index 8c116449..a7622677 100644 --- a/source/_posts/tech/env/k8s_problems.md +++ b/source/_posts/tech/env/k8s_problems.md @@ -75,3 +75,8 @@ kubectl taint nodes master2 node-role.kubernetes.io/control-plane=:NoSchedule - Equal:容忍度与污点必须在 key、value 和 effect 三者完全匹配。 - Exists:容忍度与污点必须在 key 和 effect 二者完全匹配,容忍度中的 value 字段要使用空值。 + +## k8s 时间同步集群故障 + +重启 kube-system 命名空间下的服务 +然后重启对应服务 From bf67d1101e04f0449a01c0e7ae2d942e1df04263 Mon Sep 17 00:00:00 2001 From: Gaohg Date: Wed, 29 May 2024 16:40:56 +0800 Subject: [PATCH 51/52] =?UTF-8?q?new:=20=E5=A2=9E=E5=8A=A0=E9=9B=86?= =?UTF-8?q?=E7=BE=A4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/tech/env/istio.md | 69 +++++++++++ source/_posts/tech/env/k8s.md | 6 + source/_posts/tech/env/k8s_join.md | 79 +++++++++++++ source/_posts/tech/env/k8s_problems.md | 158 +++++++++++++++++++++++++ 4 files changed, 312 insertions(+) create mode 100644 source/_posts/tech/env/istio.md create mode 100644 source/_posts/tech/env/k8s_join.md diff --git a/source/_posts/tech/env/istio.md b/source/_posts/tech/env/istio.md new file mode 100644 index 00000000..d178f000 --- /dev/null +++ b/source/_posts/tech/env/istio.md @@ -0,0 +1,69 @@ +--- +title: istio 配置 +author: flytrap +categories: + - tech +tags: + - tech + - k8s + - kubernetes + - istio + - kubeadm +date: 2024-05-29 16:01:05 +--- + +Istio 服务网格 +Istio 使用功能强大的 Envoy 服务代理扩展了 Kubernetes,以建立一个可编程的、可感知的应用程序网络。 Istio 与 Kubernetes 和传统工作负载一起使用,为复杂的部署带来了标准的通用流量管理、遥测和安全性。 + +## 安装 + +```bash +curl -L https://istio.io/downloadIstio | sh - +``` + +## 真实 ip 转发 + +### 生成环境不建议 + +```bash +kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec":{"externalTrafficPolicy":"Local"}}' +``` + +### HTTP/HTTPS 负载均衡 + +```bash +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +spec: + meshConfig: + defaultConfig: + gatewayTopology: + numTrustedProxies: 2 +``` + +通过负载均衡器, 添加 ip 转发头 +以 nginx 为例 + +```bash +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80 default_server; + listen [::]:80 default_server; + + server_name _; + + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://192.168.3.161; + } +} +``` diff --git a/source/_posts/tech/env/k8s.md b/source/_posts/tech/env/k8s.md index 6a7ce63f..a126a381 100644 --- a/source/_posts/tech/env/k8s.md +++ b/source/_posts/tech/env/k8s.md @@ -6,6 +6,7 @@ categories: tags: - tech - k8s + - kubeadm - kubernetes - 集群 date: 2024-03-16 10:00:00 @@ -524,6 +525,11 @@ kubectl -n longhorn-system create secret generic basic-auth --from-file=auth 网格服务,服务治理,好东西,推荐安装 ```bash +## 增强指标 +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +helm install kube-state-metrics prometheus-community/kube-state-metrics -n kube-system + wget https://github.com/istio/istio/releases/download/1.21.1/istio-1.21.1-linux-amd64.tar.gz tar -xzvf istio-1.20.3-linux-amd64.tar.gz cd istio-1.20.3 diff --git a/source/_posts/tech/env/k8s_join.md b/source/_posts/tech/env/k8s_join.md new file mode 100644 index 00000000..45005bd3 --- /dev/null +++ b/source/_posts/tech/env/k8s_join.md @@ -0,0 +1,79 @@ +--- +title: k8s 节点控制 +author: flytrap +categories: + - tech +tags: + - tech + - k8s + - kubernetes + - join + - kubeadm +date: 2024-05-29 15:35:20 +--- + +在 Kubernetes 中,节点分为两种, 一种是普通节点,一种是控制平面(control-plane)节点 + +- 控制平面组件包括 kube-apiserver、kube-controller-manager、kube-scheduler、etcd,是由来支撑平台运行的组件,在集群部署完成时即运行在所有的控制节点上。 +- node 节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境, + +## etcd + +- etcd 是兼具一致性和高可用性的键值数据库,是用来保存 Kubernetes 所有集群数据的后台数据库。在生产环境中,为了保证高可用性,一般将 etcd 部署在多个节点上组成集群。 + +## kube-apiserver + +- apiserver 是控制面的前端,对所有资源的操作都要经过 apiserver,apiserver 是无状态的,可以横型扩展,用 Haproxy 或者负载均衡器让多个 apiserver 协同工作。 + +## kube-scheduler + +- scheduler 负责监视新创建的、未指定运行节点(node)的 Pods,选择节点让 Pod 在上面运行。调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限。 + +## kube-controller-manager + +- controller-manager 是一系列控制器的集合,这些控制器在逻辑上属于不同的进程,但为了降低复杂性将这些控制器编译在了同一个可执行文件中,控制器包括: + +* 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应 +* 任务控制器(Job controller): 监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成 +* 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod) +* 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌 +* 以及其他比如 Pod 管理的 Replication 控制器、Deployment 控制器等数十种类型 API 对象的控制器。 + +## kube-proxy + +- kube-proxy 是集群中每个节点上运行的网络代理, 是实现 Kubernetes 服务(Service) 概念的一部分。 +- kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。 +- kube-proxy 有两种模式实现流量转发,分别是 iptables 模式和 ipvs(IP Virtual Server)模式,默认是 iptables 模式,是通过每个节点的 iptables 规则实现的,但随着 service 数量增大,iptables 模式由于线性查找匹配、全量更新等特点,性能会显著下降,因此从 Kubernetes 的 1.8 版本开始引入了 ipvs 模式,ipvs 和 iptables 都是基于 netfilter,但 ipvs 使用 hash 表并且运行在内核态,可以显著提升性能。 + +## kubelet + +- kubelet 是一个在集群中每个节点(node)上运行的代理,负责接收并处理控制节点发来的指令,以及管理当前 node 上 pod 对象的容器,它保证容器(containers)都 运行在 Pod 中。 +- kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。 +- kubelet 不会管理不是由 Kubernetes 创建的容器。 +- kubelet 支持从 API server 以配置清单形式接收资源定义,或者从指定的目录加载静态 pod 配置清单,通过容器运行时创建、启动和监事容器。 + +## 普通节点加入 + +```bash +kubeadm join : --token --discovery-token-ca-cert-hash sha256: +``` + +## 控制平面节点加入 + +```bash +kubeadm join : --token --discovery-token-ca-cert-hash sha256: --control-plane --certificate-key +``` + +## 获取 token + +```bash +kubeadm token list +## 获取hash +openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' + +## 生成新的证书 +kubeadm init phase upload-certs --upload-certs + +# 完整命令打印 +sudo kubeadm token create --print-join-command --certificate-key $(kubeadm certs certificate-key) # 如果无效,请使用上述命令重新上传证书 +``` diff --git a/source/_posts/tech/env/k8s_problems.md b/source/_posts/tech/env/k8s_problems.md index a7622677..c5496276 100644 --- a/source/_posts/tech/env/k8s_problems.md +++ b/source/_posts/tech/env/k8s_problems.md @@ -6,6 +6,8 @@ categories: tags: - tech - k8s + - kubernetes + - kubeadm - problems date: 2024-04-12 11:35:25 --- @@ -58,6 +60,23 @@ kubectl taint nodes master1 node-role.kubernetes.io/master=:NoSchedule kubectl taint nodes master2 node-role.kubernetes.io/control-plane=:NoSchedule ``` +### cordon 停止调度(不可调度,临时从 K8S 集群隔离) + +- 影响最小,只会将 node 标识为 SchedulingDisabled 不可调度状态。 +- 之后 K8S 再创建的 pod 资源,不会被调度到该节点。 +- 旧有的 pod 不会受到影响,仍正常对外提供服务。 +- 禁止调度命令"kubectl cordon node_name"。 +- 恢复调度命令"kubectl uncordon node_name"。(恢复到 K8S 集群中,变回可调度状态) + +### drain 驱逐节点(先不可调度,然后排干) + +- 首先,驱逐 Node 上的 pod 资源到其他节点重新创建。 +- 接着,将节点调为 SchedulingDisabled 不可调度状态。 +- 禁止调度命令"kubectl drain node_name --force --ignore-daemonsets --delete-local-data" +- 恢复调度命令"kubectl uncordon node_name"。(恢复到 K8S 集群中,变回可调度状态) +- drain 方式是安全驱逐 pod,会等到 pod 容器应用程序优雅停止后再删除该 pod。 +- drain 驱逐流程:先在 Node 节点删除 pod,然后再在其他 Node 节点创建该 pod。所以为了确保 drain 驱逐 pod 过程中不中断服务(即做到"无感知"地平滑驱逐),必须保证要驱逐的 pod 副本数大于 1,并且采用了"反亲和策略"将这些 pod 调度到不同的 Node 节点上了!也就是说,在"多个 pod 副本+反亲和策略"的场景下,drain 驱逐过程对容器服务是没有影响的。 + ### 知识点(k8s 污点和容忍度) - 污点(Taints):定义在节点上,用于拒绝 Pod 调度到此节点,除非该 Pod 具有该节点上的污点容忍度。被标记有 Taints 的节点并不是故障节点。 @@ -80,3 +99,142 @@ kubectl taint nodes master2 node-role.kubernetes.io/control-plane=:NoSchedule 重启 kube-system 命名空间下的服务 然后重启对应服务 + +## kubeadm 加入 master 节点失败 + +报错: error execution phase check-etcd: etcd cluster is not healthy: context deadli + +原因分析: + +- 由于该节点已经存在所以无法加入 + +起因: + +- master2 挂掉了,其他节点无法连接该节点 +- 尝试通过移除节点,并重新引导节点加入集群的方式去解决 + +master1 执行 + +```bash +kubectl delete node master2 # master1 上执行的 + +### master2上执行 +kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock +kubeadm join 192.168.1.101:6443 --token n258e9.63nk1rcbcu6422c4 --discovery-token-ca-cert-hash sha256:4916a116d04b8ac46228bae887445bbe087cac4e8096fc489fe2fc6a6060708e --control-plane --certificate-key b5e26ce8cdfa2d92412766d4cd22be7a56283a7ab3c35fca902db37c777dc0ad --cri-socket=unix:///var/run/cri-dockerd.sock +# -->: +# [check-etcd] Checking that the etcd cluster is healthy +# error execution phase check-etcd: etcd cluster is not healthy: failed to dial endpoint https://192.168.3.102:2379 with maintenance client: context deadline exceeded +# To see the stack trace of this error execute with --v=5 or higher +``` + +```bash +kubectl get pod -n kube-system + +kubectl exec -ti etcd-master1 -n kube-system sh +# k8s中etcd使用的是v3的api, 所以要先声明变量 +export ETCDCTL_API=3 +# 执行命令,查看当前的etcd节点数量 +etcdctl --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" member list +# -->: +# 8a67dbc3f58dcef3, started, master3, https://192.168.3.103:2380, https://192.168.3.103:2379, false +# ad8e97d25b4a7a33, started, master1, https://192.168.3.101:2380, https://192.168.3.101:2379, false +# c3d762ff5eaee998, started, master2, https://192.168.3.102:2380, https://192.168.3.102:2379, false +``` + +发现 master2 节点已经存在 + +解决: + +```bash +etcdctl --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" member remove c3d762ff5eaee998 +``` + +## kubernetes 中 hpa 没生效问题 + +hpa 就是 Horizontal Pod Autoscaler 的缩写,水平 pod 自动扩容器。也就是可以根据 cpu 和内存指标等,自动扩缩容。 + +### 确认一下问题 + +```bash +kubectl get hpa -n istio-system # 查询hpa情况 +# --->: +# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE +# istio-ingressgateway Deployment/istio-ingressgateway /80% 1 5 1 35d +# istiod Deployment/istiod /80% 1 5 1 35d + +kubectl describe hpa/istio-ingressgateway -n istio-system + +# 看到如下警告事件, 起始就是无法获取到当前资源使用情况 +# unable to get metrics for resource cpu: unable to fetch metrics from resource metrics API: the server could not find the requested resource (get pods.metrics.k8s.io) +``` + +### 解决方法 + +```bash +wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml +``` + +### 在 kind: Deployment 中的 启动命令中添加一行(- --kubelet-insecure-tls) + +就像这样 + +```bash + spec: + containers: + - args: + - --cert-dir=/tmp + - --secure-port=10250 + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + - --kubelet-insecure-tls +``` + +```bash +kubectl apply -f components.yaml +``` + +### 现在再看 + +```bash +kubectl get hpa -n istio-system +# --->: +# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE +# istio-ingressgateway Deployment/istio-ingressgateway 4%/80% 1 5 1 35d +# istiod Deployment/istiod 0%/80% 1 5 1 35d +``` + +## 集群中获取真实 ip + +通过负载均衡器, 添加 ip 转发头 +以 nginx 为例 + +```bash +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80 default_server; + listen [::]:80 default_server; + + server_name _; + + location / { + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_pass http://192.168.3.161; + } +} +``` + +## 关于节点挂掉 + +原因分析: + +- 节点通信,证书同步错误,导致节点失联 From 4cc34cc2503cb0984ee20d4fba709650c6d51253 Mon Sep 17 00:00:00 2001 From: Gaohg Date: Fri, 25 Apr 2025 16:09:39 +0800 Subject: [PATCH 52/52] =?UTF-8?q?new:=20=E5=A2=9E=E5=8A=A0awk=E5=91=BD?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/tech/linux/awk.md | 119 ++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 source/_posts/tech/linux/awk.md diff --git a/source/_posts/tech/linux/awk.md b/source/_posts/tech/linux/awk.md new file mode 100644 index 00000000..43c4bbca --- /dev/null +++ b/source/_posts/tech/linux/awk.md @@ -0,0 +1,119 @@ +--- +title: awk常用命令及功能 +author: flytrap +categories: + - linux +tags: + - linux + - awk + - 字符串 + - 命令行 +date: 2025-05-25 16:08:22 +--- + +AWK 是一种强大的文本处理工具,常用在 Unix/Linux 环境中处理和分析结构化数据。以下是 AWK 的常用命令和功能,简要总结: + +### 基本语法 +```bash +awk [选项] '模式 {动作}' 文件 +``` +- **模式**:指定匹配条件(如正则表达式或逻辑条件)。 +- **动作**:对匹配的行执行的操作(如打印、计算)。 +- **文件**:输入文件,若无文件,可从标准输入读取。 + +### 常用选项 +- `-F`:指定字段分隔符(默认是空格或制表符)。 + ```bash + awk -F: '{print $1}' /etc/passwd # 以冒号分隔,打印第一列 + ``` +- `-v`:定义变量。 + ```bash + awk -v var=5 '{print $1 * var}' file.txt # 使用变量 var + ``` + +### 常用内置变量 +- `FS`:输入字段分隔符(默认空格)。 +- `OFS`:输出字段分隔符(默认空格)。 +- `NR`:当前处理的记录(行)号。 +- `NF`:当前行的字段数。 +- `$0`:整行内容。 +- `$n`:第 n 个字段(从 1 开始)。 + +### 常用命令和模式 +1. **打印整行或特定字段** + ```bash + awk '{print $0}' file.txt # 打印整行 + awk '{print $1, $3}' file.txt # 打印第 1 和第 3 字段 + ``` + +2. **条件匹配** + ```bash + awk '/pattern/ {print $0}' file.txt # 打印包含 pattern 的行 + awk '$1 == "value" {print $2}' file.txt # 第一字段为 value 时打印第二字段 + ``` + +3. **指定行号** + ```bash + awk 'NR==5 {print $0}' file.txt # 打印第 5 行 + awk 'NR>=2 && NR<=5 {print $0}' file.txt # 打印第 2 到第 5 行 + ``` + +4. **统计行数或字段** + ```bash + awk 'END {print NR}' file.txt # 统计总行数 + awk '{print NF}' file.txt # 每行字段数 + ``` + +5. **计算(求和、平均值等)** + ```bash + awk '{sum += $1} END {print sum}' file.txt # 计算第一列总和 + awk '{sum += $1; count++} END {print sum/count}' file.txt # 计算第一列平均值 + ``` + +6. **格式化输出** + ```bash + awk '{printf "%-10s %s\n", $1, $2}' file.txt # 格式化输出第 1、2 字段 + ``` + +7. **处理多文件** + ```bash + awk '{print FILENAME, $0}' file1.txt file2.txt # 打印文件名和内容 + ``` + +8. **BEGIN 和 END 块** + - `BEGIN`:在处理文件前执行。 + - `END`:在处理文件后执行。 + ```bash + awk 'BEGIN {print "Start"} {print $1} END {print "End"}' file.txt + ``` + +### 常用示例 +1. **提取日志中特定列** + ```bash + awk -F' ' '{print $1, $3}' access.log # 提取日志第 1 和第 3 列 + ``` + +2. **统计文件中某值出现次数** + ```bash + awk '$1 == "error" {count++} END {print count}' log.txt # 统计 error 出现次数 + ``` + +3. **替换字段** + ```bash + awk '{sub("old", "new", $1); print $0}' file.txt # 将第一字段中的 old 替换为 new + ``` + +4. **处理 CSV 文件** + ```bash + awk -F',' '{print $1, $2}' data.csv # 处理逗号分隔的 CSV 文件 + ``` + +### 注意事项 +- AWK 脚本可以保存为文件,使用 `-f` 选项调用: + ```bash + awk -f script.awk file.txt + ``` +- AWK 支持正则表达式、循环、条件语句,适合复杂数据处理。 +- 对于大数据量,AWK 比 sed 或 grep 更高效,尤其在字段操作上。 + +如果需要更详细的 AWK 教程或特定用例,请告诉我!