2017年12月23日星期六

SSH无法连接:Too many authentication failures

问题

今天使用ssh连接另外一台主机,提示以下错误
$ ssh serverusername@xxx.xxx.xxx
Received disconnect from xxx.xxx.xxx.xxx port 22:2: Too many authentication failures for user
Disconnected from xxx.xxx.xxx.xxx port 22

分析

使用-v选项来查看ssh登录时的详细输出信息:
$ ssh -v serverusername@xxx.xxx.xxx.xxx
...
debug1: Authenticating to xxx.xxx.xxx.xxx:22 as 'serverusername'
...
debug1: Found key in /Users/username/.ssh/known_hosts:16
....
debug1: Offering public key: RSA SHA256:xxx /Users/username/.ssh/a_id_rsa
...
debug1: Offering public key: RSA SHA256:xxx /Users/username/.ssh/b_id_rsa
...
debug1: Offering public key: RSA SHA256:xxx /Users/username/.ssh/id_rsa
...
debug1: Trying private key: /Users/username/.ssh/id_dsa
debug1: Offering public key: ECDSA SHA256:xxx /Users/username/.ssh/id_ecdsa
Received disconnect from xxx.xxx.xxx.xxx port 22:2: Too many authentication failures
Disconnected from xxx.xxx.xxx.xxx port 22
由上面的详细输出,即可分析连接失败的原因,是由于本地有多个ssh key导致的问题。
我们知道,使用ssh连接服务器时,会自动用本地~/.ssh目录下的ssh key文件进行登录授权校验。服务端在收到客户端过多的ssh key校验请求时,就会拒绝客户端的连接,并报错:Too many authentication failures

解决

指定ssh key文件

在连接服务器时,如果需要使用指定的ssh key文件,需要排除不相干的ssh key文件的干扰。

命令行参数方式

可以使用命令行参数指定ssh key文件:
$ ssh -i some_id_rsa -o 'IdentitieseOnly yes' serverusername@xxx.xxx.xxx
或者:
$ ssh -i some_id_rsa -o IdentitiesOnly=yes serverusername@xxx.xxx.xxx

配置文件方式

可以在ssh配置文件~/.ssh/config中针对服务器地址进行配置。如果文件不存在,创建空配置文件。
针对服务器地址,增加配置或修改现有配置为:
Host xxx.xxx.xxx.xxx
  IdentityFile ~/.ssh/key_for_somehost_rsa
  IdentitiesOnly yes
  Port 22

密码登录

如果需要采用密码登录方式,可以选择不使用ssh key来进行登录校验

命令行参数方式

$ ssh -o 'PubkeyAuthentication no' serverusername@xxx.xxx.xxx
或:
$ ssh -o PubkeyAuthentication=no serverusername@xxx.xxx.xxx

配置文件方式

增加配置或修改现有配置如下:
Host xxx.xxx.xxx.xxx
  PubkeyAuthentication no
  Port 22

参看

2017年12月14日星期四

安装 Ruby

常见的Ruby版本管理工具有rbenvRVM等,这里介绍在macOsUbuntu 16.04LTS中使用轻量的rbenv来安装Ruby的方法。

安装rbenv

Github checkout方式

安装rbenv

采用Github上将rbenv checkout 到本地的方式,这样就不需要系统范围的安装,而且能够及时获取最新版本:

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv && src/configure && make -C src

添加脚本配置:

$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

重新打开终端窗口使配置生效,或者运行以下命令:

$ . ~/.bash_profile

更新rbenv

$ cd `rbenv root`
$ git pull

安装ruby-build

$ mkdir -p `rbenv root`/plugins
$ git clone https://github.com/rbenv/ruby-build.git `rbenv root`/plugins/ruby-build

更新ruby-build

$ cd `rbenv root`/plugins/ruby-build
$ git pull

关闭rbenv

若要关闭rbenv,使其对Ruby的版本管理失效,只需要将~/.bash_profile(macOs)或~/.bashrc(Ubuntu)文件中加入的rbenv init行删除,然后重启shell即可。

卸载

  1. 删除~/.bashrc中添加的配置行

  2. 删除rbenv安装目录:

    $ rm -rf rbenv root

注意:以上设置,在Ubuntu中将~/.bash_profile替换为~/.bashrc,如果使用zsh,替换为~/.zshrc

macOS Homebrew

安装rbenvruby-build

macOS中使用Homebrew安装rbenv

$ brew install rbenv ruby-build

rbenv安装时会自动安装其依赖的ruby-build

添加脚本配置:

$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

重新打开终端窗口使配置生效,或者运行以下命令:

$ . ~/.bash_profile

更新rbenv

$ brew update && brew upgrade rbenv ruby-build

卸载

$ brew uninstall rbenv
$ brew uninstall ruby-build

Ubuntu apt安装

$ sudo apt install rbenv

添加脚本配置:

$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc

重新打开终端窗口使配置生效,或者运行以下命令:

$ . ~/.bashrc

安装Ruby

查看可安装的版本列表:

$ rbenv install -l
Available versions:
  1.8.5-p52
  1.8.5-p113
  1.8.5-p114
  ...
  3.1.2
  ...

当前最新版本为3.1.2

安装:

$ rbenv install 3.1.2

查看当前Ruby版本:

$ rbenv version
3.1.2 (set by /Users/user/.rbenv/version)

查看本地安装所有Ruby版本:

$ rbenv versions
  system
* 3.1.2 (set by /Users/user/.rbenv/version)

切换版本

安装多个版本Ruby时,可以自如的切换需要使用的版本。rbenv中有三个不同的作用域:

  • 全局(global)
  • 本地(local)
  • 当前终端(shell)

多个作用域同时设置时,查找版本的优先级为:shell > local > global

全局设置

全局作用域设置后针对全局,没有设置本地或终端作用域的Ruby版本时,全局设置将会生效:

$ rbenv global 3.1.2

本地设置

本地作用域主要针对各个不同的项目,在项目根目录设置本地作用域时,会通过在项目根目录下生成的.rbenv-version文件来管理Ruby版本:

$ rbenv local 3.1.2

这样对Ruby版本的设置就只有在这个项目中才生效

当前终端设置

当前终端设置只针对当前终端,退出当前终端或打开新的终端时就会失效:

$ rbenv shell 3.1.2

取消设置

$ rbenv global --unset
$ rbenv local --unset
$ rbenv shell --unset

使用系统Ruby

如果通过其他方式安装了Ruby且设置了环境变量,我们可以通过以下命令使得系统Ruby生效:

$ rbenv global system

卸载Ruby

使用如下命令查看当前版本Ruby安装目录:

$ rbenv prefix

超找指定版本Ruby安装目录:

$ rbenv prefix 3.1.2

删除使用rbenv安装的Ruby,可以直接删除Ruby安装目录:

$ rm -rf `rbenv prefix 3.1.2`

还可以使用命令:

$ rbenv uninstall 3.1.2

参看

rbenv

rbenv-install-and-using

How To Install Ruby on Rails with rbenv on Ubuntu 16.04

ruby-build

bundler vs RVM vs gems vs RubyGems vs gemsets vs system ruby

2017年6月29日星期四

Git分支管理策略 -- Git-Flow

Git-Flow是2010年Vincent Driessen在他的博客中提出的一个git分支模型,是最流行的分支模型。

分支类型

Git-Flow包含了两大类共五小类分支类型,下面我们一一介绍:
  1. 主分支(main branches)
    1. master
    2. develop
  2. 辅助分支(supporting branches)
    1. Feature branches
    2. Release branches
    3. Hotfix branches

主分支

主分支包括masterdevelop分支,这两个分支作为主分支,始终存在于远程仓库中。

master分支

master分支是git仓库创建后自动创建的分支。最终测试通过的正式版本都是在这个分支上发布的。

develop分支

develop分支最初由master分支分出来,这个分支用来反映下一个发布状态的最新代码。我们在发布下一个版本时,首先要将功能分支开发完成的功能在develop分支中合并、整理,达到稳定状态时才会创建预发布分支进行发布准备。

创建develop分支

$ git checkout -b develop master
Switched to a new branch 'develop'

辅助分支

辅助分支在开发中属于临时性的分支,在使用完成后都可以删除。

功能分支(Feature branches)

Branch offMerge back
developdevelop
功能分支一般从develop分支分出,用来开发新功能新特性。这个分支最终会合并到develop分支(如果不需要这个功能了,也可以放弃这个分支的合并并删除)。
功能分支一般只存在于开发者本地仓库,不需要推送到origin仓库。在合并到develp或抛弃后,删除这个分支。

创建功能分支

下面我们从develop分支创建feature-1功能分支:
$ git checkout -b feature-1 develop
Switched to a new branch 1feature-1'

合并功能分支到develop

功能开发完成,准备发布下一个发布版本时,先合并到develop分支:
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff feature-1
Merge made by the 'recursive' strategy.
 build.gradle                      | 7 +++++++
 src/main/java/me/daemon/Main.java | 7 +++++++
 2 files changed, 14 insertions(+)
 create mode 100644 build.gradle
 create mode 100644 src/main/java/me/daemon/Main.java
$ git branch -d feature-1
Deleted branch feature-1 (was c6fc6e6).
$ git push origin develop

预发布分支(Release branches)

Branch offMerge back
developdevelop and master
预发布分支用来准备新版本的发布。
我们在开发中,一个版本可以包含多个功能或特性的开发,可能需要多个功能分支并行开发。当这些功能都开发完成后,准备发布时,先将这些功能分支合并到develop分支,然后从develop分支分出预发布分支。
当分出预发布分支后,我们可以用这个分支用来提测,修复bug等,这样develop分支就可以继续进行下一个版本的开发工作,新版本的功能分支可以合并到develop分支而不影响上一个版本的测试、修复BUG、发布等工作。

创建预发布分支

develop分支创建预发布分支release-v0.1
$ git checkout -b release-v0.1 develop
Switched to a new branch 'release-v0.1'
创建预发布分支后,在该分支上修改发布版本号,然后提交修改。

完成预发布分支

在预发布分支通过最终测试,准备发布时,需要合并到masterdevelop分支。
首先合并到master并打上tag
$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
$ git merge --no-ff release-v0.1
Merge made by the 'recursive' strategy.
 build.gradle                         | 9 +++++++++
 src/main/java/me/daemon/Feature.java | 7 +++++++
 src/main/java/me/daemon/Main.java    | 7 +++++++
 3 files changed, 23 insertions(+)
 create mode 100644 build.gradle
 create mode 100644 src/main/java/me/daemon/Feature.java
 create mode 100644 src/main/java/me/daemon/Main.java
$ git tag -a v0.1 -m "tag v0.1"
然后合并到develop
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-v0.1
Merge made by the 'recursive' strategy.
 build.gradle | 2 ++
 1 file changed, 2 insertions(+)
此时,该预发布分支的使命已经完成,可以删除该预发布分支:
$ git branch -d release-v0.1
Deleted branch release-v0.1 (was 7942f36).

BUG修复分支(Hotfix branches)

Branch offMerge back
masterdevelop and master
BUG修复分支类似与预发布分支,都是用来准备下一个版本的发布。不同的是,预发布版本是我们计划好的功能与特性集合的发布,而BUG修复版本是为了紧急修复当前发布版本的BUG而存在的。
一般我们开发中遇到的非致命、非紧急的BUG往往选择随同下个版本一起发布,只有遇到致命问题才需要立即在当前发布版本基础上分出分支,修改BUG,并立即发布下一个版本。因此BUG修复分支一般是从master分支分出的。修复完成后要合并到masterdevelop分支。

创建BUG修复分支

master分支创建BUG修复分支hotfix-1.0.1
$ git checkout -b hotfix-0.1 master
Switched to a new branch 'hotfix-0.1'
hotfix-1.0.1上升级版本号、修复BUG,然后提交修改。

完成BUG修复

首先合并到master并打tag
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-0.1
Merge made by the 'recursive' strategy.
 src/main/java/me/daemon/Feature.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git tag -a v0.2 -m "tag v0.2"
然后合并到develop
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-0.1
Merge made by the 'recursive' strategy.
 src/main/java/me/daemon/Feature.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
这里要注意,如果此时存在一个预发布分支,准备发布下一个版本,那么BUG修复分支的修改要合并到预发布分支,而不是develop分支。而在预发布分支发布后,BUG修复的代码会随着发布的代码一起合并到develop
最终,可以删除BUG修复分支:
$ git branch -d hotfix-0.1
Deleted branch hotfix-0.1 (was 17dd42a).

推送远程仓库

将分支都推送到远程仓库:
$ git push --all
推送tag:
$ git push origin v0.1
$ git push origin v0.2
也可以一次推送所有tag:
$ git push origin --tags

示例

我将示例放到我的github上,地址为:https://github.com/daemon369/git-flow-demo。为了演示,辅助分支没有删除。

图示

参看

Android logcat

Log等级 Android log 等级在 android/log.h 中定义如下: typedef   enum   android_LogPriority {    /** For internal use only. */ ANDROID_LOG_UNKNOWN =...