diff --git a/addons/testbed/kabootstrap b/addons/testbed/kabootstrap index 83cb33dde9273a7694b85e7c712240c21cb2170b..cc7e12999b70332392dc11225dbc39290bc3af97 100755 --- a/addons/testbed/kabootstrap +++ b/addons/testbed/kabootstrap @@ -27,7 +27,7 @@ DEB_REPOSITORY = 'http://apt.grid5000.fr/kadeploy' GIT_REPOSITORY = 'https://gforge.inria.fr/git/kadeploy3/kadeploy3.git' GERRIT_REPOSITORY = 'http://gerrit.nancy.grid5000.fr:8080/gerrit/kadeploy3' DEPENDANCIES = ['libmysql-ruby','ruby'] -BUILD_DEPENDANCIES = ['git'] +BUILD_DEPENDANCIES = ['git','help2man','rake'] if g5k? G5K_API = 'https://api.grid5000.fr/2.0' @@ -158,6 +158,51 @@ CFG_KADEPLOY_TEST_VLAN_PATH="#{CFG_KADEPLOY_TEST_PATH}-vlan" CFG_KADEPLOY_TEST_HOOK_PATH="#{CFG_KADEPLOY_TEST_PATH}-hook" +#This class keep the connexion of servers to reuse after. +class LazyConnexion + def initialize() + @connexions = {} + @servername = {} + @proxy = Net::SSH::Gateway.new(getgw(), ENV['USER'], :keys => $sshkeyfile) + @tunnels = {} + end + #Establish all connexion on each node in parallel. + def prefetch_connexion(nodes) + raise "to be implemented" + end + def ssh(servername,user = ENV['USER'],proxy=true) + id_con="#{user}@#{servername}" + if !@connexions[id_con] + if proxy + @connexions[id_con] = @proxy.ssh(servername,user) + else + @connexions[id_con] = Net::SSH.start(servername, user, :keys => $sshkeyfile) + end + end + yield @connexions[id_con] + end + def self.http_tunnel(server,session,verbose) + $tunnels[server] = {} if !$tunnels[server] + if !$tunnels[server][session] + http_tunnel_create(server,session,verbose) + $tunnels[server][session]=true + end + end + + def close() + $tunnels.each_pair do |server_name,sessions| + sessions.each_key do |session| + http_tunnel_drop(server_name,session) + end + end + $tunnels.clear + @connexions.each_value do |session| + session.close() + end + @connexions.clear() + end +end + def cfg_console_baudrate(cluster=nil) cluster = {:basename=>'unknown'} if !cluster case cluster[:basename] @@ -415,10 +460,10 @@ def cfg_kadeploy_conf() 'windows' => { 'reboot' => { 'sleep_time' => 15, - 'size' => 100, + 'size' => 80, }, 'check' => { - 'size' => 200, + 'size' => 100, }, }, 'environments' => { @@ -523,9 +568,9 @@ def cfg_kadeploy_conf() "log_to_db = true\n"\ "dbg_to_syslog = true\n"\ "dbg_to_syslog_level = 3\n"\ - "reboot_window = 100\n"\ + "reboot_window = 80\n"\ "reboot_window_sleep_time = 15\n"\ - "nodes_check_window = 200\n"\ + "nodes_check_window = 100\n"\ "bootloader = chainload_pxe\n"\ "purge_deployment_timer = 900\n"\ "rambin_path = /rambin\n"\ @@ -656,7 +701,7 @@ def forge_ssh_cmd_frontend(cmd) end def cfg_kadeploy_kapower_cmd(cmd) - forge_ssh_cmd_frontend("kapower3 -m `cat #{File.join(CFG_KADEPLOY_HOSTNAMES_PATH,'HOSTNAME_FQDN')}` #{cmd}") + forge_ssh_cmd_frontend("kapower3 -m `cat #{File.join(CFG_KADEPLOY_HOSTNAMES_PATH,'HOSTNAME_FQDN')}` -l hard #{cmd} --force") end def cfg_kadeploy_kaconsole_cmd() @@ -793,7 +838,7 @@ end def cfg_kadeploy_soft_reboot_cmd() ret = '' if CFG_KADEPLOY_SOFT_REBOOT - ret = "ssh -q #{SSH_OPTIONS} -o BatchMode=yes -i #{CFG_KADEPLOY_SSHKEY_DEFAULT} root@HOSTNAME_FQDN \"nohup /sbin/reboot -f &>/dev/null &\"" + ret = "ssh -q #{SSH_OPTIONS} -o BatchMode=yes -i #{CFG_KADEPLOY_SSHKEY_DEFAULT} root@HOSTNAME_FQDN \"nohup /sbin/reboot &>/dev/null </dev/null &\"" else ret = "#{cfg_kadeploy_reboot_cmd()}" end @@ -806,8 +851,8 @@ end def cfg_kadeploy_deploy_kernel_args(cluster) more = case cluster[:basename] - when 'graphite' then ' igb.blacklist=yes' - when 'griffon' then ' myri10ge.blacklist=yes' + when 'graphite' then ' igb.blacklist=yes modprobe.blacklist=igb' + when 'griffon' then ' myri10ge.blacklist=yes modprobe.blacklist=myri10ge hpet=disable' else '' end #"#{USE_NET_DRIVER ? "ETH_DRV=#{cluster[:drivers][:network]} " : ''}"\ @@ -1531,7 +1576,9 @@ $configs = {} $tunnels = true $git = false $gerrit = false -$version = 7 +$version = 8 +$tunnels = {} +$updated = {} options = {} @@ -1701,17 +1748,17 @@ def ssh_tunnel_create(session,dstport,dsthost,srcport=nil,srchost=nil) sexec(session,"kill #{tmp.chomp.split[1]}") time_start = Time.now begin + sleep(0.1) tmp = sexec(session,"lsof -i4 -n | grep LISTEN | grep 127.0.0.1:#{srcport}",false,false)[0] sexec(session,"kill -9 #{tmp.chomp.split[1]}") if (Time.now - time_start) > SSH_TUNNEL_TIMEOUT msg("Killing process that listen on #{srchost}:#{srcport} failed",MSG_ERROR,true) if Time.now - time_start > SSH_TUNNEL_TIMEOUT - sleep(0.1) end until !tmp or tmp.empty? end $stunnels["#{srchost}:#{srcport}"] = {} $stunnels["#{srchost}:#{srcport}"][:dsthost] = dsthost $stunnels["#{srchost}:#{srcport}"][:dstport] = dstport - #$stunnels["#{srchost}:#{srcport}"][:thread] = Thread.new do + #$stunnels["#{srchost}:#{srcport}"][:thread] = Thread.new do #gwsession = Net::SSH::Gateway.new(kavlan_gw(), ENV['USER'], :keys => $sshkeyfile) #gwsession.ssh(kavlan_node($kaserver),'root') do |mysession| @@ -1721,8 +1768,8 @@ def ssh_tunnel_create(session,dstport,dsthost,srcport=nil,srchost=nil) # $stunnels["#{srchost}:#{srcport}"][:thread].run time_start = Time.now begin + sleep(0.2) tmp = sexec(session,"lsof -i4 -n | grep LISTEN | grep 127.0.0.1:#{srcport}",false,false)[0] - sleep(0.1) msg("SSH tunnel creation on #{srchost}:#{srcport} failed",MSG_ERROR,true) if Time.now - time_start > SSH_TUNNEL_TIMEOUT end while !tmp or tmp.empty? $stunnels["#{srchost}:#{srcport}"][:pid] = tmp.split[1] @@ -1826,7 +1873,11 @@ def apt_cmd(session,shcmd,aptcmd,aptopts,server=nil,params='') end def apt_update(session,server=nil) - apt_cmd(session,'apt-get','update',['q'],server) + if !$updated[session] + msg('Updating debian packages list',MSG_INFO) + $updated[session] = true + apt_cmd(session,'apt-get','update',['q'],server) + end end def apt_install(session,packages,server=nil) @@ -1962,8 +2013,27 @@ def tempfile(content) tmp.unlink end +def http_tunnel_drop(host,session,verbose=true) + if $tunnels + host = host[:basename] if host.is_a?(Hash) + case $mode + when :KAVLAN, :VLANKVM + msg('Destroying HTTP proxy SSH tunnel',MSG_INFO) if verbose + ssh_tunnel_destroy(session,3128,getnode(host)) + when :KVM -def http_tunnel(host,session, verbose=true) + msg('Destroying HTTP proxy SSH tunnel',MSG_INFO) if verbose + sexec(session,'route del default') + sexec(session,"route add default gw #{gateway} dev #{iface}") if gateway + else + msg('Unknown mode',MSG_ERROR,true) + end + else + yield + end +end + +def http_tunnel_create(host,session, verbose=true) if $tunnels host = host[:basename] if host.is_a?(Hash) case $mode @@ -1971,10 +2041,6 @@ def http_tunnel(host,session, verbose=true) msg('Creating HTTP proxy SSH tunnel',MSG_INFO) if verbose ssh_tunnel_create(session,HTTP_PROXY_PORT,HTTP_PROXY_ADDR) - yield - - msg('Destroying HTTP proxy SSH tunnel',MSG_INFO) if verbose - ssh_tunnel_destroy(session,3128,getnode(host)) when :KVM msg('Creating HTTP proxy SSH tunnel',MSG_INFO) if verbose tmp = sexec(session,'route -n') @@ -1995,11 +2061,6 @@ def http_tunnel(host,session, verbose=true) sexec(session,'route del default') if gateway sexec(session,"route add default gw #{$network[:gateway]}") - yield - - msg('Destroying HTTP proxy SSH tunnel',MSG_INFO) if verbose - sexec(session,'route del default') - sexec(session,"route add default gw #{gateway} dev #{iface}") if gateway else msg('Unknown mode',MSG_ERROR,true) end @@ -2008,6 +2069,14 @@ def http_tunnel(host,session, verbose=true) end end + + +def http_tunnel(host,session, verbose=true) + LazyConnexion.http_tunnel(host,session,verbose) + yield + #http_tunnel_drop(host,session, verbose) +end + def set_default_route(session) if $mode == :KVM tmp = sexec(session,'route -n') @@ -2105,6 +2174,7 @@ options[:dns_forward] = nil options[:dns_config] = nil options[:upload] = [] options[:sort] = true +options[:git_url] = GIT_REPOSITORY $debug = false $netiface = NET_ADMIN_IFACE @@ -2223,6 +2293,9 @@ optparse = OptionParser.new(USAGE) do |opts| opts.on( '-n', '--network-config <network_config_file>', 'The network configuration that be will used for the testbed. Need to be a YAML file with fields "network" and "subnetworks" (list of "name","address"). Subnetworks are only used to optimise services configuration, they are not created/routed. Address have to be in CIDR notation (default: the network hosts are currently in)' ) do |n| options[:network_config] = n end + opts.on('', '--rake-install', 'Uses rake install to install kadeploy') do + options[:rake_install] = true + end opts.on( '', '--no-tunnels', 'Disable SSH tunnels (VLAN connections should be routed)' ) do $tunnels = false @@ -2233,6 +2306,10 @@ optparse = OptionParser.new(USAGE) do |opts| $git = true end + opts.on('', '--git-url URL' ,"define the url of git repository (default is '#{options[:git_url]}').") do |c| + options[:git_url] = c + end + opts.on( '', '--gerrit <reference>', 'Install a gerrit snapshot of Kadeploy3' ) do |r| options[:gerrit] = r $gerrit = true @@ -2283,7 +2360,7 @@ end if options[:gateway] begin addr = IPAddr.new(options[:gateway]) - msg('gateway should be specified by hostname',MSG_ERROR,true) + msg('gatewat should be specified by hostname',MSG_ERROR,true) rescue ArgumentError end $gateway = options[:gateway] @@ -2423,6 +2500,7 @@ end msg("=== Globals",MSG_INFO) msg(" mode: #{$mode.to_s}",MSG_INFO) +msg(" version: #{$version}",MSG_INFO) msg(" sshkeyfile: #{$sshkeyfile}",MSG_INFO) msg(" updatefile: #{options[:update_file]}",MSG_INFO) if options[:update_file] @@ -3051,9 +3129,13 @@ $clusters.values.collect! do |v| msg(" net driver: #{v[:drivers][:network]}",MSG_INFO) msg(" disk driver: #{v[:drivers][:disk]}",MSG_INFO) end +def test_indent() + yield +end -Net::SSH.start(getgw(), ENV['USER'], :keys => $sshkeyfile) do |gwsession| -sshgw = Net::SSH::Gateway.new(getgw(), ENV['USER'], :keys => $sshkeyfile) +sshgw = LazyConnexion.new #Net::SSH::Gateway.new(getgw(), ENV['USER'], :keys => $sshkeyfile) +sshgw.ssh(getgw(),ENV['USER'],false) do |gwsession| +#Net::SSH.start(getgw(), ENV['USER'], :keys => $sshkeyfile) do |gwsession| begin pubkey = File.open("#{$sshkeyfile}.pub",'r').read @@ -3130,7 +3212,6 @@ sshgw.ssh(servername,'root') do |session| if $mode == :KAVLAN or $mode == :VLANKVM http_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) msg('Getting nodes IPv4/MAC addresses',MSG_INFO) @@ -3181,7 +3262,6 @@ select_server_type($kanodes,:dns).each do |server| set_arp_cache(session) http_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) msg('Installing DNS server',MSG_INFO) @@ -3271,7 +3351,6 @@ select_server_type($kanodes,:dhcp).each do |server| set_arp_cache(session) http_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) msg('Installing DHCP server',MSG_INFO) @@ -3331,7 +3410,6 @@ sshgw.ssh(servername,'root') do |session| msg("Connected to #{server[:basename]}",MSG_INFO) http_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) msg('Installing mySQL server',MSG_INFO) @@ -3367,7 +3445,6 @@ sshgw.ssh(servername,'root') do |session| msg("Connected to #{server[:basename]}",MSG_INFO) http_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) case $deploysendmeth @@ -3453,7 +3530,6 @@ sshgw.ssh(servername,'root') do |session| set_arp_cache(session) kadeploy_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) if options[:git] or options[:gerrit] @@ -3467,7 +3543,8 @@ sshgw.ssh(servername,'root') do |session| msg('Installing scm and build packages',MSG_INFO) build_extra = nil if $version >= 8 - build_extra = [ 'debhelper','gem2deb','help2man','rake','texlive-latex-base','texlive-latex-recommended','texlive-latex-extra','git-buildpackage' ] + build_extra = [ 'debhelper','gem2deb','git-buildpackage' ] + build_extra.concat(['texlive-latex-base','texlive-latex-recommended','texlive-latex-extra']) if !options[:rake_install] else build_extra = [ 'docbook2x' ] end @@ -3479,7 +3556,7 @@ sshgw.ssh(servername,'root') do |session| env_vars = 'http_proxy=http://localhost:3128 https_proxy=$http_proxy GIT_SSL_NO_VERIFY=1' if options[:git] msg("Cloning Kadeploy git repository",MSG_INFO) - sexec(session,"#{env_vars} git clone #{GIT_REPOSITORY} #{tmpdir}") + sexec(session,"#{env_vars} git clone #{options[:git_url]} #{tmpdir}") unless options[:git] == :master msg("Checkout git revision #{options[:git].to_s}",MSG_INFO) @@ -3517,11 +3594,17 @@ sshgw.ssh(servername,'root') do |session| sexec(session,"dpkg --force-all -i #{File.join(tmpdir,'*.deb')}") end else - msg("Building Kadeploy packages",MSG_INFO) - sexec(session,"cd #{tmpdir} && #{env_vars} rake deb 2>&1") + if options[:rake_install] + msg("Installing Kadeploy",MSG_INFO) + sexec(session,"cd #{tmpdir} && #{env_vars} rake install 2>&1") + else - msg('Installing Kadeploy server/client',MSG_INFO) - sexec(session,"cd #{tmpdir} && dpkg --force-all -i ../*.deb") + msg("Building Kadeploy packages",MSG_INFO) + sexec(session,"cd #{tmpdir} && #{env_vars} rake deb 2>&1") + + msg('Installing Kadeploy server/client',MSG_INFO) + sexec(session,"cd #{tmpdir} && dpkg --force-all -i ../*.deb") + end msg("Copying the deploy ssh key pair",MSG_INFO) sexec(session,"mkdir -p #{CFG_KADEPLOY_SSHKEY_PATH}") @@ -3532,13 +3615,22 @@ sshgw.ssh(servername,'root') do |session| sexec(session,"cp -f #{File.join(tmpdir,'scripts','**','*')} #{CFG_KADEPLOY_CONF_PATH}") msg("Copying kastafior",MSG_INFO) - sexec(session,"cp -f #{File.join(tmpdir,'addons','kastafior','kastafior')} #{CFG_KASTAFIOR_BIN_FILE}") - sexec(session,"chmod +x #{CFG_KASTAFIOR_BIN_FILE}") + + if options[:rake_install] + sexec(session,"cd #{tmpdir} && rake install_kastafior") + else + sexec(session,"cp -f #{File.join(tmpdir,'addons','kastafior','kastafior')} #{CFG_KASTAFIOR_BIN_FILE}") + sexec(session,"chmod +x #{CFG_KASTAFIOR_BIN_FILE}") + end if $version >= 8 msg("Copying kascade",MSG_INFO) - sexec(session,"cp -f #{File.join(tmpdir,'addons','kascade','kascade')} #{CFG_KASCADE_BIN_FILE}") - sexec(session,"chmod +x #{CFG_KASCADE_BIN_FILE}") + if options[:rake_install] + sexec(session,"cd #{tmpdir} && rake install_kascade") + else + sexec(session,"cp -f #{File.join(tmpdir,'addons','kascade','kascade')} #{CFG_KASCADE_BIN_FILE}") + sexec(session,"chmod +x #{CFG_KASCADE_BIN_FILE}") + end end end @@ -3828,7 +3920,6 @@ if $deploysendmeth == :HTTP msg("Connected to #{server[:basename]}",MSG_INFO) http_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) apt_update(session,server) msg('Installing HTTP server',MSG_INFO) apt_install(session,['apache2','apache2-mpm-worker'],server) @@ -3939,11 +4030,12 @@ sshgw.ssh(servername,'root') do |session| msg("Connected to #{server[:basename]}",MSG_INFO) kadeploy_tunnel(server,session) do - msg('Updating debian packages list',MSG_INFO) - apt_update(session,server) + if !options[:rake_install] + apt_update(session,server) - msg('Installing Kadeploy client',MSG_INFO) - apt_install(session,kapkg('client'),server) + msg('Installing Kadeploy client',MSG_INFO) + apt_install(session,kapkg('client'),server) + end msg('Configuring Kadeploy client',MSG_INFO) tempfile(cfg_kadeploy_client()) do |path| @@ -4021,6 +4113,7 @@ end msg("Disconnected from #{server[:basename]}\n",MSG_INFO) msg("",MSG_INFO) +sshgw.close() end msg("Installation done",MSG_INFO) diff --git a/bin/kadeploy3 b/bin/kadeploy3 index 284c4f31a32a743072dd1214ba74de70ca0e8eff..27d4b2fdd202f7f279afd7b8ea53a481d638fac9 100755 --- a/bin/kadeploy3 +++ b/bin/kadeploy3 @@ -145,13 +145,16 @@ class KadeployClient < ClientWorkflow env = nil case options[:env_kind] when :database - username = URI.encode_www_form_component(options[:env_user]) || '' + username = URI.encode_www_form_component(options[:env_user]) envname = URI.encode_www_form_component(options[:env_name]) - envversion = options[:env_version] || '' + envversion = options[:env_version] tmp = {} tmp[:last] = true unless options[:env_version] - envs = get2(options,api_path("/#{username}/#{envname}/#{envversion}",:envs),tmp) + tmp[:username] = username if username && !username.empty? + tmp[:name] = envname if envname && !envname.empty? + tmp[:version] = envversion if envversion + envs = get2(options,api_path("/",:envs),tmp) error("The environment '#{options[:env_name]}' does not exist") if envs.size <= 0 env = envs.first diff --git a/bin/kaenv3 b/bin/kaenv3 index ec3f1434ea212160481c88db7a6870a7c4e0d8d9..0fde4c2773b9b203d3f2309c74e5419c7a05790e 100755 --- a/bin/kaenv3 +++ b/bin/kaenv3 @@ -99,8 +99,9 @@ class KaenvsClient < Client options[:env_name] = n options[:operation] = :delete } - add_opt(opt,"-l", "--list", "List environments") { + add_opt(opt,"-l", "--list [ENVNAME]", "List environments with the environment name pattern (% is the wildcard).") { |n| options[:operation] = :list + options[:env_name] = n if n } add_opt(opt,"-m", "--files-to-move FILES", "Files to move (src1::dst1,src2::dst2,...)") { |f| if /\A.+::.+(,.+::.+)*\Z/ =~f then @@ -202,12 +203,15 @@ class KaenvsClient < Client when :'move-files' desc = options[:files_to_move].values else - username = URI.encode_www_form_component(options[:env_user]) || '' + username = URI.encode_www_form_component(options[:env_user]) envname = URI.encode_www_form_component(options[:env_name]) - envversion = options[:env_version] || '' + envversion = options[:env_version] tmp = params.dup tmp[:last] = true unless options[:env_version] - envs = get2(options,api_path("/#{username}/#{envname}/#{envversion}"),tmp) + tmp[:username] = username if username && !username.empty? + tmp[:name] = envname if envname && !envname.empty? + tmp[:version] = envversion if envversion && !envversion.empty? + envs = get2(options,api_path("/",:envs),tmp) error("The environment '#{envname}' does not exist") if envs.size <= 0 desc = envs.first end @@ -245,12 +249,15 @@ class KaenvsClient < Client if ![:add, :'move-files'].include?(options[:operation]) if [:print,:list].include?(options[:operation]) - path = File.join(path,"/#{URI.encode_www_form_component(options[:env_user]||'')}/") + if options[:env_user] && !options[:env_user].empty? + params[:username] = options[:env_user] + elsif options[:operation] == :print + params[:username] = USER + end + params[:version] = options[:env_version] if options[:env_version] + params[:name] = options[:env_name] if options[:env_name] && !options[:env_name].empty? else path = File.join(path,URI.encode_www_form_component(options[:env_user]||USER)) - end - - if options[:operation] != :list path = File.join(path,URI.encode_www_form_component(options[:env_name])) if options[:env_name] path = File.join(path,options[:env_version].to_s) if options[:env_version] end diff --git a/conf/version b/conf/version index 12607670e9f55d81a89815c7b24e17daec05b26b..d926efdbc88e056dcec598f182b12d2c8d85862a 100644 --- a/conf/version +++ b/conf/version @@ -1 +1 @@ -3.3.0.rc8 +3.3.0.stable diff --git a/doc/Kadeploy-3.3.0.rc8.pdf b/doc/Kadeploy-3.3.0.stable.pdf similarity index 69% rename from doc/Kadeploy-3.3.0.rc8.pdf rename to doc/Kadeploy-3.3.0.stable.pdf index 6dcf899a122351383df86a2f4742990545858d46..a50f16b0da051dadda610fa370b9694cacfc9a8b 100644 Binary files a/doc/Kadeploy-3.3.0.rc8.pdf and b/doc/Kadeploy-3.3.0.stable.pdf differ diff --git a/doc/Kadeploy.tex b/doc/Kadeploy.tex index b916d6a9507c27a54d54825166236d19140a81b5..5d3769f2dadd04fef19044c6ecb4f059f2872f27 100644 --- a/doc/Kadeploy.tex +++ b/doc/Kadeploy.tex @@ -32,7 +32,10 @@ KADEPLOY \version, CECILL 2.0 license, All rights reserved. This is the Kadeploy \version{} documentation file. \\ -It contains a short \nameref{chap:Overview} of Kadeploy, followed by the \nameref{chap:Installation} instructions, a description of the \nameref{chap:Server_side_conf} and the \nameref{chap:Client_side_conf} , to finish with the \nameref{chap:User_guide}. +It contains a short \nameref{chap:Overview} of Kadeploy, followed by the +\nameref{chap:Installation} instructions, a description of the +\nameref{chap:Server_side_conf} and the \nameref{chap:Client_side_conf} , to +finish with the \nameref{chap:User_guide}. \\ For a better understanding of how Kadeploy3 works see this publication:\\ @@ -59,10 +62,16 @@ reconfigure the software environment on the nodes. \section{How it works?} This is how Kadeploy works: \begin{enumerate} - \item \texttt{Minimal environment setup} - The nodes reboot into a trusted minimal environment that contains all the tools required for the deployment (partitioning tools, archive management,...) and the required partitioning is performed. - \item \texttt{Environment installation} - The environment is broadcast to all the nodes and extracted on the disks. Some post-installations operations can also be performed. + + \item \texttt{Minimal environment setup} The nodes reboot into a trusted + minimal environment that contains all the tools required for the deployment + (partitioning tools, archive management, \dots) and the required partitioning + is performed. + + \item \texttt{Environment installation} The environment is sent to all + the nodes and extracted on the disks. Some post-installations operations + can also be performed. + \item \texttt{Reboot on the deployed environment} \end{enumerate} @@ -74,7 +83,10 @@ the operating system's filesystem (as a tarball, for Linux environments). \section{How does Kadeploy control the boot of the nodes ?} -This is how Kadeploy controls the boot process of the nodes in order to be able to perform it's installation task: + +This is how Kadeploy controls the boot process of the nodes in order to be able +to perform the installation tasks: + \begin{enumerate} \item Kadeploy writes PXE profiles on a TFTP or HTTP server \item Kadeploy triggers the reboot of compute nodes using SSH, IPMI or a manageable PDU @@ -88,91 +100,148 @@ This is how Kadeploy controls the boot process of the nodes in order to be able \chapter{Installation}\label{chap:Installation} \section{Requirements} \subsection{Packages}\label{sec:required-packages} -Kadeploy requires the following softwares (the Debian packages available in the Lenny flavor are given): + +Kadeploy requires the following softwares (the given packages names are +valid for the Debian/Wheezy distribution): + \begin{itemize} -\item \texttt{ruby1.8} -\item \texttt{mysql-ruby1.8} -\item \texttt{bittorrent} -\item \texttt{ctorrent} -\item \texttt{taktuk >= 3.6} + \item \texttt{ruby >= 1.8.7} + \item \texttt{ruby-mysql} + \item \texttt{taktuk >= 3.6} + \item \texttt{isc-dhcp-server} + \item \texttt{syslinux} + \item \texttt{tftpd-hpa} \end{itemize} \subsection{DHCP and TFTP} \paragraph{The DHCP service\\} -A DHCP server (\texttt{isc-dhcp-server} on Debian for instance) must be configured to provide a static IP address to the set of nodes that must be deployed. Furthermore, the DHCP response must contains the hostname of the node (see the \texttt{use-host-decl-names on;} option in \texttt{dhcpd.conf}). -Here is an example of a configuration for GPXELinux: +A DHCP server (\texttt{isc-dhcp-server} on Debian for instance) must be +configured to provide a static IP address to the set of nodes that must be +deployed. Furthermore, the DHCP response must contain the hostname of the node +(see the \texttt{use-host-decl-names on;} option in \texttt{dhcpd.conf}). + +Here is an example of a configuration for PXELinux: \begin{verbatim} default-lease-time 28800; max-lease-time 86400; allow booting; allow bootp; - not-authoritative; - use-host-decl-names on; - subnet 192.168.208.0 netmask 255.255.240.0 { - option subnet-mask 255.255.240.0; - option broadcast-address 192.168.223.255; - option routers 192.168.223.254; - option domain-name "testbed.lan"; - option domain-name-servers 192.168.209.5; - if exists user-class and option user-class = "iPXE" { - filename=concat("http://192.168.209.5/",host-decl-name); - } else { - filename "gpxelinux.0"; - } - next-server 192.168.209.5; +subnet 192.168.0.0 netmask 255.255.255.0 { + option subnet-mask 255.255.255.0; + option broadcast-address 192.168.0.255; + option routers 192.168.0.254; + option domain-name "testbed.lan"; + filename "pxelinux.0"; + next-server 192.168.0.1; host node-1.testbed.lan { - hardware ethernet 00:e0:81:b2:c4:a0; - fixed-address 192.168.209.8; + hardware ethernet 00:09:3d:12:33:e6; + fixed-address 192.168.0.10; option host-name "node-1"; } - + host node-2.testbed.lan { + hardware ethernet 00:09:3d:12:33:e7; + fixed-address 192.168.0.11; + option host-name "node-2"; } +} \end{verbatim} -More information about the configuration of PXElinux can be found at \url{http://www.syslinux.org/wiki/index.php/PXELINUX}. -\paragraph{The TFTP service\\} -A TFTP server (\texttt{tftpd-hpa} on Debian for instance) must be installed. Configuration example: -\begin{verbatim} -# /etc/default/tftpd-hpa -TFTP_USERNAME="deploy" -TFTP_DIRECTORY="/var/lib/tftpboot" -TFTP_ADDRESS="0.0.0.0:69" -TFTP_OPTIONS="-v -l -s -c" -\end{verbatim} +More information about the configuration of PXElinux can be found at +\url{http://www.syslinux.org/wiki/index.php/PXELINUX}. + \paragraph{Booting over the network\\} -To allow the network booting, you must specify in the DHCP configuration file the file name option that define the file retrieve by a client. This file name can be pxelinux.0 or gpxelinux.0. -Finally, the TFTP repository (see~\ref{sec:general_config} part) must contain the following files and directories: +To allow the network booting, you must specify in the DHCP configuration file +the \texttt{filename} option. This option defines the name of file which will +be downloaded at the boot time. This file name can be +pxelinux.0, gpxelinux.0, or ipxelinux.0. + +Finally, the TFTP repository (see~\ref{sec:general_config} part) must contain +the following files and directories: + \begin{itemize} - \item pxelinux.0 (or gpxelinux.0) + \item pxelinux.0 (or similar) \item chain.c32 \item mboot.c32 \item a kernels/ directory (can be changed in the server configuration file) \item a pxelinux.cfg/ directory \end{itemize} -These files can be found in the Syslinux software (\url{http://syslinux.org}) or directly downloaded on the kernel.org website (\url{https://www.kernel.org/pub/linux/utils/boot/syslinux/}), the 3.73 version is at least required. + +These files can be found in the Syslinux software (\url{http://syslinux.org}) +or directly downloaded on the kernel.org website +(\url{https://www.kernel.org/pub/linux/utils/boot/syslinux/}), the 3.73 version +is at least required. + +\paragraph{The TFTP service\\} +A TFTP server (\texttt{tftpd-hpa} on Debian for instance) must be installed. +Configuration example: +\begin{verbatim} +# /etc/default/tftpd-hpa +TFTP_USERNAME="tftp" +TFTP_DIRECTORY="/var/lib/tftpboot" +TFTP_ADDRESS="0.0.0.0:69" +TFTP_OPTIONS="-v -l -c -s" +\end{verbatim} \subsection{HTTP server (optional)} -In order to use the HTTP fetching capabilities of gpxelinux, an HTTP server must be configured and must contain the production environment kernel/initrtd and the deployment environment kernel/initrd (see~\ref{sec:specific_config} part). -\subsection{MySql} -A MySql server must be configured with a database and a user dedicated to Kadeploy. The rights on this database must be granted to the chosen user, from the Kadeploy server. The server used to host the database, the database name, the dedicated user and its password must be specified in the general Kadeploy configuration (see~\ref{sec:general_config} part). +In order to use the HTTP fetching capabilities of gpxelinux or iPXE, an HTTP server +must be configured and must contain the production environment kernel/initrtd +and the deployment environment kernel/initrd (see~\ref{sec:specific_config} +part). + +\subsection{MySQL} + +A MySQL server must be configured with a database and a user dedicated to +Kadeploy. The rights on this database must be granted to the chosen user, from +the Kadeploy server. The server used to host the database, the database name, +the dedicated user and its password must be specified in the general Kadeploy +configuration (see~\ref{sec:general_config} part). + +Just provided as an example, let's see a way to create the database +\texttt{deploy3} and to give the suitable rights to the \texttt{deploy} user. -Just provided as an example, let's see a way to create the database \texttt{deploy3} and to give the suitable rights to the \texttt{deploy} user. \begin{verbatim} mysql> CREATE DATABASE deploy3; mysql> GRANT select, insert, update, delete, create, drop, alter, \ create temporary tables, lock tables ON deploy3.* \ - TO 'deploy'@'frontale.site.grid5000.fr'; + TO 'deploy'@'kadeploy.site.grid5000.fr'; +\end{verbatim} + +Once the database is created and the user granted, you can use the SQL script +provided in the distribution (\texttt{db/db\_creation.sql}) to create the +tables in the database. + +\begin{verbatim} +mysql> use deploy3 +mysql> source /usr/share/doc/kadeploy/db_creation.sql; \end{verbatim} -Once the database is created and the user granted, you can use the SQL script provided in the distribution (\texttt{db/db\_creation.sql}) to create the tables in the database. + +\subsection{TakTuk} + +Kadeploy3 requires TakTuk, a powerful tool to achieve remote executions. Thus +it must be installed on the Kadeploy3 server. + +\noindent \textbf{Note for Debian users} + +\noindent TakTuk is available in the official repositories. + +\noindent \textbf{Note for RedHat users} + +\noindent TakTuk is not packaged for RedHat-based distributions. +Some RPM packages are available on the Kadeploy3 website: +\url{http://kadeploy3.gforge.inria.fr/files/taktuk/}. It's also possible to +install TakTuk from the sources, more information on the project's +website: \url{http://taktuk.gforge.inria.fr/}. + + \subsection{TakTuk} Kadeploy3 have a strong dependence on the TakTuk software, this software should be installed on the machine that hosts the Kadeploy3 service in order for it to work properly. @@ -188,12 +257,19 @@ Kadeploy3 have a strong dependence on the TakTuk software, this software should \section{Kadeploy installation} -Since Kadeploy is based on a client/server architecture, you must perform the install on both the server and the client if it is not the same machine. -Two ways are provided to install Kadeploy, a basic installer and packages (for Debian and RedHat). In both cases, you had to ensure that a user \texttt{deploy} is existing on your system. This user is used to execute the Kadeploy server. Furthermore, all the installation operations must be performed with root rights. +Since Kadeploy is based on a client/server architecture, it must be installed +both on the server and on the client side (in case of distinct hosts). -\subsection{Basic installation} -First of all , you have to uncompress the Kadeploy tarball. +Two ways are provided to install Kadeploy: 1) the packages available in the download +section at \url{http://kadeploy3.gforge.inria.fr/} (for Debian and RedHat) and +2) Rake installation from sources. In both cases, you have to ensure that a user +\texttt{deploy} exists on the system since it is used to execute the +Kadeploy server. Furthermore, all the installation operations must be performed +with root rights. + +\subsection{Installation with Rake} +First of all, you have to uncompress the Kadeploy tarball. \begin{small} \begin{Verbatim}[commandchars=\\\{\}] > tar xzf kadeploy-\version.tar.gz -C DESTINATION_DIR @@ -221,9 +297,14 @@ First of all , you have to uncompress the Kadeploy tarball. \end{verbatim} \end{small} -\paragraph{remark:} If there are already configuration files, the new example of configuration files will be installed with \texttt{.dist} extension. +\paragraph{remark:} If there are already configuration files, the new example +of configuration files will be installed with \texttt{.dist} extension. + +\noindent If you want to install the rc script, you can add the +\texttt{DISTRIB} flag. Currently, only Debian (it includes Ubuntu at least) and +RedHat (it should include CentOS and RHEL) values are supported. For instance, +you can execute: -\noindent If you want to install the rc script, you can add the \texttt{DISTRIB} flag. Currently, only Debian (it includes Ubuntu at least) and RedHat (it should include CentOS and RHEL) values are supported. For instance, you cans execute: \begin{small} \begin{verbatim} > rake install[root_dir,redhat] @@ -236,8 +317,6 @@ or if you do not install the server side on the same machine than the client sid \end{verbatim} \end{small} -\noindent In order to preserve a previous configuration, the configuration directory \texttt{/etc/kadeploy3} is saved, if existing, to a directory named \texttt{/etc/kadeploy3-save-TIMESTAMP} where \texttt{TIMESTAMP} is the moment of the new installation launch. - \noindent Finally, Kadeploy can be simply uninstalled by executing: \begin{small} \begin{verbatim} @@ -247,9 +326,9 @@ or if you do not install the server side on the same machine than the client sid \noindent In case of uninstallation, the configuration directory \texttt{/etc/kadeploy3} is not removed. -\subsection{Debian packages} -The following installation method works only an Debian based distribution. -\subsubsection{Build} +\subsection{Build packages} +The following installation method works only on Debian based distribution. +\subsubsection{Build Debian Package} \noindent First, you have to uncompress the Kadeploy tarball. \begin{small} \begin{Verbatim}[commandchars=\\\{\}] @@ -263,7 +342,12 @@ The following installation method works only an Debian based distribution. > rake deb \end{verbatim} \end{small} -This will generate three Debian package: \texttt{kadeploy-common-\version.deb}, \texttt{kadeploy-client-\version.deb}, and \texttt{kadeploy-\version.deb}. + +This will generate three Debian package: \texttt{kadeploy-common-\version.deb}, +\texttt{kadeploy-client-\version.deb}, and \texttt{kadeploy-\version.deb}. + +\ + \subsubsection{Installation} \noindent On the server side, you have to install the \texttt{kadeploy-common-\version.deb} and \texttt{kadeploy-\version.deb} packages. \begin{small} @@ -346,7 +430,7 @@ After being installed and configured, the Kadeploy server can be run either inte \noindent or in background using the rc script: \begin{small} \begin{verbatim} -> /etc/init.d/kadeploy start +> service kadeploy start \end{verbatim} \end{small} @@ -405,7 +489,13 @@ example-complex:{\footnotesize # Complex structure} \end{small} \paragraph{Documentation: paths\\} -Kadeploy configuration settings will be described by giving a \emph{path} to each resources. A \emph{path} explicit the hierarchy structure to follow to spefify a setting in the configuration file. In a \emph{path}, the character \texttt{/} describes a nested \emph{Associative array}, characters \texttt{$[...]$} describes an \emph{Ordered list} of identical \emph{Associative arrays}.\\ + +Kadeploy configuration settings are described in YAML files. +A \emph{path} defines the hierarchy structure to +specify a setting in the configuration file. In a \emph{path}, +\texttt{/} describes a nested \emph{Associative array}, +\texttt{$[...]$} describes an \emph{Ordered list} of identical +\emph{Associative arrays}.\\ Example of \emph{path}s: \begin{itemize} @@ -502,7 +592,7 @@ verbosity: logs: 4 cache: directory: /var/cache/kadeploy - size: /tmp/kadeploy_cache + size: 8000 network: server_hostname: kadeploy.lan vlan: @@ -707,7 +797,7 @@ external: \end{itemize} \item \ypath{/pxe/dhcp/export} \begin{itemize} - \item \yfieldd{kind}{String}{tftp} The method used to export PXE files (expected values are \emph{tftp}, \emph{http} and \emph{ftp}). The path to the files in the profiles will be generated depending on this method. + \item \yfieldd{kind}{String}{tftp} The method used to export PXE files (expected values are \emph{tftp}, \emph{http} and \emph{ftp}). The path to the files in the PXE profiles depends on this method. \item \yfieldd{server}{String}{hostname} The server where PXE files are stored. To be complicant with most NBPs, it's recommended to specify this server by IP address (it will also make the nodes boot faster since there is no need to make a DNS request). \end{itemize} \item \ypath{/pxe/dhcp/profiles} @@ -755,7 +845,7 @@ The information used to generate this filenames are the one specified for each n \item \ypath{/pxe/localboot/export} \begin{itemize} \item \yfield{kind}{String} The method used to export PXE files (expected values are \emph{tftp}, \emph{http} and \emph{ftp}). The path to the files in the profiles will be generated depending on this method. - \item \yfield{server}{String} The server where PXE files are stored. To be complicant with most NBPs, it's recommended to specify this server by IP address (it will also make the nodes boot faster since there is no need to make a DNS request). + \item \yfield{server}{String} The server where PXE files are stored. To be compliant with most NBPs, it's recommended to specify this server by IP address (it will also make the nodes boot faster since there is no need to make a DNS request). \end{itemize} \item \ypath{/pxe/localboot/profiles} \begin{itemize} @@ -775,14 +865,13 @@ The information used to generate this filenames are the one specified for each n \end{itemize} \item \yfieldd{autoclean\_threshold}{Fixnum}{360} at the end of an operation (deploy/reboot/power) it's status kept until the user explicitly deletes them. This value fix the maximal time (in minutes) this information will be kept in memory by the server until the autoclean loop delete them. - - \item \yfieldd{/external/default\_connector}{String}{ssh -A -l root -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey -o BatchMode=yes} define alias for DEFAULT\_CONNECTOR in taktuk connector and remoteops for cluster specific file. + \item \yfieldd{/external/default\_connector}{String}{ssh -A -l root -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey -o BatchMode=yes} define alias for DEFAULT\_CONNECTOR in Taktuk connector and remoteops for cluster specific file. \item \ypath{/external/taktuk} \begin{itemize} \item \yfieldd{connector}{String}{DEFAULT\_CONNECTOR} connector used by Taktuk \item \yfieldd{tree\_arity}{Integer}{0} Taktuk tree arity for command executed through a tree. Use 0 if you want to use the work stealing algorithm of Taktuk and thus a dynamic tree arity. Use another value >0 to specify a static tree arity (should be avoided). \item \yfieldd{auto\_propagate}{Boolean}{true} use of the auto propagation feature of Taktuk. You should use this feature if the deployment environment doesn't contain Taktuk. - \item \yfieldd{outputs\_size}{Integer}{20000} to avoid big taktuk outputs to be loaded in the server's memory, it's possible to setup a limit of the per-node output size. If TakTuk returns an output bigger than \texttt{(NODES\_NUMBER * outputs\_size)} an error will be returned. This limit can be disabled by setting the \texttt{0} value. + \item \yfieldd{outputs\_size}{Integer}{20000} to avoid big Taktuk outputs to be loaded in the server's memory, it's possible to setup a limit of the per-node output size. If TakTuk returns an output bigger than \texttt{(NODES\_NUMBER * outputs\_size)} an error will be returned. This limit can be disabled by setting the \texttt{0} value. \end{itemize} \item \ypath{/external/bittorrent} @@ -853,6 +942,7 @@ This file describes the list of all the clusters, the location of their specific Warning, a cluster-specific configuration file and some partitioning/bootloader\_install scripts must be defined for each cluster define in this file. +%TODO : keep same example ... \subsection{Example of a clusters file\\} \begin{small} \begin{verbatim} diff --git a/doc/api/api_specs-3.3.0.rc8.html b/doc/api/api_specs-3.3.0.stable.html similarity index 92% rename from doc/api/api_specs-3.3.0.rc8.html rename to doc/api/api_specs-3.3.0.stable.html index 46a5ff2ab159a3d1de626e3f351ba94078055e64..bba91403e9aea9a4a50461a33926943bb6937c12 100644 --- a/doc/api/api_specs-3.3.0.rc8.html +++ b/doc/api/api_specs-3.3.0.stable.html @@ -1,4 +1,4 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><HTML><HEAD><TITLE>Kadeploy 3.3.0.rc8 REST API specifications</TITLE><LINK rel="stylesheet" type="text/css" href="api.css"></HEAD><BODY><DIV class="apidoc_frame"><H1 class="apidoc_title"><A class="apidoc_title_link" id="title">Kadeploy 3.3.0.rc8 REST API specifications</A></H1><DIV class="apidoc_index_frame"><UL class="apidoc_index_list"><LI><A class="apidoc_index_link" href="#intro">Introduction</A></LI><UL class="operation_index_list"><LI><A class="intro_index_link" href="#request_parameters">Request's parameters</A></LI><LI><A class="intro_index_link" href="#output_type">Output type and encoding</A></LI><LI><A class="intro_index_link" href="#Global parameters">Global parameters</A></LI><LI><A class="intro_index_link" href="#Authentication">Authentication</A></LI><LI><A class="intro_index_link" href="#Errors management">Errors management</A></LI><LI><A class="intro_index_link" href="#workflow_operations">Workflow based operations</A></LI><LI><A class="intro_index_link" href="#file_export">Exporting files for the server</A></LI><LI><A class="intro_index_link" href="#API documentation notations">API documentation notations</A></LI></UL><LI><A class="apidoc_index_link" href="#Reboot operations">Reboot operations</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/reboot"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/reboot</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Environments management">Environments management</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/environments"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/environments</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/environments/:username?/:name?/:version?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/environments/:username?/:name?/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username/:name/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username?/:name?/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username?/:name?/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/environments/:username/:name/:version?"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Console">Console</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/console"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/console</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/console"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/console</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/console/:id"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/console/:id</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/console/:id/error"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/console/:id/error</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/console/:id"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/console/:id</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Rights management">Rights management</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/rights"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/rights</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/rights/:username?/:node?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/rights/:username?/:node?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/rights/:username?/:node?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/rights/:username?/:node?</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/rights/:username/:node?/:partition?"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/rights/:username/:node?/:partition?</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Deployment">Deployment</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/deployment"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/deployment</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Power operations">Power operations</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#PUT/power"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/power</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/power"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/power</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Workflow-based operations">Workflow-based operations</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/%OPERATION"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/%OPERATION</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/logs/:cluster?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/logs/:cluster?</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/debugs/:node?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/debugs/:node?</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/state"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/state</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/status"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/status</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/error"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/error</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/%OPERATION/:id"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Nodes information">Nodes information</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#GET/nodes/:nodename?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/nodes/:nodename?</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Global information">Global information</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#GET/clusters"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/clusters</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/auth_headers_prefix"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/auth_headers_prefix</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/info"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/info</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/version"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/version</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Statistics">Statistics</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#GET/stats/%OPERATION?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/stats/%OPERATION?</SPAN></A></LI></UL></UL></DIV><HR class="apidoc_index_sep"><DIV class="intro_frame"><H1 class="intro_title"><A class="intro_title_link" id="intro">Introduction</A></H1><DIV class="section_frame"><H2 class="section_title"><A id="request_parameters">Request's parameters</A></H2><P class="section_paragraph">There is several ways to specify parameters when using the network API. Parameters can be specified in the query's URI parameter but also in the query's body. Remark: it's only possible to use String and Array data structures when specifying parameters using the query's URI to specify more advanced parameters (Numbers, Hashs, ...) it's necessary to specify the parameters using a more advanced description language (JSON/YAML) in the query's body.</P><P class="section_paragraph">The following examples are equivalent:</P><P class="section_paragraph"><B>Specifying parameters in the query's URI</B></P><P class="section_paragraph"><PRE class="code_sample"> POST /deploy?nodes=node-1.testbed.lan&nodes=node-2.testbed.lan HTTP/1.1 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><HTML><HEAD><TITLE>Kadeploy 3.3.0.stable REST API specifications</TITLE><LINK rel="stylesheet" type="text/css" href="api.css"></HEAD><BODY><DIV class="apidoc_frame"><H1 class="apidoc_title"><A class="apidoc_title_link" id="title">Kadeploy 3.3.0.stable REST API specifications</A></H1><DIV class="apidoc_index_frame"><UL class="apidoc_index_list"><LI><A class="apidoc_index_link" href="#intro">Introduction</A></LI><UL class="operation_index_list"><LI><A class="intro_index_link" href="#request_parameters">Request's parameters</A></LI><LI><A class="intro_index_link" href="#output_type">Output type and encoding</A></LI><LI><A class="intro_index_link" href="#Global parameters">Global parameters</A></LI><LI><A class="intro_index_link" href="#Authentication">Authentication</A></LI><LI><A class="intro_index_link" href="#Errors management">Errors management</A></LI><LI><A class="intro_index_link" href="#workflow_operations">Workflow based operations</A></LI><LI><A class="intro_index_link" href="#file_export">Exporting files for the server</A></LI><LI><A class="intro_index_link" href="#API documentation notations">API documentation notations</A></LI></UL><LI><A class="apidoc_index_link" href="#Reboot operations">Reboot operations</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/reboot"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/reboot</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Environments management">Environments management</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/environments"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/environments</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/environments?username=:username?&amp;name=:name?&amp;version=:version?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/environments?username=:username?&name=:name?&version=:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username/:name/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username?/:name?/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username?/:name?/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/environments/:username/:name/:version?"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Console">Console</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/console"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/console</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/console"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/console</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/console/:id"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/console/:id</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/console/:id/error"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/console/:id/error</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/console/:id"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/console/:id</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Rights management">Rights management</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/rights"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/rights</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/rights/:username?/:node?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/rights/:username?/:node?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/rights/:username?/:node?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/rights/:username?/:node?</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/rights/:username/:node?/:partition?"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/rights/:username/:node?/:partition?</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Deployment">Deployment</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/deployment"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/deployment</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Power operations">Power operations</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#PUT/power"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/power</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/power"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/power</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Workflow-based operations">Workflow-based operations</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/%OPERATION"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/%OPERATION</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/logs/:cluster?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/logs/:cluster?</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/debugs/:node?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/debugs/:node?</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/state"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/state</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/status"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/status</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/%OPERATION/:id/error"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id/error</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/%OPERATION/:id"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/%OPERATION/:id</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Nodes information">Nodes information</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#GET/nodes/:nodename?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/nodes/:nodename?</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Global information">Global information</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#GET/clusters"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/clusters</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/auth_headers_prefix"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/auth_headers_prefix</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/info"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/info</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/version"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/version</SPAN></A></LI></UL><LI><A class="apidoc_index_link" href="#Statistics">Statistics</A></LI><UL class="operation_index_list"><LI><A class="operation_index_link" href="#GET/stats/%OPERATION?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/stats/%OPERATION?</SPAN></A></LI></UL></UL></DIV><HR class="apidoc_index_sep"><DIV class="intro_frame"><H1 class="intro_title"><A class="intro_title_link" id="intro">Introduction</A></H1><DIV class="section_frame"><H2 class="section_title"><A id="request_parameters">Request's parameters</A></H2><P class="section_paragraph">There is several ways to specify parameters when using the network API. Parameters can be specified in the query's URI parameter but also in the query's body. Remark: it's only possible to use String and Array data structures when specifying parameters using the query's URI to specify more advanced parameters (Numbers, Hashs, ...) it's necessary to specify the parameters using a more advanced description language (JSON/YAML) in the query's body.</P><P class="section_paragraph">The following examples are equivalent:</P><P class="section_paragraph"><B>Specifying parameters in the query's URI</B></P><P class="section_paragraph"><PRE class="code_sample"> POST /deploy?nodes=node-1.testbed.lan&nodes=node-2.testbed.lan HTTP/1.1 Accept: */* Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend @@ -346,7 +346,7 @@ Content-Length: 533 "status": "/reboot/R-759f3f78-9742-47e6-b67e-c12b6750c2e4/status", "error": "/reboot/R-759f3f78-9742-47e6-b67e-c12b6750c2e4/error" } -}</PRE></DIV></DIV></DIV></DIV><P class="operation_back_link"><A class="operation_back_link" href="#Reboot operations">Back to operation</A></P><HR class="operation_inter_sep"></DIV><HR class="operation_sep"><DIV class="operation_frame"><H1 class="operation_title"><A id="Environments management">Environments management</A></H1><DIV class="operation_index_frame"><H2 class="operation_index_title">Resources</H2><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/environments"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/environments</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/environments/:username?/:name?/:version?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/environments/:username?/:name?/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username/:name/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username?/:name?/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username?/:name?/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/environments/:username/:name/:version?"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI></UL><H2 class="operation_index_title">Return types</H2><DIV class="type_frame"><H3 class="type_title"><A id="type_Environment"><B class="type_name">Environment</B><SPAN class="type_title_desc">(<SPAN class="type_basetype">Hash</SPAN>)</SPAN></A></H3><P class="type_desc">The description of an environment</P><DIV class="type_subframe"><TABLE class="type_fields"><TR><TH>Name</TH><TH>Type</TH><TH>Description</TH></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">user</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The owner of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">name</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The name of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">os</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The operating system of the environment<BR>Possible values: linux, xen, other</TD></TR><TR class="field_frame"><TD class="field_name">{<SPAN class="element_self"><SPAN class="element_normal">image</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">The image file that contains the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">image</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">file</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The path to the image file (see more <A href="#file_export">here</A>)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">image</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">kind</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The kind of image<BR>Possible values: tar, dd, fsa</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">image</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">compression</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The compression algorithm used to compress the image<BR>Possible values: gzip, bzip2, xz</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">version</SPAN></SPAN></TD><TD class="field_type">Integer</TD><TD class="field_desc">The version of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">description</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The description of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">author</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The author of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">visibility</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The visibility of the environment<BR>Possible values: public, private, shared</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">destructive</SPAN></SPAN></TD><TD class="field_type">Boolean</TD><TD class="field_desc">The environment destruct the disk partitioning</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">multipart</SPAN></SPAN></TD><TD class="field_type">Boolean</TD><TD class="field_desc">The environment image is a multi-partitioned archive</TD></TR><TR class="field_frame"><TD class="field_name">{<SPAN class="element_self"><SPAN class="element_normal">preinstall</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">A preinstall script archive</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">preinstall</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">file</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The path to the archive file (see more <A href="#file_export">here</A>)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">preinstall</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">compression</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The compression algorithm used to compress the archive<BR>Possible values: gzip, bzip2, xz</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">preinstall</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">script</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to a script (inside the archive) that will be launched during the pre-install step</TD></TR><TR class="field_frame"><TD class="field_name">[<SPAN class="element_self"><SPAN class="element_normal">postinstalls</SPAN></SPAN>]</TD><TD class="field_type">Array</TD><TD class="field_desc">A list of postinstall script archives</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_self"><SPAN class="element_iter">#i</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">A postinstall script archive</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_iter">#i</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">file</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The path to the archive file (see more <A href="#file_export">here</A>)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_iter">#i</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">compression</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The compression algorithm used to compress the archive<BR>Possible values: gzip, bzip2, xz</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_iter">#i</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">script</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to a script (inside the archive) that will be launched during the post-install step</TD></TR><TR class="field_frame"><TD class="field_name">{<SPAN class="element_self"><SPAN class="element_normal">boot</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">The environment's boot parameters</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">kernel</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to the kernel file (inside the environment\s image)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">initrd</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to the initrd file (inside the environment\s image)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">kernel_params</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The parameters to be given to the kernel at launch time</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">hypervisor</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to the hypervisor file (inside the environment\s image), useful when deploying Xen environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">hypervisor_params</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The parameters to be given to the hypervisor at launch time, useful when deploying Xen environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">block_device</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The block device environment should be installed on, useful for multi-partitioned environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">deploy_part</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The partition the environment should be installed on, useful for multi-partitioned environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">partition_type</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The partition type that will be set when partitioning the disk</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">filesystem</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The filesystem type of the environment, useful for tar environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">options</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Custom options</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_normal">options</SPAN></SPAN>.[<SPAN class="element_self"><SPAN class="element_normal">partitions</SPAN></SPAN>]</TD><TD class="field_type">Array</TD><TD class="field_desc">A list of id/partition association</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent"><SPAN class="element_normal">options</SPAN></SPAN>.[<SPAN class="element_normal">partitions</SPAN>]</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">id</SPAN></SPAN></TD><TD class="field_type">Integer</TD><TD class="field_desc">The id of the partition inside the compressed archive</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent"><SPAN class="element_normal">options</SPAN></SPAN>.[<SPAN class="element_normal">partitions</SPAN>]</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">device</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The physical device this archive part should be installed on</TD></TR></TABLE></DIV><H3 class="type_subtitle">Example #1</H3><PRE class="code_sample">{ +}</PRE></DIV></DIV></DIV></DIV><P class="operation_back_link"><A class="operation_back_link" href="#Reboot operations">Back to operation</A></P><HR class="operation_inter_sep"></DIV><HR class="operation_sep"><DIV class="operation_frame"><H1 class="operation_title"><A id="Environments management">Environments management</A></H1><DIV class="operation_index_frame"><H2 class="operation_index_title">Resources</H2><UL class="operation_index_list"><LI><A class="operation_index_link" href="#POST/environments"><SPAN class="resource_id_method_POST">POST</SPAN> <SPAN class="resource_id_path">/environments</SPAN></A></LI><LI><A class="operation_index_link" href="#GET/environments?username=:username?&amp;name=:name?&amp;version=:version?"><SPAN class="resource_id_method_GET">GET</SPAN> <SPAN class="resource_id_path">/environments?username=:username?&name=:name?&version=:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username/:name/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#PUT/environments/:username?/:name?/:version?"><SPAN class="resource_id_method_PUT">PUT</SPAN> <SPAN class="resource_id_path">/environments/:username?/:name?/:version?</SPAN></A></LI><LI><A class="operation_index_link" href="#DELETE/environments/:username/:name/:version?"><SPAN class="resource_id_method_DELETE">DELETE</SPAN> <SPAN class="resource_id_path">/environments/:username/:name/:version?</SPAN></A></LI></UL><H2 class="operation_index_title">Return types</H2><DIV class="type_frame"><H3 class="type_title"><A id="type_Environment"><B class="type_name">Environment</B><SPAN class="type_title_desc">(<SPAN class="type_basetype">Hash</SPAN>)</SPAN></A></H3><P class="type_desc">The description of an environment</P><DIV class="type_subframe"><TABLE class="type_fields"><TR><TH>Name</TH><TH>Type</TH><TH>Description</TH></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">user</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The owner of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">name</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The name of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">os</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The operating system of the environment<BR>Possible values: linux, xen, other</TD></TR><TR class="field_frame"><TD class="field_name">{<SPAN class="element_self"><SPAN class="element_normal">image</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">The image file that contains the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">image</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">file</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The path to the image file (see more <A href="#file_export">here</A>)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">image</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">kind</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The kind of image<BR>Possible values: tar, dd, fsa</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">image</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">compression</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The compression algorithm used to compress the image<BR>Possible values: gzip, bzip2, xz</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">version</SPAN></SPAN></TD><TD class="field_type">Integer</TD><TD class="field_desc">The version of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">description</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The description of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">author</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The author of the environment</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">visibility</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The visibility of the environment<BR>Possible values: public, private, shared</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">destructive</SPAN></SPAN></TD><TD class="field_type">Boolean</TD><TD class="field_desc">The environment destruct the disk partitioning</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">multipart</SPAN></SPAN></TD><TD class="field_type">Boolean</TD><TD class="field_desc">The environment image is a multi-partitioned archive</TD></TR><TR class="field_frame"><TD class="field_name">{<SPAN class="element_self"><SPAN class="element_normal">preinstall</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">A preinstall script archive</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">preinstall</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">file</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The path to the archive file (see more <A href="#file_export">here</A>)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">preinstall</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">compression</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The compression algorithm used to compress the archive<BR>Possible values: gzip, bzip2, xz</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">preinstall</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">script</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to a script (inside the archive) that will be launched during the pre-install step</TD></TR><TR class="field_frame"><TD class="field_name">[<SPAN class="element_self"><SPAN class="element_normal">postinstalls</SPAN></SPAN>]</TD><TD class="field_type">Array</TD><TD class="field_desc">A list of postinstall script archives</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_self"><SPAN class="element_iter">#i</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">A postinstall script archive</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_iter">#i</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">file</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The path to the archive file (see more <A href="#file_export">here</A>)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_iter">#i</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">compression</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The compression algorithm used to compress the archive<BR>Possible values: gzip, bzip2, xz</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent">[<SPAN class="element_normal">postinstalls</SPAN>]</SPAN>.{<SPAN class="element_iter">#i</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">script</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to a script (inside the archive) that will be launched during the post-install step</TD></TR><TR class="field_frame"><TD class="field_name">{<SPAN class="element_self"><SPAN class="element_normal">boot</SPAN></SPAN>}</TD><TD class="field_type">Hash</TD><TD class="field_desc">The environment's boot parameters</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">kernel</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to the kernel file (inside the environment\s image)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">initrd</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to the initrd file (inside the environment\s image)</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">kernel_params</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The parameters to be given to the kernel at launch time</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">hypervisor</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Path to the hypervisor file (inside the environment\s image), useful when deploying Xen environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">hypervisor_params</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The parameters to be given to the hypervisor at launch time, useful when deploying Xen environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">block_device</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The block device environment should be installed on, useful for multi-partitioned environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent">{<SPAN class="element_normal">boot</SPAN>}</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">deploy_part</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The partition the environment should be installed on, useful for multi-partitioned environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">partition_type</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The partition type that will be set when partitioning the disk</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">filesystem</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The filesystem type of the environment, useful for tar environments</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_normal">options</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">Custom options</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_normal">options</SPAN></SPAN>.[<SPAN class="element_self"><SPAN class="element_normal">partitions</SPAN></SPAN>]</TD><TD class="field_type">Array</TD><TD class="field_desc">A list of id/partition association</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent"><SPAN class="element_normal">options</SPAN></SPAN>.[<SPAN class="element_normal">partitions</SPAN>]</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">id</SPAN></SPAN></TD><TD class="field_type">Integer</TD><TD class="field_desc">The id of the partition inside the compressed archive</TD></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_parent"><SPAN class="element_parent"><SPAN class="element_normal">options</SPAN></SPAN>.[<SPAN class="element_normal">partitions</SPAN>]</SPAN>.<SPAN class="element_self"><SPAN class="element_normal">device</SPAN></SPAN></TD><TD class="field_type">String</TD><TD class="field_desc">The physical device this archive part should be installed on</TD></TR></TABLE></DIV><H3 class="type_subtitle">Example #1</H3><PRE class="code_sample">{ "name": "debian-custom", "version": 2, "visibility": "private", @@ -614,7 +614,7 @@ Content-Length: 642 } ] } -}</PRE></DIV></DIV></DIV></DIV><P class="operation_back_link"><A class="operation_back_link" href="#Environments management">Back to operation</A></P><HR class="operation_inter_sep"><DIV class="resource_frame"><H2 class="resource_title"><A id="GET/environments/:username?/:name?/:version?"><B class="resource_method_GET">GET</B> <SPAN style="font-family: monospace;" class="resource_path">/environments/:username?/:name?/:version?</SPAN></A></H2><P class="resource_desc">Gather the description of environments. If no user is given, the public environment will be displayed, otherwise a list of all environments that are public or owned by the user will be returned. The :username or the :name fields have to be encoded following the RFC 3986 specifications (non-ASCII characters are encoded with a percent notation)</P><DIV class="request_frame"><H3 class="request_title">Request <SPAN class="request_title_desc">(<SPAN class="request_type">Hash</SPAN>, <SPAN class="request_content">application/json</SPAN>)</SPAN></H3><DIV class="request_subframe"><H4 class="request_subtitle">Parameters</H4><TABLE class="request_parameters"><TR><TH>Name</TH><TH>Type</TH><TH>Kind</TH><TH>Description</TH></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_param">name</SPAN></SPAN></TD><TD class="parameter_type">String</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">The name of the environment</TD></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_param">username</SPAN></SPAN></TD><TD class="parameter_type">String</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">The owner of the environment</TD></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_param">version</SPAN></SPAN></TD><TD class="parameter_type">String</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">The version of the environment</TD></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_normal">last</SPAN></SPAN></TD><TD class="parameter_type">Set</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">Show the last version of environments (by default every versions are returned)</TD></TR></TABLE></DIV></DIV><DIV class="response_frame"><H3 class="response_title">Response <SPAN class="response_title_desc">(<SPAN class="response_type">Array</SPAN>, <SPAN class="response_content">application/json</SPAN>)</SPAN></H3><DIV class="response_subframe"><H4 class="response_subtitle">Fields</H4><TABLE class="response_fields"><TR><TH>Name</TH><TH>Type</TH><TH>Description</TH></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_iter">#i</SPAN></SPAN></TD><TD class="field_type"><A href="#type_Environment">Environment</A></TD><TD class="field_desc">One of the environment that were matching the request's parameters</TD></TR></TABLE><H4 class="response_subtitle">Return codes</H4><TABLE class="response_codes"><TR><TH>Code#</TH><TH>Description</TH></TR><TR class="code_frame"><TD class="code_number">200</TD><TD class="code_desc">OK, the request is successful</TD></TR><TR class="code_frame"><TD class="code_number">500</TD><TD class="code_desc">Internal Server Error, an uncatched exception was thrown on the server</TD></TR><TR class="code_frame"><TD class="code_number">400</TD><TD class="code_desc">Bad Request, Kadeploy Error: please check the X-Application-Error-Code and X-Application-Error-Code headers</TD></TR><TR class="code_frame"><TD class="code_number">401</TD><TD class="code_desc">Unauthorized, you need to be authenticated</TD></TR><TR class="code_frame"><TD class="code_number">403</TD><TD class="code_desc">Forbidden, you do not the rights to perform this operation. Unlike a 401 Unauthorized response, authenticating will make no difference.</TD></TR><TR class="code_frame"><TD class="code_number">415</TD><TD class="code_desc">Unsupported Media Type, check the Content-Type of your request's body</TD></TR><TR class="code_frame"><TD class="code_number">404</TD><TD class="code_desc">File not found, the resource you are looking for cannot be found</TD></TR></TABLE></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #1 <SPAN class="example_desc">Get the list of all visible environments</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments HTTP/1.1 +}</PRE></DIV></DIV></DIV></DIV><P class="operation_back_link"><A class="operation_back_link" href="#Environments management">Back to operation</A></P><HR class="operation_inter_sep"><DIV class="resource_frame"><H2 class="resource_title"><A id="GET/environments?username=:username?&amp;name=:name?&amp;version=:version?"><B class="resource_method_GET">GET</B> <SPAN style="font-family: monospace;" class="resource_path">/environments?username=:username?&name=:name?&version=:version?</SPAN></A></H2><P class="resource_desc">Gather the description of environments. If no user is given, the public environment will be displayed, otherwise a list of all environments that are public or owned by the user will be returned. The :username or the :name fields have to be encoded following the RFC 3986 specifications (non-ASCII characters are encoded with a percent notation)</P><DIV class="request_frame"><H3 class="request_title">Request <SPAN class="request_title_desc">(<SPAN class="request_type">Hash</SPAN>, <SPAN class="request_content">application/json</SPAN>)</SPAN></H3><DIV class="request_subframe"><H4 class="request_subtitle">Parameters</H4><TABLE class="request_parameters"><TR><TH>Name</TH><TH>Type</TH><TH>Kind</TH><TH>Description</TH></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_param">name</SPAN></SPAN></TD><TD class="parameter_type">String</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">The name of the environment</TD></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_param">username</SPAN></SPAN></TD><TD class="parameter_type">String</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">The owner of the environment</TD></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_param">version</SPAN></SPAN></TD><TD class="parameter_type">String</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">The version of the environment</TD></TR><TR class="parameter_frame"><TD class="parameter_name"><SPAN class="element_self"><SPAN class="element_normal">last</SPAN></SPAN></TD><TD class="parameter_type">Set</TD><TD class="parameter_mandat">Optional</TD><TD class="parameter_desc">Show the last version of environments (by default every versions are returned)</TD></TR></TABLE></DIV></DIV><DIV class="response_frame"><H3 class="response_title">Response <SPAN class="response_title_desc">(<SPAN class="response_type">Array</SPAN>, <SPAN class="response_content">application/json</SPAN>)</SPAN></H3><DIV class="response_subframe"><H4 class="response_subtitle">Fields</H4><TABLE class="response_fields"><TR><TH>Name</TH><TH>Type</TH><TH>Description</TH></TR><TR class="field_frame"><TD class="field_name"><SPAN class="element_self"><SPAN class="element_iter">#i</SPAN></SPAN></TD><TD class="field_type"><A href="#type_Environment">Environment</A></TD><TD class="field_desc">One of the environment that were matching the request's parameters</TD></TR></TABLE><H4 class="response_subtitle">Return codes</H4><TABLE class="response_codes"><TR><TH>Code#</TH><TH>Description</TH></TR><TR class="code_frame"><TD class="code_number">200</TD><TD class="code_desc">OK, the request is successful</TD></TR><TR class="code_frame"><TD class="code_number">500</TD><TD class="code_desc">Internal Server Error, an uncatched exception was thrown on the server</TD></TR><TR class="code_frame"><TD class="code_number">400</TD><TD class="code_desc">Bad Request, Kadeploy Error: please check the X-Application-Error-Code and X-Application-Error-Code headers</TD></TR><TR class="code_frame"><TD class="code_number">401</TD><TD class="code_desc">Unauthorized, you need to be authenticated</TD></TR><TR class="code_frame"><TD class="code_number">403</TD><TD class="code_desc">Forbidden, you do not the rights to perform this operation. Unlike a 401 Unauthorized response, authenticating will make no difference.</TD></TR><TR class="code_frame"><TD class="code_number">415</TD><TD class="code_desc">Unsupported Media Type, check the Content-Type of your request's body</TD></TR><TR class="code_frame"><TD class="code_number">404</TD><TD class="code_desc">File not found, the resource you are looking for cannot be found</TD></TR></TABLE></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #1 <SPAN class="example_desc">Get the list of all visible environments</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend</PRE><H4 class="example_subtitle">Response</H4><PRE class="code_sample">HTTP/1.1 200 OK @@ -679,7 +679,7 @@ Content-Length: 1589 "multipart": false, "user": "root" } -]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #2 <SPAN class="example_desc">Get the list of the environments a specified user can see</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments/frontend HTTP/1.1 +]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #2 <SPAN class="example_desc">Get the list of the environments a specified user can see</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments?username=frontend HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend</PRE><H4 class="example_subtitle">Response</H4><PRE class="code_sample">HTTP/1.1 200 OK @@ -764,7 +764,7 @@ Content-Length: 2029 "multipart": false, "user": "root" } -]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #3 <SPAN class="example_desc">Get the description of a specific environment</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments/frontend/debian-custom HTTP/1.1 +]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #3 <SPAN class="example_desc">Get the description of a specific environment</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments?username=frontend&name=debian-custom HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend</PRE><H4 class="example_subtitle">Response</H4><PRE class="code_sample">HTTP/1.1 200 OK @@ -791,7 +791,7 @@ Content-Length: 442 "multipart": false, "user": "frontend" } -]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #4 <SPAN class="example_desc">Get the description of a specific version of a specific environment</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments/frontend/debian-custom/1 HTTP/1.1 +]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #4 <SPAN class="example_desc">Get the description of a specific version of a specific environment</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments?username=frontend&name=debian-custom&version=1 HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend</PRE><H4 class="example_subtitle">Response</H4><PRE class="code_sample">HTTP/1.1 200 OK @@ -818,7 +818,7 @@ Content-Length: 432 "multipart": false, "user": "frontend" } -]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #5 <SPAN class="example_desc">Get the description of every versions of a specific environment</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments/frontend/debian-custom HTTP/1.1 +]</PRE></DIV></DIV></DIV><DIV class="example_frame"><H3 class="example_title">Example #5 <SPAN class="example_desc">Get the description of every debian-custom</SPAN></H3><DIV onclick="this.lastChild.style.display = (this.lastChild.style.display == 'none' ? 'block' : 'none');this.firstChild.style.display = (this.firstChild.style.display == 'none' ? 'block' : 'none');" class="example_subframe"><P class="toggle_link">show</P><DIV class="toggle_content" style="display: none;"><H4 class="example_subtitle">Request</H4><PRE class="code_sample">GET /environments?name=debian-custom HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend</PRE><H4 class="example_subtitle">Response</H4><PRE class="code_sample">HTTP/1.1 200 OK diff --git a/doc/api/envs.api b/doc/api/envs.api index d834c5a835106b9397d3d522e2f141e5e29f31e7..58a69d24e39749479ef5ca2dee40e33f5a51710b 100644 --- a/doc/api/envs.api +++ b/doc/api/envs.api @@ -409,7 +409,7 @@ operation 'Environments management' do EOS end - resource :GET, '/environments/:username?/:name?/:version?', 'Gather the description of environments. If no user is given, the public environment will be displayed, otherwise a list of all environments that are public or owned by the user will be returned. The :username or the :name fields have to be encoded following the RFC 3986 specifications (non-ASCII characters are encoded with a percent notation)' do + resource :GET, '/environments?username=:username?&name=:name?&version=:version?', 'Gather the description of environments. If no user is given, the public environment will be displayed, otherwise a list of all environments that are public or owned by the user will be returned. The :username or the :name fields have to be encoded following the RFC 3986 specifications (non-ASCII characters are encoded with a percent notation)' do request do parameter ':username', :String, 'The owner of the environment', false parameter ':name', :String, 'The name of the environment', false @@ -496,7 +496,7 @@ operation 'Environments management' do example 'Get the list of the environments a specified user can see', <<-EOS , - GET /environments/frontend HTTP/1.1 + GET /environments?username=frontend HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend @@ -589,7 +589,7 @@ operation 'Environments management' do example 'Get the description of a specific environment', <<-EOS , - GET /environments/frontend/debian-custom HTTP/1.1 + GET /environments?username=frontend&name=debian-custom HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend @@ -624,7 +624,7 @@ operation 'Environments management' do example 'Get the description of a specific version of a specific environment', <<-EOS , - GET /environments/frontend/debian-custom/1 HTTP/1.1 + GET /environments?username=frontend&name=debian-custom&version=1 HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend @@ -657,9 +657,9 @@ operation 'Environments management' do ] EOS - example 'Get the description of every versions of a specific environment', + example 'Get the description of every debian-custom', <<-EOS , - GET /environments/frontend/debian-custom HTTP/1.1 + GET /environments?name=debian-custom HTTP/1.1 Accept: text/plain, application/json Host: kadeploy.testbed.lan:25300 X-Kadeploy-User: frontend diff --git a/lib/kadeploy3/client/client.rb b/lib/kadeploy3/client/client.rb index 43c197befe08eece6afd48ad6779dc0ca0b04abc..14bf7828443e118745a6d633982585b53b3a9595 100644 --- a/lib/kadeploy3/client/client.rb +++ b/lib/kadeploy3/client/client.rb @@ -693,6 +693,10 @@ class Client opt.separator "Contact: #{CONTACT_EMAIL}" opt.separator "" opt.separator "Generic options:" + opt.on("-h", "--help", "Show this message") do + puts opts + exit 0 + end add_opt(opt,"-v", "--version", "Get the server's version") { options[:get_version] = true } diff --git a/lib/kadeploy3/common/environment.rb b/lib/kadeploy3/common/environment.rb index 6bbfcf548754e6003aa356bfa363eb17445d7cad..391db8143088331cc8f2ddfbc9a8a487cbc545d6 100644 --- a/lib/kadeploy3/common/environment.rb +++ b/lib/kadeploy3/common/environment.rb @@ -356,7 +356,7 @@ class Environment # * Otherwise only the last version is returned # # ======= Behavior wrt the optional parameters - # * If owner_user is nil or empty, look for the environments belonging to context_user first. + # * If owner_user is nil or empty, look for the environments belonging to context_user first, excepted for almighty users who can see everything # * Private environments are returned if: # * context_user is equal to owner_user or owner_user is nil # * context_user is an almighty user @@ -364,123 +364,71 @@ class Environment # * owner_user is nil or empty # * no environment belongs to owner_user def self.get_from_db_context(dbh,name,version,owner_user,context_user,almighty_users) - user2 = owner_user.nil? || owner_user.empty? ? context_user : owner_user + is_almighty = almighty_users.include?(context_user) + + user2 = (owner_user.nil? || owner_user.empty?) && !is_almighty ? context_user : owner_user + get_from_db( dbh, name, version, user2, - context_user == user2 || almighty_users.include?(context_user), + context_user == user2 || is_almighty, owner_user.nil? || owner_user.empty? - ) + ) + end + + def self.add_cond(args,condition,sql,value) + if value && !value.empty? + args<<value + condition += sql + end + condition end def self.get_from_db(dbh, name, version, user, private_envs=false, public_envs=false) version = version.to_s if version.is_a?(Fixnum) - - dbproc = Proc.new do |userq,visiq| - args = [] - query = "SELECT * FROM environments WHERE name=?" + args = [] + last_version = false + sort='' + conditions = "WHERE true " + if name && !name.empty? args << name - if userq and !userq.empty? and user and !user.empty? - query += " AND #{userq}" + conditions += ' AND name like ?' + end + if user && !user.empty? + args << user + if public_envs + conditions += " AND (user like ? OR (user <> ? AND visibility = 'public'))" args << user - end - query += " AND #{visiq}" if visiq and !visiq.empty? - - if version == true - query += " ORDER BY version" - elsif version and !version.empty? - query += " AND version = ?" - args << version else - subquery = "SELECT MAX(version) FROM environments WHERE name = ?" - args << name - if userq and !userq.empty? and user and !user.empty? - subquery += " AND #{userq}" - args << user - end - subquery += " AND #{visiq}" if visiq and !visiq.empty? - query += " AND version = (#{subquery})" - end - - res = dbh.run_query(query, *args) - tmp = res.to_hash if res - if tmp and !tmp.empty? - ret = [] - tmp.each do |hash| - ret << Environment.new.load_from_dbhash(hash) - end - ret - else - false + conditions += ' AND user like ?' end end - - visiq = (private_envs ? nil : "visibility <> 'private'") - - # look for the environment of the specified user - # allowing or not the check private envs - ret = dbproc.call('user=?',visiq) - - # if no envs were found and allowed to check publics envs, - # we check publics envs with a different user than the one specified - if (!ret or ret.size > 1) and public_envs - ret = dbproc.call('user<>?',"visibility = 'public'") + if !private_envs + conditions += " AND visibility <> 'private'" end - return ret - end - - def self.get_list_from_db(dbh, user, private_envs=false, public_envs=false, show_all_version=false) - args = [] - where = '' - if user - if show_all_version - where = "user = ?" - args << user - - where << " AND visibility <> 'private'" unless private_envs - - if public_envs - where << " OR (user <> ? AND visibility = 'public')" - args << user - end - else - cond = Proc.new do |lab,ar| - ret = "(e1.user = ?" - ar << user - ret << " AND visibility <> 'private'" unless private_envs - if public_envs - ret << " OR (user <> ? AND visibility = 'public')" - ar << user - end - ret << ")" - end - - where = "#{cond.call('e1',args)} \ - AND e1.version = ( \ - SELECT MAX(e2.version) FROM environments e2 \ - WHERE e2.name = e1.name \ - AND e2.user = e1.user \ - AND #{cond.call('e2',args)} \ - GROUP BY e2.user,e2.name)" - end - else #we show the environments of all the users - unless show_all_version - where = "e1.version=( \ - SELECT MAX(e2.version) FROM environments e2 \ - WHERE e2.name = e1.name \ - AND e2.user = e1.user \ - GROUP BY e2.user, e2.name)" - end + if version == true + sort=', version desc' + elsif version and !version.empty? + conditions += " AND version = ?" + args << version + else + last_version = true end - query = "SELECT * FROM environments e1" - query += " WHERE #{where}" unless where.empty? - query += " ORDER BY e1.user, e1.name, e1.version" + sql = if last_version + "select e.* from (select name,max(version) as maxversion "\ + "from environments #{conditions} group by name,user) m "\ + "inner join environments e on e.name = m.name and m.maxversion = e.version "\ + "ORDER BY field(visibility,'public','private','shared'), name#{sort};" + else + "select * from environments #{conditions} "\ + "ORDER BY field(visibility,'public','private','shared'), name#{sort};" + end - res = dbh.run_query(query, *args) + res = dbh.run_query(sql, *args) tmp = res.to_hash if res if tmp and !tmp.empty? ret = [] diff --git a/lib/kadeploy3/server/kaenvs.rb b/lib/kadeploy3/server/kaenvs.rb index 9993821171969a486d7bef3d99899b6c0970cf4a..fb3fa9a04d015788b719c34a6a854fe4c5c85283 100644 --- a/lib/kadeploy3/server/kaenvs.rb +++ b/lib/kadeploy3/server/kaenvs.rb @@ -39,18 +39,23 @@ module Kaenvs context.username = context.user end - unless (context.environment.load_from_desc( - env, - context.almighty_users, - context.username, - context.client - )) + unless ( + context.environment.load_from_desc( + env, + context.almighty_users, + context.username, + context.client + ) + ) kaerror(APIError::INVALID_ENVIRONMENT) end end when :get parse_params(params) do |p| context.last = p.parse('last',nil,:toggle=>true) + context.env_user = p.parse('username',String) + context.env_version = p.parse('version',String) + context.env_name = p.parse('name',String) end when :modify context.config = duplicate_config() @@ -137,33 +142,22 @@ module Kaenvs end end - def envs_get(cexec,user=nil,name=nil,version=nil) + def envs_get(cexec) envs = nil - if user and name - error_not_found! if name.empty? - envs = Environment.get_from_db_context( + envs = Environment.get_from_db_context( cexec.database, - name, - version || !cexec.last || nil, # if nil->last, if version->version, if true->all - user, + cexec.env_name, + cexec.env_version || !cexec.last || nil, # if nil->last, if version->version, if true->all + cexec.env_user, cexec.user, cexec.almighty_users - ) - else - envs = Environment.get_list_from_db( - cexec.database, - user || (cexec.almighty_users.include?(cexec.user) ? nil : cexec.user), # Almighty user can see everything - (!user or cexec.user == user) || cexec.almighty_users.include?(cexec.user), #If the user wants to print the environments of another user, private environments are not shown - (user.nil? or user.empty?),# Show only the environments of a specific user if user is defined - !cexec.last - ) - end + ) if envs envs.collect do |env| env.to_hash.merge!({'user'=>env.user}) end - elsif name or version + elsif cexec.env_name or cexec.env_version error_not_found! else [] @@ -214,7 +208,7 @@ module Kaenvs ret = [] updates = {} - envs = Environment.get_list_from_db(cexec.database,user,true,true,true) + envs = Environment.get_from_db(cexec.database,user,nil,nil,true,true,true) envs.each do |env| cexec.environment[:update_files].each do |oldf,newf| @@ -308,6 +302,7 @@ module Kaenvs end end + def envs_delete(cexec,user,name,version=nil) if (envs = Environment.del_from_db( cexec.database, diff --git a/man/kaconsole3.1 b/man/kaconsole3.1 index 1ab0fc8f965184087d6b275128ce840e4f86c870..79d92e2ef993aad74316cb3b94605e8cfe453fe1 100644 --- a/man/kaconsole3.1 +++ b/man/kaconsole3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KACONSOLE3 "1" "September 2014" "kaconsole3 3.3.0.rc8" "User Commands" +.TH KACONSOLE3 "1" "November 2014" "kaconsole3 3.3.0.stable" "User Commands" .SH NAME kaconsole3 \- access the console of deploying nodes .SH SYNOPSIS @@ -9,6 +9,9 @@ kaconsole3 \- access the console of deploying nodes Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/man/kadeploy3.1 b/man/kadeploy3.1 index b8a963599bd6c04145fcebccd68c7bb636efb407..4624c04e48cf7c8962e66e880fab42e663d429d9 100644 --- a/man/kadeploy3.1 +++ b/man/kadeploy3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KADEPLOY3 "1" "September 2014" "kadeploy3 3.3.0.rc8" "User Commands" +.TH KADEPLOY3 "1" "November 2014" "kadeploy3 3.3.0.stable" "User Commands" .SH NAME kadeploy3 \- Kadeploy client -- perform efficient deployments on cluster nodes .SH SYNOPSIS @@ -9,6 +9,9 @@ kadeploy3 \- Kadeploy client -- perform efficient deployments on cluster nodes Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/man/kadeploy3d.8 b/man/kadeploy3d.8 index 81ac4847a03f02c70b11dbed23eac446d4a3e322..1cf871fc3d8ff6b6262c96821edadfe73c8d99db 100644 --- a/man/kadeploy3d.8 +++ b/man/kadeploy3d.8 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KADEPLOY3D "8" "September 2014" "kadeploy3d 3.3.0.rc8" "System Administration Utilities" +.TH KADEPLOY3D "8" "November 2014" "kadeploy3d 3.3.0.stable" "System Administration Utilities" .SH NAME kadeploy3d \- Kadeploy server .SH SYNOPSIS diff --git a/man/kaenv3.1 b/man/kaenv3.1 index 41924b5e8da3a791764422be2adce308435b0862..3c1054c2eaf7c88d905846c4fa820b9f9e859dbc 100644 --- a/man/kaenv3.1 +++ b/man/kaenv3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KAENV3 "1" "September 2014" "kaenv3 3.3.0.rc8" "User Commands" +.TH KAENV3 "1" "November 2014" "kaenv3 3.3.0.stable" "User Commands" .SH NAME kaenv3 \- manage the Kadeploy environments .SH SYNOPSIS @@ -9,6 +9,9 @@ kaenv3 \- manage the Kadeploy environments Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP @@ -37,8 +40,8 @@ Add an environment \fB\-d\fR, \fB\-\-delete\fR ENVNAME Delete an environment .TP -\fB\-l\fR, \fB\-\-list\fR -List environments +\fB\-l\fR, \fB\-\-list\fR [ENVNAME] +List environments with the environment name pattern (% is the wildcard). .TP \fB\-m\fR, \fB\-\-files\-to\-move\fR FILES Files to move (src1::dst1,src2::dst2,...) diff --git a/man/kanodes3.1 b/man/kanodes3.1 index ca3b94111714f447f30057aa875b6f7a2a648c64..e75f84221ea2a61f1dafcaebba344dce015421bf 100644 --- a/man/kanodes3.1 +++ b/man/kanodes3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KANODES3 "1" "September 2014" "kanodes3 3.3.0.rc8" "User Commands" +.TH KANODES3 "1" "November 2014" "kanodes3 3.3.0.stable" "User Commands" .SH NAME kanodes3 \- get information on the current deployments .SH SYNOPSIS @@ -9,6 +9,9 @@ kanodes3 \- get information on the current deployments Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/man/kapower3.1 b/man/kapower3.1 index f8c1dfa3502a9c403ae15623336dfd72cc8ac51d..4131c6a50840d3cfe3f4fbef3dd2fd084474d7dc 100644 --- a/man/kapower3.1 +++ b/man/kapower3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KAPOWER3 "1" "September 2014" "kapower3 3.3.0.rc8" "User Commands" +.TH KAPOWER3 "1" "November 2014" "kapower3 3.3.0.stable" "User Commands" .SH NAME kapower3 \- control the power status of nodes .SH SYNOPSIS @@ -9,6 +9,9 @@ kapower3 \- control the power status of nodes Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/man/kareboot3.1 b/man/kareboot3.1 index b72e7450d4d5ade547325c31b608f729cbbeaf09..536ea203446a7dcaed8b46f7bddb21c9810577b4 100644 --- a/man/kareboot3.1 +++ b/man/kareboot3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KAREBOOT3 "1" "September 2014" "kareboot3 3.3.0.rc8" "User Commands" +.TH KAREBOOT3 "1" "November 2014" "kareboot3 3.3.0.stable" "User Commands" .SH NAME kareboot3 \- perform reboot operations on the nodes involved in a deployment .SH SYNOPSIS @@ -9,6 +9,9 @@ kareboot3 \- perform reboot operations on the nodes involved in a deployment Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/man/karights3.8 b/man/karights3.8 index f7b7b0f6991ce314d5df74fa25e67ff154c82a39..12d8fd8556c5f74f6757238fbd6969fa075e238d 100644 --- a/man/karights3.8 +++ b/man/karights3.8 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KARIGHTS3 "8" "September 2014" "karights3 3.3.0.rc8" "System Administration Utilities" +.TH KARIGHTS3 "8" "November 2014" "karights3 3.3.0.stable" "System Administration Utilities" .SH NAME karights3 \- manage users deployment rights .SH SYNOPSIS @@ -9,6 +9,9 @@ karights3 \- manage users deployment rights Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/man/kastat3.1 b/man/kastat3.1 index 56654a253b8c752caf53f2b1dff83fbafc75961f..3ae2503df1d48e122e52c68f625061396edece0c 100644 --- a/man/kastat3.1 +++ b/man/kastat3.1 @@ -1,5 +1,5 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.40.10. -.TH KASTAT3 "1" "September 2014" "kastat3 3.3.0.rc8" "User Commands" +.TH KASTAT3 "1" "November 2014" "kastat3 3.3.0.stable" "User Commands" .SH NAME kastat3 \- get statistics on the deployments .SH SYNOPSIS @@ -9,6 +9,9 @@ kastat3 \- get statistics on the deployments Contact: kadeploy3\-users@lists.gforge.inria.fr .SS "Generic options:" .TP +\fB\-h\fR, \fB\-\-help\fR +Show this message +.TP \fB\-v\fR, \fB\-\-version\fR Get the server's version .TP diff --git a/release_version b/release_version index 67f312a3c1e09402bad69a5190f2fcf74425a60b..2bf5ad0447d3370461c6f32a0a5bc8a3177376aa 100644 --- a/release_version +++ b/release_version @@ -1 +1 @@ -rc8 +stable diff --git a/sbin/kadeploy3d b/sbin/kadeploy3d index e812ae8d35ea2e5aa232a564377c41c02b1d59e1..afe38df7def4be15436e68269a6efa0f7c167921 100755 --- a/sbin/kadeploy3d +++ b/sbin/kadeploy3d @@ -1,7 +1,12 @@ #!/usr/bin/ruby -w + # Necessary to force the Debian's ruby-mysql library to return UTF-8 encoded strings +# We disable the warning message here. +warn_level = $VERBOSE +$VERBOSE = nil Encoding.default_external = Encoding::UTF_8 if RUBY_VERSION >= '1.9' +$VERBOSE = warn_level $:.unshift(ENV['KADEPLOY3_LIBS']) if ENV['KADEPLOY3_LIBS'] $kadeploy_logdir=ENV['KADEPLOY3_LOG_DIR']||'/var/log/kadeploy3'