cryptDB安装分析
cryptDB的安装脚步是用ruby语言写的,由于这里对ruby语言不熟悉,只能做简答的分析。我们先看看cryptDB的目录结构。
主要的目录有bins、doc、main、udf目录,下面我们通过分析其安装脚步来看cryptDB到底干了什么。
一、安装
在script目录下有个install.rb文件,cryptDB是通过该文件进行安装的,在安装时执行以下命令即可(注意cryptDB是安装的Ubutun13.0.4上的)
- install.rb cryptDB的路径名
#!/usr/bin/env ruby require 'etc' require 'fileutils' $usage = "Usage: ./install <path-to-cryptdb> [automake-version] [gcc-version]" SHADOW_NAME = "shadow" PROXY_NAME = "proxy-src" MYSQL_NAME = "mysql-src" TAR_GZ = ".tar.gz" class String def cyan "\033[36m#{self}\033[0m" end def red "\033[31m#{self}\033[0m" end def bold "\033[1m#{self}\033[22m" end end # NOTE: For whatever reason we fail to get the correct exit code when # apt-get fails; and execution continues per-normal. def get_pkgs p_puts "Retrieving packages..." pkg_shell = ShellDoer.new("~") pkg_shell.>(%q{ sudo apt-get install gawk liblua5.1-0-dev libntl-dev \ libmysqlclient-dev libssl-dev libbsd-dev \ libevent-dev libglib2.0-dev libgmp-dev \ mysql-server libaio-dev automake \ gtk-doc-tools flex cmake libncurses5-dev \ bison g++ make }) end def fn(cdb_path, in_make_v=nil, in_gcc_v=nil) cryptdb_path = File.expand_path(cdb_path) cryptdb_shell = ShellDoer.new(cryptdb_path) bins_path = File.join(cryptdb_path, "bins/") ############################# # mysql-proxy # ########################### # + automake fixups. p_puts "Checking automake..." automake_version = if in_make_v in_make_v else first_line_version(%x(automake --version)) end if automake_version.nil? fail no_version_fail("automake") end p_puts "Building mysql-proxy..." # untar proxy_path = File.join(cryptdb_path, PROXY_NAME) proxy_tar_path = File.join(bins_path, PROXY_NAME) + TAR_GZ cryptdb_shell.>("rm -rf #{proxy_path}") cryptdb_shell.>("tar zxf #{proxy_tar_path}") mp_shell = ShellDoer.new(proxy_path) proxy_install_path = File.join(bins_path, "proxy-bin") mp_shell.>("./autogen.sh") mp_shell.>("./configure --enable-maintainer-mode --with-lua=lua5.1 --prefix=\"#{proxy_install_path}\"") mp_shell.>("make") mp_shell.>("make install") mp_shell.>("rm -rf #{proxy_path}") ############################# # gcc ############################# p_puts "Checking gcc..." gcc_version = if in_gcc_v in_gcc_v else first_line_version(%x(gcc --version)) end if gcc_version.nil? fail no_version_fail("gcc") end if Version.new(gcc_version) < Version.new("4.6") fail("update your gcc version to >= 4.6 before installing!") end ############################# # mysql ############################# p_puts "Building mysql..." # untar mysql_path = File.join(cryptdb_path, MYSQL_NAME) mysql_tar_path = File.join(bins_path, MYSQL_NAME) + TAR_GZ cryptdb_shell.>("rm -rf #{mysql_path}") cryptdb_shell.>("tar zxf #{mysql_tar_path}") mysql_build_path = File.join(mysql_path, "/build") Dir.mkdir(mysql_build_path) if false == File.exists?(mysql_build_path) mysql_shell = ShellDoer.new(mysql_build_path) mysql_shell.>("cmake -DWITH_EMBEDDED_SERVER=on -DENABLE_DTRACE=off ..") mysql_shell.>("make") ############################# # cryptdb ############################# p_puts "Building cryptdb..." conf_path = File.join(cryptdb_path, "conf", "config.mk") File.open(conf_path, 'w') do |file| file.write(generate_config(mysql_path)) end cryptdb_shell.>("make clean") cryptdb_shell.>("make") cryptdb_shell.>("service mysql stop", true) cryptdb_shell.>("make install") cryptdb_shell.>("service mysql start") shadow_path = File.join(cryptdb_path, SHADOW_NAME) cryptdb_shell.>("rm -rf #{shadow_path}") cryptdb_shell.>("mkdir #{shadow_path}") # Give the user access to all the stuff we created. cryptdb_shell.>("chown -R #{Etc.getlogin} #{cryptdb_path}") # remind the user about EDBDIR p_puts "You must do: export EDBDIR=/full/path/to/cryptdb/ before running cryptdb; we recommend putting it into your .bashrc" end class ShellDoer def initialize(dir) @dir = dir end def >(cmd, ignore=false) pretty_execute(cmd, ignore) end private def pretty_execute(cmd, ignore) %x(cd #{@dir} && #{cmd.strip} 1>&2) if $?.exitstatus != 0 && false == ignore fail "`#{cmd}` failed".red.bold end end end def no_version_fail(name) "unable to determine #{name} version, supply version # thru command line argument.\n#{$usage}\n" end def first_line_version(text) /([0-9]+\.[0-9]+(?:\.[0-9]+)?)/.match(text.split("\n").first)[0] end # > Version numbers must have at least 1 number. # > Only numbers and 'dot' are valid. class Version < Array def initialize(s) if s.empty? fail "empty strings are not version numbers!" end parsed = parse_version(s) if parsed.empty? fail "unable to parse '#{s}' as version number" end super(parsed) end def >=(v2) fail "versions only compare with versions" if !v2.is_a?(Version) m = [self.size, v2.size].max (pad(self, m) <=> pad(v2, m)) >= 0 end def <(v2) fail "versions only compare with versions" if !v2.is_a?(Version) m = [self.size, v2.size].max (pad(self, m) <=> pad(v2, m)) < 0 end private def pad(a, size) return a if size < a.size a + [0] * (size - a.size) end def parse_version(v) v.scan(/([0-9]+)\.?/).map(&:first).map(&:to_i) end end def p_puts(output_me) puts output_me.cyan.bold end def generate_config(mysql_path) ["MYSRC := #{mysql_path}", "MYBUILD := $(MYSRC)/build", "RPATH := 1", "", "## To enable debugging:", "# CXXFLAGS += -g", "", "## To use a different compiler:", "# CXX := g++-4.6", "", "## Where UDFs go:", "MYSQL_PLUGIN_DIR := /usr/lib/mysql/plugin"].join("\n") end def test_version pairs = [["1.1", "1.3"], ["1.5", "2.5"], ["1.12.2", "2.3"], ["5", "8.9"], ["1.0.0.1", "1.1"], ["3.4.5", "4.5.2"], ["2.0", "5.1.0.0"], ["0.1", "0.1.0.0.2"], ["0", "0.1"]] pairs.inject(true) do |acc, (low, high)| Version.new(low) < Version.new(high) && Version.new(high) >= Version.new(low) && acc end end def root? if 0 != Process.uid fail "root required to install dependencies and UDFs".red.bold end end ############################# ############################# # Execution Begins Here ############################# ############################# if ARGV.size() < 1 || ARGV.size() > 3 fail $usage end root?() get_pkgs() fn(ARGV[0], ARGV[1], ARGV[2]) #TODO: add restart of Mysql server after UDF updates
从注释中可以看出安装的顺序是mysql-proxy(这是一个mysql的代理软件,开源),gcc版本检查、mysql编译(这里不安装,因为需要用到其中的库)、最后是cryptdb的编译和安装。
二、mysql-proxy安装
mysql-proxy只是一个代理软件,而cryptDB是在该代理软件上做的开发,关于该代理软件可自行百度或google。从安装脚步中可以大概看出,通过我们传入的cryptDB的路径名来获取mysql-proxy.src.tar.gz位置,然后对其进行解压并安装到/full/path/to/cryptDB/bins/proxy-bin目录下
三、GCC版本检查
GCC的版本必须大于等于4.6
四、mysql的编译
mysql的源代码和mysql-proxy源代码都放在bins目录下,将mysql的源代码解压的/full/path/to/cryptdb/mysql-src/build下,然后执行make进行编译。
五、cryptdb编译
在编译cryptdb时,直接在其主目录下进行编译。/full/path/to/cryptdb/下执行make、service mysql stop、make install、service mysql start一些列命令就可以完成cryptDB的安装了。
六、运行
其实是在运行mysql-proxy代理软件,为我们的加密服务则在wrapper.lua文件中,关于mysql-proxy的简单使用可参考
http://www.cnblogs.com/itech/archive/2011/09/22/2185365.html