R6300V2 and dnspod ddns

终于把联通宽带配的光猫的路由给废了,为什么,因为端口转发功能实在是配置不起来了。

所以,把光猫的路由改成桥接模式变成交换机。

R6300V2刷了KoolShare改版固件的梅林固件。

$ vi /jffs/scripts/ddns-start
#!/bin/sh

updateDns() {
local userName="DNSPod的帐号"
local password="DNSPod的密码"
local sub_domain="@"
local domain_id="" # 域名ID
local record_id="" # 子记录ID
local data="login_email=${userName}&login_password=${password}&format=json&domain_id=${domain_id}&record_id=${record_id}&record_line=%E9%BB%98%E8%AE%A4&sub_domain=${sub_domain}"
curl -X POST https://dnsapi.cn/Record.Ddns -d "${data}" -s | grep -c '"code":"1"'
}

local updated="0"
local waitTime=10
logger -t DnsPodUpdater "Trying to update dnspod record..."
while [[ $updated -ne "1" ]]; do
updated=$(updateDns)
echo $updated
if [[ $updated -eq "1" ]]; then
logger -t DnsPodUpdater "Dnspod record updated."
else
logger -t DnsPodUpdater "Dnspod record update failed, retrying after $waitTime seconds..."
sleep $waitTime
fi
done

/sbin/ddns_custom_updated 1
$ chmod 755 /jffs/scripts/ddns-start

domain_id与record_id可以通过https://www.dnspod.cn/docs/index.html文档里的获取域名信息记录列表得到。

进入路由的外部网络 -> DDNS -> 启用,Custom。

完成。

参考:

https://nap6.com/question/1144

http://koolshare.cn/thread-4422-1-1.html

polipo convert socket to http proxy

$ brew install polipo
$ ln -sfv /usr/local/opt/polipo/*.plist ~/Library/LaunchAgents
$ vim /usr/local/opt/polipo/homebrew.mxcl.polipo.plist

...

<string>/usr/local/opt/polipo/bin/polipo</string>
<string>socksParentProxy=localhost:1080</string>

...

增加 <string>socksParentProxy=localhost:1080</string>

$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.polipo.plist

Test

$ http_proxy=localhost:8123 https_proxy=localhost:8123 curl google.com

Docker And Haproxy

最近一直想把我的计划完成,在Raspberry Pi上搭一个简单Docker集群。

今天先把Haproxy先搞起来,主要是提供外部访问Docker容器的作用,因为Raspberry Pi集群是在一个内网里的,我的网络中有一个二级路由,要想让一级路由中的其它电脑访问容器提供的服务,就需要在二级路由中做一个端口转发,这样容器多了管理起来很麻烦。

只需要在Haproxy中做代理即可很方便地进行转发,未来还可以做“服务发现”来自动更新配置。

先下载Raspberry Pi专用的容器

$ docker pull hypriot/rpi-haproxy

创建haproxy的配置

$ vim haproxy.cfg
...

frontend http-in
    bind *:80
    use_backend nginx

backend nginx
    server s1 192.168.10.137:8080

...

创建专用数据卷并上传配置到数据卷中

$ docker volume create --name haproxy-data
$ docker-machine scp haproxy.cfg pi:`docker volume inspect --format '{ { .Mountpoint }}' haproxy-data`/

创建docker-compose.yml文件

$ vim docker-compose.yml
haproxy:
    image: hypriot/rpi-haproxy
    ports:
        - "80:80"
        - "443:443"
    volumes:
        - "haproxy-data:/haproxy-override"

运行

$ docker-compose up

下一步是在一级路由网络中使用bind9创建虚拟域名服务来访问haproxy,再由haproxy根据域名进行转发到指定容器。

参考:

https://github.com/hypriot/rpi-haproxy

Android Account Manager

由于最近需要开发个后台同步的功能,翻看了官方的文档,发现了 Sync Adapter https://developer.android.com/training/sync-adapters/index.html

首先创建一个AbstractAccountAuthenticator,在系统设置的帐号里增加咱们的帐号管理器。

创建完该服务和创建xml/authenticator.xml和添加AndroidManifest.xml注册服务,安装包即可在系统设置的帐号里看到咱们的管理器。

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="hr.saas.android.account"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:smallIcon="@mipmap/ic_launcher" />
<service
    android:name="hr.saas.android.account.GenericAccountService"
    android:enabled="true"
    android:exported="false">
    <intent-filter>
        <action android:name="android.accounts.AccountAuthenticator" />
    </intent-filter>
    <meta-data
        android:name="android.accounts.AccountAuthenticator"
        android:resource="@xml/authenticator" />
</service>

完成这步需要创建我们的登录Activity去请求我们的服务器验证登录,获得Token。

// 创建Account
final Account account = new Account(accountEntity.getUsername(), GenericAccountService.ACCOUNT_TYPE);

// 添加
final AccountManager accountManager = AccountManager.get(getContext());
accountManager.addAccountExplicitly(account, accountEntity.getPassword(), null);
accountManager.setAuthToken(account, GenericAccountService.ACCOUNT_TYPE, accountEntity.getToken());

这样我们的帐号的信息就保存到了系统里了,就算把我们的应用删除了,帐号信息也不会被删除,可以做到持久化。

接下来就是使用这些帐号来登录我们的App了。

Account accounts[] = mAccountManager.getAccountsByType(GenericAccountService.ACCOUNT_TYPE);
if (accounts.length > 0) {
    // 获取Token
    mAccountManager.getAuthToken(accounts[0], GenericAccountService.ACCOUNT_TYP, ...)
} else {
    // 通过addAccount方法去添加一个帐号
    mAccountManager.addAccount(GenericAccountService.ACCOUNT_TYPE, ...)
}

参考:

http://udinic.wordpress.com/2013/04/24/write-your-own-android-authenticator/

https://github.com/Udinic/AccountAuthenticator

http://www.devtf.cn/?p=1121

android and golang

毕竟Go语言是Google亲生的,现在Golang团队已经适配好了可以运行在Android平台的Go了,大概看了一下官方的说明,用起来也算很方便,还有Gradle插件支持。

https://github.com/golang/mobile/tree/master/example/bind 这是官方提供的一个Demo。

Package layout

go.mobile/
    cmd/gobind        command line tool
    bind/             code generator, used by command line tool
        bindjava      cgo-JNI bridge, imported by generated code
        registry      global registration for wrapped functions
        seq           data serialization format - Go implementation

> 安装gomobile

$ go get golang.org/x/mobile/cmd/gomobile
$ gomobile init

$ go get golang.org/x/mobile/example/bind/hello
$ gomobile bind -target=android golang.org/x/mobile/example/bind/hello

就会在当前目录下生成hello.aar,通过把hello.aar解压出来就会发现,原来底层也是通过JNI的方式去调用Go的函数的,只是中间包了一层。gomobile工具已经把so与java都提供好了,直接把aar导到现有的工程中就可以直接调用里面的java方法了,这个过程完全不用去定义jni方法,包名,当然了,demo中只提供了,java调用go的过程,go调用java看了一下设计文档,是通过type I interface定义一组接口并生成java的接口文件,然后去实现大概是这样。

https://godoc.org/golang.org/x/mobile/cmd/gomobile

https://docs.google.com/document/d/1y9hStonl9wpj-5VM-xWrSTuEJFUAxGOXOhxvAs7GZHE/edit

Demo代码 https://github.com/linguofeng/androidandgolang