天狗文档Capistrano 入门.doc_第1页
天狗文档Capistrano 入门.doc_第2页
天狗文档Capistrano 入门.doc_第3页
天狗文档Capistrano 入门.doc_第4页
天狗文档Capistrano 入门.doc_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Capistrano是什么?它其实是一种部署工具。而部署又是什么?以 Web 应用而言,它是通用术语,包括如下所有任务。 在生产服务器上安装应用程序,或是更新为最新版本。 web服务器的启动、重启与停止。 使网站进入维护状态,或将其回复常态。 只要对外发布 Web 应用程序,这样的任务便如家常便饭一样稀松平常。刚开始是有点有趣,但归根到底还是乏味的工作。对于我们这群以懒惰为美德的程序员来说,当然不愿甘心于这种状况。因此,我想进行有关Capistrano方面的研究。(2008/03/24) 第1章 安装从现在起将介绍很多有关 Capistrano 的内容,开始之前让我们先设定几个前提条件吧。 本地机 OS 为 Ubuntu 7.10。 服务器 OS 为 CentOS 4.6。 部署的 Web 程序以 Ruby on Rails 2.0 编写。 数据库管理系统为 MySQL 。 前端 web 服务器为 Apache 2.2 。主要作为负载平衡器(反向代理)来使用。 Rails 应用程序在 Mongrel 1.1.4 上运行。 这些前提条件并不是说所有都需要。只不过是笔者现在使用的环境而已。如果本地机的 OS 是 Linux 或是 Mac OS X,按照这篇文章进行操作的话大体上也能顺利运行。在 Windows 中,需要注意以下几点。 输入时省略命令开头的 sudo 。 路径分隔符用 代替 / 。 现在我们开始 Capstrasno 的安装。目前(2008年5月)的最新版本是 2.3.0。Capistrano 是通过 Ruby 的软件包管理工具 RubyGames 来安装的。首先,请确认 RubyGames 的版本。% gem -version1.1.1用 Ruby on Rails 进行开发的话,我认为 RubyGems 是肯定要安装的。如果编号显示的是旧版本,请更新一下。% sudo gem update -system接下来,请检查是否已经安装好 Capistrano 。% gem list capistrano* LOCAL GEMS *像这样没有任何的显示、或是只显示出比 2.3.0 更旧的版本编号,便安装 Capistrano 。% sudo gem install capistranoPassword:Updating metadata for 92 gems from pleteSuccessfully installed net-ssh-2.0.1Successfully installed net-sftp-2.0.0Successfully installed net-scp-1.0.0Successfully installed net-ssh-gateway-1.0.0Successfully installed highline-1.4.0Successfully installed capistrano-2.3.06 gems installedInstalling ri documentation for net-ssh-2.0.1.Installing ri documentation for net-sftp-2.0.0.Installing ri documentation for net-scp-1.0.0.Installing ri documentation for net-ssh-gateway-1.0.0.Installing ri documentation for highline-1.4.0.Installing ri documentation for capistrano-2.3.0.Installing RDoc documentation for net-ssh-2.0.1.Installing RDoc documentation for net-sftp-2.0.0.Installing RDoc documentation for net-scp-1.0.0.Installing RDoc documentation for net-ssh-gateway-1.0.0.Installing RDoc documentation for highline-1.4.0.Installing RDoc documentation for capistrano-2.3.0.以防万一,用 cap 命令来检查 Capistrano 的版本。% cap -versionCapistrano v2.3.0OK。到目前为止一切顺利。修订2008/05/12 对 Capistrano2.3.0 进行修改。(2008/03/24) 第2章 SSH公钥的设置这一章将就使用 Capistrano 的前提条件之一的 SSH 公钥进行介绍。因为以已经配置好生产服务器为前提,所以现在应该可以通过 SSH 登陆到生产服务器。但是是否已在生产服务器上设置好了 SSH 公钥了呢。如果还没有的话,现在开始操作吧。另外,在 Windows 环境下 Capistrano 的安装方法将在下一章(第3章 Windows 环境下的 Capistrano)中说明。首先,创建一个SSH公钥。% ssh-keygenGenerating public/private rsa key pair.Enter file in which to save the key (/home/kuroda/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/kuroda/.ssh/id_rsa.Your public key has been saved in /home/kuroda/.ssh/id_rsa.pub.The key fingerprint is:a3:ed:8b:aa:6d:6c:92:16:70:6b:1d:51:3a:24:6f:b9 kurodadesktop接着,将此公钥复制到生产服务器上。生产服务器的域名设为 alpha.oiax.jp 。% scp .ssh/id_rsa.pub alpha.oiax.jp:kurodaalpha.oiax.jps password:登陆生产服务器。说一下,今后在本地主机上操作时的提示符为 % ,而在远程机上的提示符用 $ 表示。% ssh alpha.oiax.jpPassword:首先创建 app 用户。% sudo /usr/sbin/useradd -m app这是部署及运行 Rails 应用程序的专有用户。如果此用户名已被使用,则可以选择如 rails 等其它的名字。另外虽然也可以使用开发者个人的账户(如kuroda)来部署,但在多人开发的情况下,容易牵涉到文件权限的问题,因此建议设立专用的用户。首先,在 /.ssh 设公钥。$ mkdir -m 700 .ssh$ cat id_rsa.pub .ssh/authorized_keys接下来在 /home/app/.ssh 设公钥。$ sudo -u app mkdir -m 700 /home/app/.ssh$ sudo -u app touch /home/app/.ssh/authorized_keys$ sudo sh -c cat id_rsa.pub /home/app/.ssh/authorized_keys退出。$ exit想省去反复输入路径短语这个麻烦的人可在 ssh-agent 设置密钥。% ssh-agent bash% ssh-addEnter passphrase for /home/kuroda/.ssh/id_rsa: Identity added: /home/kuroda/.ssh/id_rsa (/home/kuroda/.ssh/id_rsa)使用公钥登陆到生产服务器。% ssh alpha.oiax.jp$ exit登录时没被要求密码的话就OK了。接下来,用 app 用户登录。% ssh appalpha.oiax.jp$ exit这里应该不用输入密码也可以登陆。那么,让我们来试试 Capistrano 吧。在本地主机适当的目录下,创建一个包含下列内容的文本文件 Capfile 。不添加扩展名。另外,用 kuroda 指定远程主机上使用 SSH 登录的用户名,并且使用远程主机的实际名称置换 alpha.oiax.jp。set :user, kurodatask :stamp, :hosts = alpha.oiax.jp do run touch /home/kuroda/touchedend至此,便登陆到 alpha.oiax.jp 并定义了执行 touch /home/kuroda/touched 命令的任务 stamp 。Unix 命令的 touch 是为了更新文件的时间戳,如果没有文件的话请创建一个。为了执行 stamp 任务,进入保存 Capfile 的目录,输入 cap stamp 。% cap stamp * executing stamp * executing touch /home/kuroda/touched servers: alpha.oiax.jp alpha.oiax.jp executing command command finished在生产服务器上确认结果。$ pwd/home/kuroda$ la -l touched-rw-r-r- 1 kuroda kuroda 5 Mar 24 22:58 touched在执行 stamp 任务之前所不存在的 touched 文件产生了。修订 2008/05/17 配合以用户 app 登录远程主机的方式,对文章进行修改。(2008/03/25) 第3章 Windows环境下的 Capistrano在上章SSH SSH 公钥的设置中已经介绍了在 Linux 和 Mac OS X 环境下,使用 Capistrano 的准备工作。这章介绍Windows环境下的工作。Capistrano 是使用 Ruby 的 Net:SSH 模块登陆远程服务器的。因此,ssh 的客户端程序基本上是不必要的。在你电脑上的适当文件夹下创建一个如下内容的 Capfile 文件。task :stamp, :hosts = alpha.oiax.jp do run touch /home/kuroda/touchedend然后执行 stamp 任务。% cap stamp * executing stamp * executing touch /home/kuroda/touchedPassword: servers: alpha.oiax.jp alpha.oiax.jp executing command command finished在此过程中,除了被要求密码外,与之前都相同。在 windows 中,为了通过密钥实现 SSH 登陆,就要利用叫做 PuTTY 的免费软件。从 PuTTY Download Page 上下载 putty-x.xx-installer.exe 并安装。首先,运行 puttygen 程序,创建 SSH 公钥,保存密钥,在远程服务器的 authorized_keys 文件中添加公钥。详细请参照 PuTTYgen 的利用 。另外,不要忘记在文件 /home/app/.ssh/authorized_keys 上也添加公钥。接下来启动 pageant 程序。这是一个常驻程序,启动后会在任务托盘里显示成一个戴着帽子的电脑的图标。双击该图标,将打开一个窗口“Pageant Key List”, 点击“Add Key”,选择刚刚保存下的密钥文件,将密钥注册到 pageant。Windows 启动以后,只要事先进行过此步操作,则在执行 Capistrano 时不输入密码也可以。% cap stamp * executing stamp * executing touch /home/kuroda/touched servers: alpha.oiax.jp alpha.oiax.jp executing command command finished修订 2008/05/17 配合以用户 app 登录远程主机的方式,对文章进行修改。(2008/03/26) 第4章 capify这章介绍部署Rails应用程序所作的准备。下面,把你的 Rails 程序命名为 ballad 。还有,用 alpha.oiax.jp 作为生产服务器的主机名称,以 /var/rails/ballad/ 作为部署目录。Subversion 库的URL 是 https:/repository.oiax.jp/svn/ballad/trunk。注意一下,这里使用的主机名称、URL等,都是虚拟的。进入 ballad 应用程序的根目录,输入命令 capify . 。% capify .add writing ./Capfileadd writing ./config/deploy.rbdone capified!在生成的文件中,有一个 Capfile 的内容如下,这个文件基本上不改。load deploy if respond_to?(:namespace) # cap2 differentiatorDirvendor/plugins/*/recipes/*.rb.each |plugin| load(plugin) load config/deploy在 config 目录中生成的 deploy.rb 文件的初始状态如下:set :application, set your application name hereset :repository, set your repository location here# If you arent deploying to /u/apps/#application on the target# servers (which is the default), you can specify the actual location# via the :deploy_to variable:# set :deploy_to, /var/www/#application# If you arent using Subversion to manage your source code, specify# your SCM below:# set :scm, :subversionrole :app, your app-server hererole :web, your web-server hererole :db, your db-server here, :primary = true更换如下。set :application, balladset :repository, https:/repository.oiax.jp/svn/ballad/trunkset :deploy_to, /var/rails/#applicationset :user, appset :use_sudo, falserole :app, alpha.oiax.jprole :web, alpha.oiax.jprole :db, alpha.oiax.jp, :primary = true通过 set :user, app ,将远程主机上使用 SSH 登录的用户设定为 app 。在使用其它的用户(例如rails)的情况下,将其更换。下一行的 set :use_sudo, false ,是限定运行 Rails 应用程序时是否使用 sudo 的变量。比如我是通过 app 用户运行的,所以设定false 。修订 2008/05/17 配合以用户 app 登录远程主机的方式,对文章进行修改。(2008/03/27) 第5章 目标主机的准备这章主要介绍部署的计算机服务器的(目标主机)的安装。也许有人认为在目标主机上没有安装 Capistrano 的必要,这显然是一个误会。Capistrano 是一种能够自动执行各种指令的工具,它能在你的电脑也就是本地主机上运行,能使用Ruby 的 Net:SSH 模块功能,还能登陆目标主机。那么,通过 SSH 登录目标主机(alpha.oiax.jp),开始操作吧。首先,创建放置 Rails 应用程序的 /var/rails 目录。$ sudo mkdir /var/rails$ sudo chown app:app /var/rails退出目标主机。$ exit执行 deploy:setup 任务。(省略了显示的一部分)% cap deploy:setup * executing deploy:setup * executing umask 02 & mkdir -p /var/rails/ballad /var/rails/ballad/releases . servers: alpha.oiax.jp alpha.oiax.jp executing command command finished这个命令是指在目标主机上创建一个部署目录,在部署目录下面进一步创建文件夹分枝。这项操作在每一个应用程序进行一次即可。那么,登陆目标主机,执行 find 命令显示目录树,这次的操作就完成了。$ find /var/rails/var/rails/var/rails/ballad/var/rails/ballad/shared/var/rails/ballad/shared/log/var/rails/ballad/shared/pids/var/rails/ballad/shared/system/var/rails/ballad/releases修订 2008/05/17 将“生成应用程序执行专用用户 app ”的内容,移至第2章 SSH 公钥的设置。修订 2008/05/12 完成执行应用程序的专用用户 app 。(2008/03/28) 第6章 deploy:update这章将在目标主机上配置源代码。在本地主机执行 deploy:update 任务(省略一部分显示)% cap deploy:update * executing deploy:update * transaction: start * executing deploy:update_code. * transaction: commit但是,通常情况下这种方式是不怎么行得通的。首先,如果必须通过用户名和密码从 Subversion 库获取源代码的话,就显示如下。% cap deploy:update * executing deploy:update * transaction: start * executing deploy:update_code * executing svn checkout -q -r21 https:/repository.oiax.jp/svn/ballad/trunk . servers: alpha.oiax.jp alpha.oiax.jp executing command * err Authentication realm: repository.oiax.jp * Password for app:Password: 与目标主机登陆名(app)一样的用户可以检索 Subversion 库,而且,如果所有进行部署操作的开发人员都知道密码的话,直接在这里输入就可以了。但是实际上应该避免开发者之间共用密码。因此,像下面一样改写 deploy.rb :set :application, balladset :svn_user, ENVsvn_user | ENVUSERset :svn_password, Proc.new Capistrano:CLI.password_prompt(SVN Password: ) set :repository, Proc.new -username #svn_user + -password #svn_password + -no-auth-cache + https:/repository.oiax.jp/svn/ballad/trunk/ set :deploy_to, /var/rails/#applicationset :user, appset :use_sudo, falserole :app, alpha.oiax.jprole :web, alpha.oiax.jprole :db, alpha.oiax.jp, :primary = true像这样执行 deploy:update 任务(Subversion 的用户名设为 kuroda)。% svn_user=kuroda cap deploy:update这个方法还是有一点问题。进程中会在命令提示符 SVN Password: 输入密码,但是这样 svn 命令会反映在画面中,密码就会被看见。这样的话,在和其它成员共同开发时就会很麻烦。但是,如果养成了添加 -q 选项来执行任务的习惯的话,这个问题就可以避免了。% svn_user=kuroda cap -q deploy:update可是,也有可能因为一些原因导致命令在目标主机上的执行遭遇失败而中止。从显示在终端的文字中查找 * executing . 这个形式的最后一行,并复制包含在双引号内的指令,在目标主机上执行以查找原因。修正 2008/05/17 配合以用户 app 登录远程主机的方式,对文章进行修改。(2008/03/29) 第7章 Rails应用程序的启动、停止、重启这章介绍Rails应用程序的启动、停止、重启。在第1章 安装提到的,在 Mongrel 1.1.4 上运行 Rails 应用程序是这篇文章的前提条件。首先,确认在目标主机上安装的 RubyGems 版本。$ gem -version1.1.1如果没有安装 RubyGems 的话,就从 RybyForge 下载最新版并安装。$ wget /frs/download.php/35283/rubygems-1.1.1.tgz$ tar xzf rubygems-1.1.1.tgz$ cd rubygems-1.1.1$ sudo ruby setup.rb如果是旧版本的话请更新。$ sudo gem update -system接下来确认 Mongrel 的版本。$ gem list mongrel* LOCAL GEMS *mongrel (1.1.4)mongrel_cluster (1.0.5)如果什么都没有显示或是显示的是 Mongrel 旧版本的话,进行安装。$ sudo gem install mongrel同样也安装 mongrel_cluster 。$ sudo gem install mongrel_cluster设置生产环境用的 database.yml (代码样本省略)。$ cd /var/rails/ballad/shared$ sudo -u app mkdir config$ sudo -u app vi config/database.yml设置spin 脚本。$ sudo -u app mkdir script$ sudo -u app vi script/spinspin 脚本的内容如下:#!/bin/sh/var/rails/ballad/current/script/process/spawner -p 3000 -i 4-p 选项指定端口号,-i 选项指定 mongrel 实例数。在上述例中、使用3000到3003的端口号,运行了4个 mongrel 实例。还有,虽然通过-e 选项能指定“执行环境(development|test|production)”,但是因为默认 production ,通常不必指定也可以。返回本地主机,在 config/deploy.rb 添加以下内容:desc Copy shared config files to current application.task :after_update_code, :roles = :app do run cp -f #shared_path/config/database.yml #release_path/config/ run cp -f #shared_path/script/spin #release_path/script/ run chmod u+x #release_path/script/spinend这个 after_update_code 任务,会在执行 update_code 任务后自动执行。它指把 database.yml 和spin 复制到正确的目录,并给予 spin 脚本运行权限。那尝试执行 deploy:update 任务。在 /var/rails/ballad/current/script 目录中如果生成了 spin 文件就 OK 了。其次,建立数据库。但是先需要完成数据库管理系统的安装。首先,登陆远程主机并创建数据库:$ rake db:create RAILS_ENV=production然后迁移。通常执行 rake db:migrate RAILS_ENV=production 也可以,但在这里我们还是从本地主机通过 Capistrano 执行:% cap deploy:migrate到这里准备完成。可以启动Rails应用程序。% cap deploy:start * executing deploy:start * executing sh -c cd /var/rails/ballad/current & nohup script/spin servers: alpha.oiax.jp alpha.oiax.jp executing command * out : alpha.oiax.jp = Starting mongrel dispatchers * out : alpha.oiax.jp Checking if something is already running on :3000.NO * out : alpha.oiax.jp Starting dispatcher on port: :3000 * out : alpha.oiax.jp Checking if something is already running on :3001.NO * out : alpha.oiax.jp Starting dispatcher on port: :3001 * out : alpha.oiax.jp Checking if something is already running on :3002.NO * out : alpha.oiax.jp Starting dispatcher on port: :3002 * out : alpha.oiax.jp Checking if something is already running on :3003.NO * out : alpha.oiax.jp Starting dispatcher on port: :3003 command finished将 deploy:start 换为 deploy:stop 的话就中止,换成 deploy:restart 的话就重新启动。说一下,一旦开始程序运用,不伴随迁移的小修改会反复进行,所以将 deploy:update 任务和 deploy:restart 任务结合使用的次数会变多。因此要准备好 deploy 任务以顺利运行这两个任务。这样一来加上在应用程序上的修改,只在本地主机输入以下指令,进行一次更新源代码和重启程序的操作就行:% cap deploy设定变量 svn_user 的情况如下。% svn_user=kuroda cap -q deploy(2008/05/17) 第8章 deploy:rollback 与 deploy:cleanup这章是关于 deploy:rollback 任务和 deploy:cleanup 任务的介绍。执行 deploy:update 任务时,Capistrano 能从 Subversion 等库中获取源代码,详细地查看的话,还有很多东西。 在 releases 目录下创建一个基于当前时刻,以 YYmmddHHMMSS 为形式的子目录,在那里可获取最新的源代码。 在子目录创建一个到目录 shared/log 的符号链接。 创建一个从 current 目录到子目录的符号链接。 总之,Capistrano 能取得以前获取过的源代码,并根据符号链接的改建运行最新版。deploy:rollback 这个任务的作用是返回前一个源代码并重启应用程序。具体来说就是将 current 目录的连接地址替换为获取了前一个源代码的目录,删除最新源代码,执行 deploy:restart 任务。这是在应用程序刚开始部署的情况下发现重大错误,希望立即返回原始状态的任务。 * executing deploy:rollback * executing deploy:rollback_code * executing ls -x /var/rails/ballad/releases servers: alpha.oiax.jp alpha.oiax.jp executing command command finished * executing rm /var/rails/ballad/current; ln -s /var/rails/ballad/releases/20080517010640/var/rails/ballad/current & rm -rf /var/rails/ballad/releases/20080518014637 servers: alpha.oiax.jp alpha.oiax.jp executing command command finished * executing deploy:restart * executing /var/rails/ballad/current/script/process/reaper servers: alpha.oiax.jp alpha.oiax.jp executing command * out : alpha.oiax.jp Restarting 17952 * out : alpha.oiax.jp Restarting 17962 * out : alpha.oiax.jp Restarting 17964 * out : alpha.oiax.jp Restarting 17960 command finished另外,反复执行 deploy:update 任务的话,会在目标主机上堆积旧的源代码。因为浪费磁盘空间,所以希望留下几代,剩下的都从最新版清除。这种时候,执行 deploy:cleanup 任务。默认情况下将清除 5 代左右的源代码。需要留下的代数可由 keep_releases 变量控制,所以在 config/deploy.rb 作如下书写的话,大概留下 3 代的源代码。set :keep_releases, 3执行实例: * executing deploy:cleanup * executing ls -x /var/rails/ballad/releases servers: alpha.oiax.jp alpha.oiax.jp executing command command finished * keeping 3 of 5 deployed releases * executing rm -rf /var/rails/ballad/releases/20080512155340/var/rails/ballad/releases/20080513092114 servers: alpha.oiax.jp alpha.oiax.jp executing command command finished(2008/05/18) 第9章 切换至维护页面此章对 Capistrano 的 deploy:web:disable 和 deploy:web:enable 任务进行说明根据 cap -T 表示的说明,各种任务的目的如下: deploy:web:disable - 使访问者看到维护页面。 deploy:web:enable - 可以再次通过web搜索应用程序。 嗯,看起来似乎很便利,但是接下来会变成什么却毫无头绪。让我们来看看源代码(省略一部分)。namespace :deploy do namespace :web do task :disable, :roles = :web, :except = :no_release = true do require erb on_rollback run rm #shared_path/system/maintenance.html reason = ENVREASON deadline = ENVUNTIL template = File.read(File.join(File.dirname(_FILE_), templates, maintenance.rhtml) result = ERB.new(template).result(binding) put result, #shared_path/system/maintenance.html, :mode = 0644 end task :enable, :roles = :web, :except = :no_release = true do run rm #shared_path/system/maintenance.html end endenddeploy:web:disable 任务的内容,一句话,就是用 ERB 生成希望作为维护页面显示的 HTML 文件,并把这个写入 #shared_path/system/maintenance.html 文件。作为维护页面的模板 maintenance.rhtml 已存在。因为 File.dirname(_FILE_) 是这个源代码的某个目录,便成了 Capistrano 的安装目录(根据环境不同,/usr/lib/ruby/gems/1.8/gems/capistrano-2.3.0/等等)下的lib/capistrano/recipes/templates/maintenance.rhtml 。因为还没有指定模板的变量,所以想准备好单独的维护页面的话(这个当然是想准备的),参考此代码,自己写任务,添加至 config/deploy.rb 。然后,deploy:web:enable 任务删除这个文件。通常,shared_path 是变量 :deploy_to 指定目录下的 shared 目录。也就是说,在 /var/rails/ballad 部署的话,/var/rails/ballad/shared/system/maintenance.html 这个文件便会有问题。这个文件如果存在的话,可以只凭这个让访问者看到维护页面这样的话说起来很简单,其实并非如此。还有必要同 Apache 的 mod_rewrite 指令进行一些斗争。我看见 mod_rewrite 就会变得有些郁闷。mod_rewrite 是瑞士军刀,也是黑魔术(voodoo)(Apache module mod_rewrite)。它能够灵活的进行任何设定,这种奇妙的语法真让我着迷。好啦。不管怎样,在 httpd.conf 做如下输入的话,deploy:web:disable 任务便可执行了。 ServerName DocumentRoot /var/rails/ballad/current/public ErrorLog /var/log/httpd/ballad-error_log CustomLog /var/log/httpd/ballad-access_log combined env=!nolog Order Deny,Allow Allow from All RewriteEngine On RewriteCond %DOCUMENT_ROOT/system/maintenance.html -f RewriteCond %REQUEST_URI !/images/ RewriteCond %REQUEST_URI !/javascripts/ RewriteCond %REQUEST_URI !/stylesheets/ RewriteRule .*$ /system/maintenance.html L RewriteRule /(images|javascripts|stylesheets)/(.*)$ /$1/$2 L ProxyRequests Off ProxyPass / balancer:/ballad_cluster/ BalancerMember :3000 BalancerMember :3001 BalancerMember :3002 Bal

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论