Living a Simple Life is a Happy Life

有饭吃,自由自在,就非常开心

Markdown Raw Format

| Comments

有时候想要在Markdwon里面画ASCII画,会被Format掉,例如:

|——————–+ | | | —— ——- | | | | \ / | | ——-/ | | | +——————–+

这个时候可以用缩进来解决:

|--------------------+
|                    |
|  ------    ------- |
|                    |
|     \        /     |
|      -------/      |
|                    |
+--------------------+

参考: https://meta.stackexchange.com/questions/177133/turn-off-markdown-formatting/177135#177135?newreg=acda653c863843a99d1008c464864262

引发了一点兴趣,meta.stackexchange.com上面有个测试语法专贴,各种乱搞洋洋大观:

http://meta.stackexchange.com/questions/3122/formatting-sandbox/43134#43134

Docker Cheat Sheet

| Comments

container相关

1
2
3
4
$ docker run -it xxx /bin/bash                                      // 启动一个container
$ docker rm -f xxx                                                  // 结束一个container,加-f表示删除掉,这样比较干净
$ docker run -it --add-host host:ip xxx /bin/bash                   // 启动一个container,增加/etc/hosts设定
$ docker run -d -p 127.0.0.1:5000:5000 webapp python app.py         // 启动一个container,映射本地的5000端口

image 相关

1
2
3
4
5
$ docker rmi -f xxx                                                 // 删除一个image,以下情况下不能删除:
                                                                    // * 有其他image依赖于这个image
                                                                    // * 有已创建的container依赖于这个image
                                                                    // build的过程会出现很多<none>的临时image,最好不要去手工清除
$ docker build tag Dockerfile_dir                                   // build一个image

docker service 相关

配置文件位置

  • ubuntu: /etc/default/docker

  • centos: /etc/sysconfig/docker

配置参数

DOCKER_OPTS

增加docker 仓库验证

--insecure-registry own-docker.com

设置storage backend

-s overlay

使用overlay极大提升性能和稳定性,建议开启。但是有两个问题:

  • 编译centos镜像时,调用yum会报checksum错误,所以基本上不能在overlay上面构建redhat系的镜像

  • 不支持 inotify_add_watch 调用,tail -f 类的命令会有问题,具体见:https://github.com/docker/docker/issues/11705

相关工具:

docker镜像瘦身工具

https://github.com/jwilder/docker-squash

nsenter, docker inspect的增强版

https://github.com/jpetazzo/nsenter

dockerfly,自己写的一个构建工具

https://github.com/brain-zhang/dockerfly

shipyard,还算是比较靠谱的监控工具

https://github.com/shipyard/shipyard

一些坑:

  • centos 在4.0.0-1.el6.elrepo.x86_64内核下,启动xfs+overlay,删除文件夹会有问题
  • overlay下,tail命令会有问题
  • overlay下,docker build,yum的checksum会有问题
  • devicemapper效率巨慢无比,不要用

python2.x:Error When Printing an Exception Containing a Unicode String

| Comments

Python2.x中抛出Unicode的异常需要注意:

1
2
3
4
5
>>> try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     print e
...     print str(e)

会报UnicodeEncodeError: ‘ascii’ codec can’t encode character …

同样,如果在log中直接输出,也会报错

1
2
3
4
5
6
7
8
>>> import logging
    logger = logging.getLogger('default')
    try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     logger.error(e)
...     logger.error("%s", e)
...     logger.error("%s", str(e))

简单的解决办法就是用e.message

1
2
3
4
5
>>> try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     print e.message
...     print "%s" % e.message

也可以详细的可以指定encoder

1
2
3
4
>>> try:
...     raise Exception(u'Error when printing 中文异常')
... except Exception, e:
...     print unicode(e.message).encode('utf-8')

Python3就没这个事了,备忘一下。

参考:

http://bugs.python.org/issue2517

C:dynamic Array in Stack

| Comments

以前一直认为C99 只支持const int 定义数组,今天才学到C99里面是支持动态数组的。

1
2
3
4
5
int main()
{
    int x = 12;
    char pz[x];
}

C99是支持的。在gcc4+以上的版本里测试OK。

另外stackoverflow上提到C++不支持动态数组,在g++4.4.7里面试了一下,也是可以的。

不是我不明白,这世界变化快。

Out好多好多年了…….

参考: http://stackoverflow.com/questions/1204521/dynamic-array-in-stack http://stackoverflow.com/questions/737240/c-c-array-size-at-run-time-w-o-dynamic-allocation-is-allowed

svn1.7+ Zsh报错

| Comments

更新svn(subversion)>1.7后 zsh 的svn自动完成会报错。

_arguments:comparguments:312: invalid argument: [--cl]:arg:

修改方法:

打开文件:/usr/share/zsh/4.3.11/functions/_subversion

找到35行左右

${=${${${(M)${(f)"$(LC_ALL=C _call_program options svn help $cmd)"#(*Valid options:|(#e))}:#* :*}%% #:*}/ (arg|ARG)/:arg:}/(#b)-([[:alpha:]]) \[--([a-z-]##)\](:arg:)#/(--$match[2])- $match[1]$match[3] (-$match[1])--$match[2]$match[3]} 改为

${=${${${(M)${(f)"$(LC_ALL=C _call_program options svn help $cmd)"#(*Valid options:|(#e))}:#* :*}%% #:*}/ (arg|ARG)/:arg:}/(#b)(-##)([[:alpha:]]##) \[--([a-z-]##)\](:arg:)#/(--$match[3])$match[1]$match[2]$match[4] ($match[1]$match[2])--$match[3]$match[4]}

参考资料: http://www.zsh.org/mla/workers/2011/msg01448.html

自定义Django的密码策略

| Comments

Django 从1.4 版本开始,包含了一些安全方面的重要提升。其中一个是使用 PBKDF2 密码加密算法代替了 SHA1 。另外一个特性是你可以添加自己的密码加密方法。

Django 会使用你提供的第一个密码加密方法(在你的 setting.py 文件里要至少有一个方法)

1
2
3
4
5
6
7
8
PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher', # Insecure Hashes
    'django.contrib.auth.hashers.MD5PasswordHasher', # Insecure Hashes
    'django.contrib.auth.hashers.CryptPasswordHasher', # Insecure Hashes
)

但Django默认生成的密码策略往往会带上 md5_xxx, pbkdf2_xxx,同其他系统整合的时候,一般是没有这些前缀的,这就需要我们自定义一个密码策略。

下面介绍下如何定义一个简单的 md5(md5(password, salt)) 密码策略。

step1

建立一个app,django-admin.py startapp ownmd5

step2

在 ownmd5中 建立 hashers.py 文件,加入 OwnMd5PasswordHasher 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import hashlib
from django.utils.translation import ugettext_noop as _
from django.utils.datastructures import SortedDict
from django.utils.crypto import constant_time_compare
from django.utils.encoding import force_bytes, force_str, force_text
from django.contrib.auth.hashers import BasePasswordHasher, mask_hash


class OwnMD5PasswordHasher(BasePasswordHasher):
    """
    The Salted MD5 password hashing algorithm (not recommended)
    """
    algorithm = "ownmd5"

    def encode(self, password, salt):
        assert password is not None
        assert salt and '$' not in salt
        hash = hashlib.md5(hashlib.md5(force_bytes(salt + password)).hexdigest()).hexdigest()
        return hash

    def verify(self, password, encoded, salt):
        encoded_2 = self.encode(password, salt)
        return constant_time_compare(encoded, encoded_2)

    def safe_summary(self, encoded, salt):
        return SortedDict([
            (_('algorithm'), self.algorithm),
            (_('salt'), mask_hash(salt, show=4)),
            (_('hash'), mask_hash(hash)),
        ])

###step3

将 OwnMD5PasswordHasher 加入到settings.py 中:

1
2
3
PASSWORD_HASHERS = (
    'ownmd5.hashers.OwnMD5PasswordHasher',
)

这样,默认的user及auth模块都会采用自定义的md5算法。

参考:

https://docs.djangoproject.com/en/1.6/topics/auth/passwords/

Auto Reload Modules in Django Shell

| Comments

python manage.py shell

太常用了,但是每次修改模块代码后,总要 exit—>reset 才能重新load一遍代码,实在是不爽。

也曾经改造ipython,想要代码修改后实时载入,各种坑,最后各种懒之下还是老老实实reload。

最近发现一个扩展,django-externsions:

https://github.com/django-extensions/django-extensions

装上好用不少,貌似还比较靠谱,推荐之。

Vim 对选中范围内容批量替换

| Comments

vim可以很方便的用 %s/src/dst/g 批量替换。

但是我想对ctrl+v 块选择的内容做批量替换就麻烦一点了,每次都得打一串很长很长的脚本命令。

发现的一个插件做这个事,vis:

https://github.com/vim-scripts/vis

支持两个命令模式:B 和 S

B 在选定区域内执行命令

ctrl+v选中内容后,使用:B cmd,此时命令栏的状态应该是:'<,'>B cmd这样。

例如替换内容, ctrl-v :B s/pattern/becomes/

执行外部命令,ctrl-v :B !sort

S 在选定区域内查找内容

ctrl+v选中内容后,使用:S pattern,此时命令栏的状态应该是:'<,'>S pattern这样。

解脱了….

记一下免得又忘掉。

Vim 命令行操作小技巧

| Comments

vim 使用:进入命令行后,除了直接敲命令外,一般会有两个操作:

1.查看历史指令并执行

2.复制寄存器中的内容 1 查看历史指令需要在进入命令行之前使用q:,再选则就OK了。

2 使用寄存器,一般复制时使用” + [寄存器名称] + y,进入命令行后再输入ctrl R,选择相应的寄存器粘贴就OK了。

vim tooltips

Display CRLF as ^M:

1
:e ++ff=unix

Rake Gen Deploy Rejected in Octopress

| Comments

Octopress老版本,例如我用的,在一台新机器上check 下来Repo,重建source分支时,会报rejected错误。

怎么pull也不管用,解决办法参考这里:

http://stackoverflow.com/questions/17609453/rake-gen-deploy-rejected-in-octopress

悲剧提示,我后来发现有一段blog被revert掉了,诡异的是在github上面的提交记录也没了,要慎用,要做好备份。