APT Hash sum mismatch

工作当中遇到此问题,然后偶尔看见此文。 此文是 APT Hash sum mismatch 的翻译。

TL;DR

APT 仓库能够提供未压缩和压缩过的文件格式。常用的几个的压缩格式是 gzip, bzip 和lzma。 apt 的 Bug 在处理lzma文件(.xz)读写的时候会偶尔报告“Hash sum mismatch”错误。 本文提供一种变通方式,另外,在特定版本的 apt 中,该bug已经被修复。 使用如下系统的用户应该升级到系统提供的最新的 apt 版本:

  • Ubuntu Trusty (14.04) 及更新的版本
  • Debian Jessie (8) 及更新的版本

更早系统的用户应该升级系统或者使用如下的变通方法。 目前,我们决定关闭 packagecloud 的所有仓库中对 lzma 格式的支持。元数据仍然能够以 gzip, bzip 以及未压缩的格式来获取。packagecloud 仓库的所有者们并不需要做任何事情。

Hash sum mismatch 变通方法

用户可以通过两种方法强制 apt 不使用 lzma 格式的元数据。 第一种办法就是运行 apt-get 的时候添加额外的命令行参数:

apt-get update -o Acquire::CompressionTypes::Order::=gz

(注意:如果你偏向于使用 bzipped 格式,你也可以指定参数为“bz2”) 或者,你可以在全局的 apt 设置中指定这个选项,这样你就不必每次运行 apt 的时候输入这些。 步骤如下:

  1. 创建 /etc/apt/apt.conf.d/99compression-workaround 文件
  2. 添加这些文本到文件中: Acquire::CompressionTypes::Order:: "gz";
阅读更多

strace 速查表

此文是 strace cheat sheet 的翻译。

TL;DR

strace 可以追踪系统调用、信号,在调试中,它还是收集上下文环境的非常好的工具。 此速查表将会展示一些技巧来说明 strace 的使用方法、如何过滤输出,并且介绍了一些 strace 的实用参数。

strace PTRACE_TRACEME EPERM (Operation not permitted)

你应该以 root 身份来运行 strace。如果你以 root 用户运行,也得到这个提示,这说明在你的系统中,strace 不允许附加到进程上。 你可以修改 /proc 中的设置,来开启 strace 附加到进程的功能:

1
sudo bash -c 'echo 0 > /proc/sys/kernel/yama/ptrace_scope'

为了让这个修改永久生效,请首先检查你的系统有没有 /etc/sysctl.d/10-ptrace.conf  文件。 如果你的系统有这个文件,修改该文件:

1
kernel.yama.ptrace_scope = 0

如果你的系统没有这个文件:

  1. 打开 /etc/sysctl.conf 文件
  2. 找到设置 kernel.yama.ptrace_scope
  3. 如果该设置存在,将其修改为 0
  4. 如果不存在,添加一行 kernel.yama.ptrace_scope = 0
阅读更多

《一日重生》

人生总是有很多不如意。

查理在失意许久之后,决定自杀,来结束这些痛苦。意外之中,他的母亲出现了,他和他母亲度过了一天。

这一天看起来是平常的一天,去给别人理发,给塞尔玛小姐化妆等。在平淡的叙事中,加上查理自己的回忆,查理看到了很多小时候被遗忘、被忽略的事情。

确实,查理一心只想追求父爱,忽略了母爱;等到母亲去世之后才知道母爱的珍贵,此后人生的曲折,只能自己一个人去面对。

遗憾的是,查理面对的,仅仅是母亲的灵魂,唯一能改变的,只能是自己。

那天晚上,母亲带着他去见了父亲的第一任妻子,她说出了“原谅”这个词。

过去的恩怨,我们没有机会去讨回、去复仇,现在能做的,也就只有原谅,要原谅的,不是别人,恰恰是自己。


查理是幸运的,他还有机会去重新经历一遍,了解过去、了解自我。

对于我们,就像书中母亲说的一样:

阅读更多

Violet?Purple?

这两个单词都是紫色的意思。突然想到这个有什么区别,所以查了下,还真有。

Violet得名于紫罗兰(紫罗兰的英文也是violet),是一种真正的颜色,有自己的波长(380–450 nm)。

而Purple则是蓝色和红色的混合色。相比Violet,Purple更偏向于贵族的意味。


这是violet:
violet

这是purple:

purple


references: Violet (color), Purple.

阅读更多

PHP 7.0中,目前不能定义函数的返回类型为null或者void

TL;DR:

  • 在PHP 7.0下,不要将函数的返回值声明为null或者void,在PHP7.1下可以。
  • 目前函数返回值不可被声明为nullable。

引子

今天有开发同学遇到了定义返回值为null的函数无法被load的问题: Cannot use ‘App\null’ as class name as it is reserved 追查发现,是因为函数的返回值被声明为了null。

追查

首先,看看返回值到底能不能声明为null: 在RFC PHP RFC: Return Type Declarations 中的Future Work中说:

Allow functions to declare that they do not return anything at all (void in Java and C)

这说明此RFC并不支持声明返回值为null或者void! 但是 PHP RFC: Void Return Type 则表示支持void表示没有任何返回值,但是不允许用null来声明!(还给了原因) 但此RFC会在PHP 7.1中实现,所以目前在PHP 7.0中还不能使用。 PS:经过实验,PHP7.0中,声明返回值为void可以通过语法检查,但是无论怎么返回都会报错(无论是直接return还是不返回):

Return value of App\User::func() must be an instance of void, none returned

更远一点,关于声明返回值为nullable的问题,现在还在草稿阶段,还有很长的路要走:PHP RFC: Declaring Nullable Types

阅读更多

开始使用Docker(在OS X下)

如果你想在OS X上尝试Docker,但是又觉得安装虚拟机什么的太麻烦了,那么你可以考虑下Docker Toolbox

安装Docker Toolbox

虽然官方提供了下载链接,但是我依然决定使用Homebrew Cask来安装Docker Toolbox:

brew cask install dockertoolbox

当然,如果下载特别慢的话,可以使用ProxyChains-NG来代理下。 安装结束后,VritualBox也被当作依赖安装了。(但是我推荐再安装virtualbox-extension-pack:brew cask install virtualbox-extension-pack )

创建虚拟机

接下来就要为所有的docker容器创建一个虚拟机了:

docker-machine create –driver virtualbox –virtualbox-hostonly-cidr “192.168.125.1/24” default

--driver virtualbox 表示使用VirtualBox来创建虚拟机;--virtualbox-hostonly-cidr “192.168.125.1/24” 表示使用192.168.125.1/24网段(默认使用的是192.168.99.1/24网段,但是和newifi的默认网段重复了)。 可以添加--engine-registry-mirror http://.m.daocloud.io 来使用daocloud的registry mirror。

第一个docker命令

阅读更多

安装 PHP 7

PHP 7 正式发布了好久了,现在就总结下如何在各个系统上安装 PHP 7。(本文在很大程度上参考了 Installing PHP 7.0.0

Ubuntu系列

PHP 7 可以直接使用 PPA for PHP (5.6, 7.0) : Ondřej Surý:(原来这个PPA中的fpm不能正常工作,后来发现已经改掉了)

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install php7.0

Debian系列

PHP 7 可以通过 Dotdeb repository 来安装: 创建文件 /etc/apt/sources.list.d/dotdev.list ,内容为如下两行:(其中的 <distribution> 根据需要替换为 squeeze, wheezy 或者 jessie):

deb http://packages.dotdeb.org all
deb-src http://packages.dotdeb.org all

添加GPG key :

wget https://www.dotdeb.org/dotdeb.gpg
sudo apt-key add dotdeb.gpg

安装 PHP 7 :

阅读更多

PHP7 中五个鲜有人知的特性

本文是 Five Lesser-Known Features of PHP 7 的译文 PHP 7 即将发布(原文如此,现在 PHP 7 已经正式发布),我觉得检查 PHP 7 带来的一些鲜为人知的新特性是一件非常酷的事情:

1. define()可以定义数组常量

自 PHP 5.6 开始,可以使用 const 关键字在类中定义常量数组:

const LUCKY_NUMBERS = [4, 8, 15, 16, 23, 42];

PHP 7 将同样的功能引入到 define() 函数中:

define(‘LUCKY_NUMBERS’, [4, 8, 15, 16, 23, 42]);

2. 被0除

PHP 7 之前,被0除会导致一条 E_WARNING 并返回 false。一个数字运算返回一个布尔值是没有意义的,所以 PHP 7 会返回如下的 float 值之一(同时出发一条 E_WARNING):

  • +INF
  • -INF
  • NAN

比如:

阅读更多

PHP/Laravel中的“异常链”

之前知道,Python 3 中终于实现了对异常链的支持。 最近,在代码中,有一处写着:

try {
// some code
} catch (\Exception $e) {
\Log::error(‘xxx_id’ . $xxx->id);
}

问了之后才发现,这是需要知道是哪个id触发的错误,如果不捕获异常的话,在backtrace信息中可能不会出现此id。 但是,这样做虽然可以达到他的目的,但是掩盖了底层的错误,对后续的追查不利。 然后,作为(伪)Python开发者的我就想起了Python3中的异常链技术,所以找了下PHP中有没有类似的东西,结果发现:自PHP 5.3开始,支持了类似的技术。 解决方案:可以自己扩展Excepiton类,默认的构造方法里面,第三个参数是前一个异常,经过测试,在Laravel框架中,同一条链中的Exception都会展示出来(无论是在Console输出,还是日志输出中)。


好,让我们来自己试一试。 首先写一个Command:

class NestExceptionTest extends Command
{
protected $name = ‘NestExceptionTest’;

public function fire()
{
    try {
        $this->testOneLevel();
    } catch (\\Exception $e) {
        throw new \\Exception("top level", 0, $e);
    }
}

private function testOneLevel()
{
    try {
        $this->testTwoLeve();
    } catch (\\Exception $e) {
        throw new \\Exception('one level', 0, $e);
    }
}

private function testTwoLeve()
{
    throw new \\Exception('two level');
}

}

为了偷懒,就没有自己定义自己的Exception,仅仅是不同的错误信息来区分。 执行此命令,输出如下: Exception output console同时,日志输出如下:

[2015-12-12 13:54:06] production.ERROR: exception ‘Exception’ with message ‘two level’ in /Users/robberphex/projects/xxx/app/Console/Commands/NestExceptionTest.job:31
Stack trace:
#0 /Users/robberphex/projects/xxx/app/Console/Commands/NestExceptionTest.job(23): App\Console\Commands\SiteMap\SiteMapBuild->testTwoLeve()
#1 /Users/robberphex/projects/xxx/app/Console/Commands/NestExceptionTest.job(14): App\Console\Commands\SiteMap\SiteMapBuild->testOneLevel()
#2 [internal function]: App\Console\Commands\SiteMap\SiteMapBuild->fire()
#3 /Users/robberphex/projects/xxx/vendor/laravel/framework/src/Illuminate/Container/Container.php(503): call_user_func_array(Array, Array)
#4 /Users/robberphex/projects/xxx/vendor/laravel/framework/src/Illuminate/Console/Command.php(150): Illuminate\Container\Container->call(Array)
#5 /Users/robberphex/projects/xxx/vendor/symfony/console/Command/Command.php(256): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#6 /Users/robberphex/projects/xxx/vendor/laravel/framework/src/Illuminate/Console/Command.php(136): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#7 /Users/robberphex/projects/xxx/vendor/symfony/console/Application.php(838): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#8 /Users/robberphex/projects/xxx/vendor/symfony/console/Application.php(189): Symfony\Component\Console\Application->doRunCommand(Object(App\Console\Commands\SiteMap\SiteMapBuild), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#9 /Users/robberphex/projects/xxx/vendor/symfony/console/Application.php(120): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#10 /Users/robberphex/projects/xxx/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(107): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#11 /Users/robberphex/projects/xxx/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 {main}

阅读更多

Let’s Encrypt/HTTPS配置记录

前几天收到Let’s Encrypt public beta的邮件,所以就尝试了下ssl+https+http/2。

Let’s Encrypt 配置

首先,我之前遇到过Error creating new authz 的错误,就一直没有尝试,后来发现v2ex上有人通过设置NS记录解决了问题(虽然文中说要设置MX记录,但是我只更换了NS记录到CloudFlare),生效时间可能是24h。 不过由于cf会友好地将所有流量切换到它的反代服务器,所以需要关闭此特性;另外,也需要关闭cf中HTTPS的开关,由自己的主机来处理HTTPS请求(所以我仅仅是将cf作为一个DNS服务器而已)。 另外有一个坑:由于我用的是nginx,letsencrypt这个客户端程序需要自己接受80端口的请求来验证服务器身份,所以需要临时关闭nginx。 最后开始生成服务器证书: 第一步:将letsencrypt项目clone到特定目录下:

git clone https://github.com/letsencrypt/letsencrypt.git /opt/letsencrypt

第二步:cd到该目录,然后执行如下命令生成证书:

./letsencrypt-auto –agree-dev-preview –server https://acme-v01.api.letsencrypt.org/directory certonly

依次填写邮箱、域名后,会在 /etc/letsencrypt/live// 目录下生成证书(nginx只用到fullchain.pem和privkey.pem) 注:此命令一定要添加–server选项,否则生成的证书并不被浏览器信任。 证书都已经生成,接下来配置nginx。

nginx配置

注:如果要开HTTP/2的话,就必须要添加nginx mainline的repo了:

[nginx]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1

阅读更多