Sunday, February 22, 2009

无人值守批量安装软件

因工作需要, 要在N台机器上安装nrpe, 就有了这样的要求:

知识背景:
1. ports包管理机制(man ports)
1. 脚本语言(此使用perl)
1. ssh的使用

前提:
* 每台机器应该有ssh的public key, 否则每次都输入密码人会晕的

无人值守,第一个是去掉需要人干涉的部分!这就是make包的过程!

有两种情况:
1. make过程出错了
2. configure需要人指定

第一种可以通过N多个if去处理,我是不想这样做的, 大不了登机手工安装,所谓的特殊案例特殊处理.出错记录一下就行了

第二种是可以通过ports的管理机制去处理的. 如下:

make install时有时会出现一个"对话框"的, 这个东西的是使用diaglog( 请man 1 diaglog )程序去产生的. 但是可以使用BATCH变量



#!/usr/bin/env perl

open LogFile, ">/tmp/install_nrpe.log";

my @HostList = (1..100);

for my $Host (@HostList){
$Host = "192.168.54." . $Host;
system "ssh", "-o ConnectTimeOut=1", $Host, "pkg_info|grep nrpe2" ;
if ( $? == 256 ){
print $Host . "\n";
system "ssh", $Host, "cd /usr/ports/net-mgmt/nrpe2/ && sudo make BATCH=yes install";
}else{
print LogFile "can't install at " . $Host . "\n";
}

}

脚本的一点说明:
1. ssh使用了-o ConnectTimeOut=1是表示, 在使用ssh连接时, 超时为1秒, 这样就不会让ssh一直在等待了.
2. $?为ssh运行远程命令的返回码.本例中为"pkg_info|grep nrpe2".

/var: create/symlink failed, no inodes free

还没有见过这样的问题:
/var: create/symlink failed, no inodes free

没有空间了吗?使用df -h 怎么看都还有空间!细看才体会到这里提的inodes的意义!

google了一把,才知道df命令有一个参数是显示partition的inodes的

[jessinio@demo2 /var/db/portsnap]$ df -hi
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/ad0s1a 496M 288M 168M 63% 3912 61878 6% /
devfs 1.0K 1.0K 0B 100% 0 0 100% /dev
/dev/ad0s2d 79G 38G 35G 52% 931619 9808091 9% /data0
/dev/ad0s1e 496M 15M 441M 3% 1146 64644 2% /tmp
/dev/ad0s1f 24G 19G 3.3G 85% 936629 2360649 28% /usr
/dev/ad0s1d 1.9G 1.3G 431M 76% 262862 19760 93% /var
/usr/ports 24G 19G 3.3G 85% 936629 2360649 28% /data0/jails/trac10/usr/ports
/usr/src 24G 19G 3.3G 85% 936629 2360649 28% /data0/trac11/usr/src
/usr/ports 24G 19G 3.3G 85% 936629 2360649 28% /data0/trac11/usr/ports
devfs 1.0K 1.0K 0B 100% 0 0 100% /data0/jails/trac10/dev


在/var目录下发现/var/db/portsnap/files有20000左右个文件:
ls /var/db/portsnap/files|wc -l

使用脚本去删除之:

opendir DIR,"/var/db/portsnap/files";
for (readdir DIR){
system "rm", "/var/db/portsnap/files/" . $_;
}
close DIR;

* BTW: 不知道当时为什么不使用rmdir去删除, SB了!!

Saturday, February 14, 2009

perl中的数据结构

开始学perl,是从<<learning perl >>一书开始的, 这样有个好处:初学者不用也不应该去知道perl太多的约定,不然,perl还没有学到人就怕了.

learning perl一书内容比较简单.感觉很自在.大概浏览了后,发现提到perl两种数据结构:
1. array
1. hash

但是没有提到:
1. 多维array
1. array与hash的混合引用.

这最觉得不爽了, 对于算法不强的人来说这无疑是个灾难!

google了一把, 原来这方面的知识在<<programming perl>>一书中讲到:
* http://docstore.mik.ua/orelly/perl/prog3/ch09_01.htm

回顾一下简单的array和简单的hash的产生方法:
1. array的产生:
my @TiketNum = (1, 19, 20, 45, 56, 19, 42, 56);
2. hash的产生:
my %Person = (
jessinio => "SA",
jacke => "PE",
hyliker => "RP",
zoomq => "LD",
smallfish => "EA"
);

可以看到, array和hash都是使用了"("和")"与产生的.

仅仅利用"()"产生array和hash是不能构造出复杂的数据结构的.如下面的写法就出问题了:
my @TiketNum = ((1, 9), 19, 20, 45,56,19,42,56);
print $TiketNum[0][0]

或者:
my @TiketNum = (1, 19, 20, 45,56,19,42,56);
$TiketNum[0] = (1, 9);
print $TiketNum[0][0];

都是有问题的. hash也是有同样的问题



看了programming perl讲到的数据结构后, 知道了array和hash原来有其它的产生方法:
1. array 使用 "[]"
1. hash 使用"{}"

要想复杂的数据结构只能利用这两种产生方法, 如:

my %Person = (
name => "jessinio",
age => 26,
description => "System administrator",
location => "zhu hai",
LuckNumber => [8, 168, 88] #不是使用"()"的!!
);
print $Person{'LuckNumber'}[0];

* 当然, 可以把所有的"()"用"{}","[]"去代替
产生array和hash后, 去修改存在的array和hash, 使之成为复杂的数据结构, 要使用"[]"和"{}"

如:

my @TiketNum = (1, 19, 20, 45,56,19,42,56);
$TiketNum[0] = [1, 4, 0, 8]; #不是使用"()"的!!
print $TiketNum[0][3];

还可以array的成员为hash:
my @TiketNum = (1, 19, 20, 45,56,19,42,56);
$TiketNum[0] = {1 => 4, 0 => 8}; #不是使用"()"的!!
print $TiketNum[0]{1};


这样就有复杂的数据结构了.



BTW: 没有这两种数据结构真的不是滋味!shell就没有了!!!呃......所以学perl了(原因之一) ^_^

光棍的情人节

今天是2.14,西方情人节,对于我这种光棍来说,一早就接到电信公司打来开通ADSL的电话(为什么不是MM的电话呢? -_-!)。
一早就想在宿舍开通ADSL了,就是RMB的问题,今天终于把网络安装上了。好了,modem在跑了,就是没有router。反正今天不是光棍的节日,决定几个光棍一起去电脑城逛!

电脑城多了一个推销电脑的理由:把netbook送给她(他),呃。。。。。自己都还没有呢

真的很喜欢netbook了。为什么?我的notebook太奶奶的重了!

无事做又去体会了一把M8手机,感觉很好,不知道iphone使用起来是什么感觉。

逛了二三个小时,掏了个D-Link牌的router回。

然后。。。。回到宿舍还没有体会到wireless带来的宅男生活,就跑去hospital去了。。。。囧。。。。。

猜是抽烟抽到肺烂了。。。。。

结果。。。。X光片看不出。。。。总的感觉是:花钱买放心

总后,回宿舍做菜去:picasa照片:http://picasaweb.google.com/jessinio/214#


菜做了,也吃了,是时候搞宅男应该做的事了:玩系统!

玩什么? linux连接到WPA2 wireless network

结果。。。。。还是搞不掂!!!!!!算了,好男不吃眼前亏,有空再搞!

常用的linux无线命令行(WEP的)
http://wirelessdefence.org/Contents/LinuxWirelessCommands.htm

Friday, February 13, 2009

postgres学习之(4): 初步学习总结

在学习postgres时, 常常有些概念或者名词会容易搞错的. 下面总结一下.


pgsql
psql
role
superuser
psql或者createdb等等postgres-client带有的命令行中的--username参数.


在开始前, 应该使用DBMSs和database去区分数据库软件与数据库这两个概念. (^_^)

pgsql是一个用户名, 是安装DBMSs的操作系统中的一个常规用户. 这个常规用户作为操作系统本来的常规用户外, 还有一个特殊的身份: DBMSs软件管理中的root权限者!也就是说, pgsql在操作系统中是一个和nobody没有区别的用户. 但是当pgsql登陆入DMSs软件系统中时, 它就是superuser了! 因为DBMSs内有一套自身的权限机制.


psql是一个交互性命令行.它是用户与DBMSs软件系统交互的接口, 类似kernel与shell的关系.


role是认证系统中的角色, role包括有三个属性:用户名, 密码, 权限(自已总结的, 不是真的), linux操作系统与DBMSs软件系统使用不同的role系统, 但是当DBMSs软件系统使用了trust认证方式时, DBMSs软件系统会把存在于DBMSs中的role的"用户名/密码"与linux系统中的"用户名/密码"进行映射. 当使用非trust认证方式时, 这种映射就不存在.



superuser是超级管理员, 这分为DBMSs软件系统中的superuser和操作系统的superuser, 此superuser非彼superuser


psql或者createdb等等postgres-client带有的命令行中的--username参数, 是指连接到DMBSs软件系统时, 指定使用DBMSs中的role的名字.




个人屁笔记.

postgres学习之(3): database管理之用户认证

postgres有多个认证方式, 如:LDAP, Kerberos, md5, trust等等, 因为本人工作环境中, 会使用到两种:
1. md5
2. trust

现在只记录这两种方式, 其它的到使用到再记录.

postgres的认证方式配置在于: /usr/local/pgsql/data/pg_hba.conf

如下是本人的postgres认证配置:

# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust



trust与md5的区别.

在上篇学习笔记中, 知道了, jessinio用户连接到数据库是无需使用密码的, 再看一下例子, 了解两种认证方式的区别:
[jessinio@study ~]$ psql --host 127.0.0.1 -d jessinio -U pgsql
Welcome to psql 8.2.9, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

jessinio=#


可以连接.

为什么呢? 条件有二:
1. 127.0.0.1是使用了trust认证
1. jessinio在createuser时设置用户的密码!



把pg_hba.conf的trust修改为md5后:
host all all 127.0.0.1/32 trust

重新连接:

[jessinio@study ~]$ psql --host 127.0.0.1 -d jessinio -U jessinio
Password for user jessinio:

要求输入输入密码了! 在createuser时没有指定密码, 现在怎么重新设置密码呢? 答案是使用pgsql这个superuser去干!

# psql -d jessinio -U pgsql
# alter user jessinio with password 'pgsql_password';


这样就重置密码了.

DBMSs都是建议不使用trust的.

在initdb的手册中写得:

--auth=authmethod
This option specifies the authentication method for local users
used in pg_hba.conf. Do not use trust unless you trust all local
users on your system. Trust is the default for ease of installa-
tion.

postgres学习之(2): database管理之用户与DB

为方便日后数据迁移. 一定要学会postgres的管理, 不然, 处于被动环境.

信息来源: <> 和 伟大的man手册
postgres的管理都可以通过交互前端psql命令去完成.

但是为了方便, 还有几个细化的命令(这此命令实际上就是SQL的wrapper!):
1. createdb
注: 一旦创建了一个数据库, 创建者就是该数据库的拥有者和管理员. 一般情况下为用户pgsql, linux下应该为postgres, 因为pgsql一般是数据库管理员使用的帐号, 当然, 不使用pgsql用户权限也可以正常使用createdb, 这取决于postgres的认证方式. 否则会出现下面的信息:

[jessinio@study ~]$ psql
psql: FATAL: database "jessinio" does not exist

[jessinio@study ~]$ createdb jessinio
createdb: could not connect to database postgres: FATAL: role "jessinio" does not exist

上面的主要信息是: jessinio无法使用createdb, 这是因为在postgres服务中, 没有jessinio这个role(角色)!

role表示了:要连接和使用数据库, 第一条件是要在postgres系统中存在相应的role才能登陆!
* 注意: 有了相应的role, 并不等于有了root权限(superuser)!
* 权限总的来说有两种: 对DBMSs的权限, 还有一种是对DB的权限

role如何去创建与修改, 新创建的role对DBMSs有哪些权限?

答案是:createuser

下面是一些选项和它们的默认值:
--superuser
--no-superuser: Ture
--createdb
--no-createdb: Ture
--createrole
--no-createrole: Ture
--login: Ture
--no-login
--inherit
--no-inherit: Ture
--connection-limit: no limit
--encrypted
--unencrypted: Ture
* Ture表示默认值.

下面是实际情况:

[pgsql@study /usr/home/jessinio]$ createuser jessinio
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) n
CREATE ROLE

好了, 现在有jessinio用户有了对DBMSs操作的role了, createdb吧:
[jessinio@study ~]$ createdb jessinio
CREATE DATABASE

一切顺利!!!!!

去哪里使用万能的SQL呢? 答案是: psql

[jessinio@study ~]$ psql
Welcome to psql 8.2.9, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

jessinio=>

进入了.

留意一下, 就可以知道, jessinio用户登陆是不用输入密码的. 为什么呢?

这与postgres的认证系统有关. postgres的认证方式写在下一篇blog中.

Thursday, February 12, 2009

postgres学习之(1): postgres的安装

工作中需要使用到postgres, 为了方便, 决定学习一把postgres的安装与管理!(日后不怕事呀 ^_^)
* 文章内容全是个人摸索过程, 废话比较多. 应该少看为好 (^_^)

Step One:
当然是安装了, 在FreeBSD下, postgres的server Port的版本需要与postgres的client Port版本一一对应的, 就是说:
* postgres的client8.2就要与postgres的server8.2对应, 不过安装会出错. 例子如下:
本人的机器中早已经安装了postgres82-client. 当本人想去安装postgres83-server时就出错, 解决方法有二:
1. pkg_delete 8.2的client, 安装8.3的client
1. 安装8.2的server

本人选择了第二种, ^_^反正是学习, 方便就行了.

安装完server后, 就会增加一个系统用户名:pgsql
* 注意, 在linux系统下, 此用户名应该是postgres! 我是相当地 囧!!

Step Two:
check一把配置文件. FreeBSD下是/usr/local/pgsql, 不过, 现在还不知道从何入手.

小白的我只知道系统下管理postgres操作是使用系统的特殊用户: 那就是pgsql了!!

切换过去吧:
# su pgsql
$ bash
[pgsql@study /]$
* 这样就使用pgsql用户了. 这是有几个pgsql用户可以使用的命令:
pg_config: retrieve information about the installed version of Postgres
pg_ctl: start, stop, or restart a PostgreSQL server
pg_dumpall: extract a PostgreSQL database cluster into a script file
pg_restore: restore a PostgreSQL database from an archive file created by pg_dump
pg_controldata: display control information of a PostgreSQL database cluster
pg_dump: extract a PostgreSQL database into a script file or other archive file
pg_resetxlog: reset the write-ahead log and other control information of a PostgreSQL database cluster

逐一man一次! ^_^ 无敌的man呀~!~!~!~

发现man不是万能的, 还是看书吧!囧!!

在书上找到了一点灵感, 就是使用pkg_info


pkg_info -L postgresql-server-8.2.9|less

看到了一个initdb, man了一下, 看到cluster这个名词, 这不是pg_*系列命令中的一个有这个单词的吗?

哈, 就是pg_controldata了, 看来两者相关!

每个数据库都有一个叫data的数据目录的, 新安装的postgres还没有看到, 看到是使用initdb的时候了.

好晕, initdb一堆ooptions! 其实, initdb只有个option是必选的: --pgdata=directory

不理, 试一下简单的:

[pgsql@study /usr/ports/databases/postgresql82-server]$ initdb --pgdata=/usr/local/pgsql/
The files belonging to this database system will be owned by user "pgsql".
This user must also own the server process.

The database cluster will be initialized with locales
COLLATE: C
CTYPE: zh_CN.UTF-8
MESSAGES: C
MONETARY: C
NUMERIC: C
TIME: C
The default database encoding has accordingly been set to UTF8.

initdb: directory "/usr/local/pgsql" exists but is not empty
If you want to create a new database system, either remove or empty
the directory "/usr/local/pgsql" or run initdb
with an argument other than "/usr/local/pgsql".

* 发现不行, pgdata目录一定要为空的, 结果使用/usr/local/pgsql/data就OK了

成功initdb后, 有如下内容:

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.

Success. You can now start the database server using:

postgres -D /usr/local/pgsql/data
or
pg_ctl -D /usr/local/pgsql/data -l logfile start

* 从上面的info可以得到三个信息:
1. 配置文件为pg_hba.conf
1. postgres的启动方式
1. 现在这个cluster的认证方式
* 配置配置文件就不能猜了, 只能看手册了.


本人只修改两个文件:
* pg_hba.conf
* postgresql.conf

postgres服务正常启动! good boy

使用CPAN安装perl包

本来不想搞的. 就是因为在FreeBSD下安装xfce时要求几个perl模块:

1. URI::Escape
1. URI::URL
1. URI::file


cpan命令行的man手册:

* linux下的cpan命令与FreeBSD下的cpan命令在参数的数目上有不同(linux上的参数较多)

cpan命令行总的来说只有两个方式使用:

1. 对特定的module进行操作
# with arguments and no switches, installs specified modules
cpan module_name [ module_name ... ]
* 这是只有module名, 没有使用参数

# with switches, installs modules with extra behavior
cpan [-cfimt] module_name [ module_name ... ]
* 这是使用了参数

2. 对cpan操作
# without arguments, but some switches
cpan [-ahrvACDLO]

对于第一种: 对特定的modules进行操作, 也就是: Module options
有四种情况:
* c 等于make clean
* i 等于install
* m 等于make
* t 等于make test


对于第二种: cpan操作, 也就是: Meta Options
有四种情况:
* a 生成CPAN.pm包
* h 帮助信息
* r 生新编译包
* v 版本信息

没有专业的味道

一下搞FreeBSD, 一下搞Linux, 我都不知道自己是哪一边的了.

现在又搞起了FreeBSD的desktop环境.

呃......

没有专业的味道.....

无语.....

使用FreeBSD做桌面

人就是要折腾的! 手上多出一台机, 反正没有玩过freeBSD下的Xorg, 就玩一下吧.



[jessinio@study /usr/ports/x11/xorg]$ make fetch
This is a meta-port, meaning that it just depends on its subparts of the port.
It won't build and install all the parts until you have typed make install
This port does not ensure things are upgraded; use portupgrade if you want to
upgrade X.Org. If you simply type 'make install' it may use over 2GB to build
all of the subports. You can install the ports singly if you are low on space.
===> Vulnerability check disabled, database not found

呃...... 安装xorg要2GB? 汗!

只能慢慢的等待安装了:
# make install |tee ~/xorg.log


因为前段时间使用了gentoo, 所以在FreeBSD下安装桌面环境还是属于轻车熟路的.

安装四个包就OK了:
1. /usr/port/x11/xorg
1. /usr/port/x11-wm/xfce4
1. /usr/port/chinese/zh-scim-tables
1. /usr/port/www/firefox3
1. /usr/port/chinese/stardict
1. /usr/port/net/rdesktop


只是在安装xfce4时出现了点问题: xfce4需要使用到perl的几个模块, 但是使用cpan安装这几个包是时, 总是在test阶段过不了. 一气之下, 使用force去强制安装. 结果包是安装上了, 不良后果还没有出现. 问题的解决方法还没有找到. 下次使用cpan碰到再解决.


这就FreeBSD的桌面环境起来了!(至少对我来说是这样)

还要增加的软件集为:
1. pidgin
1. QQ
1. ??(暂时还想不出来)

呃..... 好像我只使用这几个软件呢...... 看来是人Out了!!!!

ssh登陆时出错

例子如下:

当我ssh到某一台机器时, ssh会出现下面这种情况:

jessinio@jessinio-desktop:~$ ssh inter0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the DSA host key has just been changed.
The fingerprint for the DSA key sent by the remote host is
46:3c:fc:26:78:b7:e8:a2:4c:e4:ab:c5:65:11:43:e0.
Please contact your system administrator.
Add correct host key in /home/jessinio/.ssh/known_hosts to get rid of this message.
Offending key in /home/jessinio/.ssh/known_hosts:52
DSA host key for inter0 has changed and you have requested strict checking.
Host key verification failed.

这种事常常会发生,特别是SA.
平时我的解决方法是rm ~/.ssh/known_hosts

不过, 这样有个问题:以前登陆过的机器在ssh登陆时,都会出现:
Are you sure you want to continue connecting (yes/no)?

有点烦!

今天细看了一下上面的ssh抛出的信息(平时我都没有细看过 囧!! ):
Offending key in /home/jessinio/.ssh/known_hosts:52

结果把~/.ssh/known_hosts的第52行delete后, 一切OK

Sunday, February 8, 2009

freeBSD下mount光驱

记录此事, 是因为在FreeBSD工作中, 发现FreeBSD下的光驱与linux的dev不一样.

linux下是/dev/cdrom, 但是在FreeBSD下一时找不得对应功能的dev设备.

google了一把, 发现了比较有意思的mount命令使用方法:

# mount /cdrom

这就是freeBSD方便mount上cdrom的方法.这是怎么做到的呢?

答案是: 得用/etc/fstab

看一下机器的fstab:
/dev/acd0 /cdrom cd9660 ro,noauto 0 0

这样, 在mount命令后加一个path, mount就会去找/etc/fstab对应的dev和mountpoint了.

这等同于:
# mount_cd9660 /dev/acd0 /cdrom
也同于:
# mount -t iso9660 /dev/acd0 /cdrom


BTW:

1. FreeBSD下的光驱dev为acd
2. mount -a 也是利用/etc/fstab