From b88033ff2ac13c7aaacfc62876acd6ae0dcc862e Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 01:09:27 -0700 Subject: [PATCH 01/37] fix installation issue --- build/package.xml | 36 +++++++++---------- cloud.spec | 1 + debian/cloud-deps.install | 1 + .../storage/secondary/cloud-install-sys-tmplt | 3 +- wscript_build | 2 +- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/build/package.xml b/build/package.xml index 275d2656567..01c702f0980 100755 --- a/build/package.xml +++ b/build/package.xml @@ -200,26 +200,22 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/cloud.spec b/cloud.spec index fed252fbc93..4bbff9af42c 100644 --- a/cloud.spec +++ b/cloud.spec @@ -475,6 +475,7 @@ fi %{_javadir}/asm-3.1.jar %{_javadir}/xapi-5.6.100-1-SNAPSHOT.jar %{_javadir}/log4j-*.jar +%{_javadir}/apache-log4j-extras-1.1.jar %{_javadir}/trilead-ssh2-build213-svnkit-1.3-patch.jar %{_javadir}/cglib-2.2.jar %{_javadir}/xmlrpc-common-3.*.jar diff --git a/debian/cloud-deps.install b/debian/cloud-deps.install index 5b11d6309ca..e11f7e034ad 100644 --- a/debian/cloud-deps.install +++ b/debian/cloud-deps.install @@ -23,6 +23,7 @@ /usr/share/java/mail-1.4.jar /usr/share/java/httpcore-4.0.jar /usr/share/java/log4j-*.jar +/usr/share/java/apache-log4j-extras-1.1.jar /usr/share/java/trilead-ssh2-build213-svnkit-1.3-patch.jar /usr/share/java/cglib-2.2.jar /usr/share/java/xmlrpc-common-3.*.jar diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt index 12e8ea9b59d..55f3d18c93f 100755 --- a/scripts/storage/secondary/cloud-install-sys-tmplt +++ b/scripts/storage/secondary/cloud-install-sys-tmplt @@ -40,6 +40,7 @@ DISKSPACE=5120000 #free disk space required in kilobytes dbHost= dbUser= dbPassword= +jasypt='/usr/share/java/jasypt-1.9.0.jar' while getopts 'm:h:f:u:Ft:e:s:o:r:d' OPTION do case $OPTION in @@ -129,7 +130,7 @@ then encPassword=$(sed '/^\#/d' /etc/cloud/management/db.properties | grep 'db.cloud.password' | tail -n 1 | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'i | sed 's/^ENC(\(.*\))/\1/') if [ ! $encPassword == "" ] then - dbPassword=(`java -classpath /usr/share/java/cloud-jasypt-1.8.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI decrypt.sh input=$encPassword password=$msKey verbose=false`) + dbPassword=(`java -classpath $jasypt org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI decrypt.sh input=$encPassword password=$msKey verbose=false`) if [ ! $dbPassword ] then echo "Failed to decrypt DB password from db.properties" diff --git a/wscript_build b/wscript_build index 9bb645b7967..3598880f87f 100644 --- a/wscript_build +++ b/wscript_build @@ -162,7 +162,7 @@ def build_dependences (): start_path = bld.path.find_dir ("deps") - bld.install_files('${JAVADIR}',start_path.ant_glob(["libvirt-0.4.8.jar", "axis2-1.5.1.jar", "jstl-1.2.jar", "commons-discovery-0.5.jar", "commons-codec-1.6.jar", "ejb-api-3.0.jar", "xmlrpc-client-3.1.3.jar", "commons-dbcp-1.4.jar", "commons-pool-1.6.jar", "gson-1.7.1.jar", + bld.install_files('${JAVADIR}',start_path.ant_glob(["apache-log4j-extras-1.1.jar", "libvirt-0.4.8.jar", "axis2-1.5.1.jar", "jstl-1.2.jar", "commons-discovery-0.5.jar", "commons-codec-1.6.jar", "ejb-api-3.0.jar", "xmlrpc-client-3.1.3.jar", "commons-dbcp-1.4.jar", "commons-pool-1.6.jar", "gson-1.7.1.jar", "netscaler-1.0.jar", "netscaler-sdx-1.0.jar", "backport-util-concurrent-3.1.jar", "ehcache-1.5.0.jar", "httpcore-4.0.jar", "log4j-1.2.16.jar", "trilead-ssh2-build213-svnkit-1.3-patch.jar", "cglib-2.2.jar", "xmlrpc-common-3.*.jar", "xmlrpc-client-3.*.jar", "axis-1.4.jar", "wsdl4j-1.6.2.jar", "bcprov-jdk16-1.46.jar", "jsch-0.1.42.jar", "jasypt-1.9.0.jar", "commons-configuration-1.8.jar", "commons-lang-2.6.jar", "mail-1.4.jar", "activation-1.1.jar", "mysql-connector-java-5.1.21.jar", "hibernate-jpa-2.0-api-1.0.0.Final.jar", "hibernate-entitymanager-3.5.1-Final.jar", "hibernate-core-3.5.1-Final.jar", "hibernate-commons-annotations-3.2.0.Final.jar", "hibernate-annotations-3.5.1-Final.jar", "asm-3.1.jar", "xapi-5.6.100-1-SNAPSHOT.jar"], excl = excludes), cwd=start_path) From 1a23464868de72d36e104c3442b3a7444fea3154 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 01:32:14 -0700 Subject: [PATCH 02/37] fix ant build failed on jenkins --- wscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wscript b/wscript index 2491a7de90f..290798b5984 100644 --- a/wscript +++ b/wscript @@ -290,6 +290,7 @@ Utils.discover_ant_targets_and_properties = discover_ant_targets_and_properties # this is NOT a task for a task generator -- it is a plain function. # If you want to use it as a task function in a task generator, use a lambda x: runant("targetname") def runant(tsk): + conf = _getbuildcontext() environ = dict(os.environ) environ["CATALINA_HOME"] = tsk.env.TOMCATHOME environ["ANT_HOME"] = _join("tools","ant","apache-ant-1.7.1") @@ -301,7 +302,7 @@ def runant(tsk): else: stanzas = [ _join(environ["ANT_HOME"],"bin","ant"), - "-Dthirdparty.classpath=./deps/*:%s"%(tsk.env.CLASSPATH.replace(os.pathsep,",")), + "-Dthirdparty.classpath=%s:%s"%(tsk.env.CLASSPATH.replace(os.pathsep,","), conf.env.DEPSCLASSPATH), ] stanzas += tsk.generator.antargs ret = Utils.exec_command(" ".join(stanzas),cwd=tsk.generator.bld.srcnode.abspath(),env=environ,log=True) From fda4bac6e79a219a0cd02e75bacadc6e74c8b15c Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 02:21:53 -0700 Subject: [PATCH 03/37] fix systemvm zip --- build/package.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/package.xml b/build/package.xml index 01c702f0980..979b8646bb9 100755 --- a/build/package.xml +++ b/build/package.xml @@ -204,6 +204,7 @@ + From 022de34e030a4a5257250c501a90bc07f88eef18 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 02:25:51 -0700 Subject: [PATCH 04/37] another try to fix the deb build --- wscript | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wscript b/wscript index 290798b5984..17a11d34aca 100644 --- a/wscript +++ b/wscript @@ -290,8 +290,9 @@ Utils.discover_ant_targets_and_properties = discover_ant_targets_and_properties # this is NOT a task for a task generator -- it is a plain function. # If you want to use it as a task function in a task generator, use a lambda x: runant("targetname") def runant(tsk): - conf = _getbuildcontext() + environ = dict(os.environ) + depsclasspath = [ os.path.abspath(x) for x in _glob(_join(".","deps","*.jar")) ] environ["CATALINA_HOME"] = tsk.env.TOMCATHOME environ["ANT_HOME"] = _join("tools","ant","apache-ant-1.7.1") if tsk.generator.env.DISTRO == "Windows": @@ -302,7 +303,7 @@ def runant(tsk): else: stanzas = [ _join(environ["ANT_HOME"],"bin","ant"), - "-Dthirdparty.classpath=%s:%s"%(tsk.env.CLASSPATH.replace(os.pathsep,","), conf.env.DEPSCLASSPATH), + "-Dthirdparty.classpath=%s:%s"%(tsk.env.CLASSPATH.replace(os.pathsep,","), pathsep.join(depsclasspath)), ] stanzas += tsk.generator.antargs ret = Utils.exec_command(" ".join(stanzas),cwd=tsk.generator.bld.srcnode.abspath(),env=environ,log=True) From 02b46c5892116f842050fb99a33ce010d5506559 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 04:19:33 -0700 Subject: [PATCH 05/37] final try --- wscript | 5 +---- wscript_build | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/wscript b/wscript index 17a11d34aca..f46217d6e5a 100644 --- a/wscript +++ b/wscript @@ -292,7 +292,6 @@ Utils.discover_ant_targets_and_properties = discover_ant_targets_and_properties def runant(tsk): environ = dict(os.environ) - depsclasspath = [ os.path.abspath(x) for x in _glob(_join(".","deps","*.jar")) ] environ["CATALINA_HOME"] = tsk.env.TOMCATHOME environ["ANT_HOME"] = _join("tools","ant","apache-ant-1.7.1") if tsk.generator.env.DISTRO == "Windows": @@ -303,7 +302,7 @@ def runant(tsk): else: stanzas = [ _join(environ["ANT_HOME"],"bin","ant"), - "-Dthirdparty.classpath=%s:%s"%(tsk.env.CLASSPATH.replace(os.pathsep,","), pathsep.join(depsclasspath)), + "-Dthirdparty.classpath=%s"%(tsk.env.CLASSPATH.replace(os.pathsep,",")), ] stanzas += tsk.generator.antargs ret = Utils.exec_command(" ".join(stanzas),cwd=tsk.generator.bld.srcnode.abspath(),env=environ,log=True) @@ -640,7 +639,6 @@ def rpm(context): shutil.move(tarball,_join(sourcedir,tarball)) specfile = "%s.spec"%APPNAME - Utils.exec_command("mvn install -P deps") checkdeps = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"--nobuild",specfile]+packagever+releasever) dorpm = lambda: c(["rpmbuild","--define","_topdir %s"%outputdir,"-bb",specfile]+buildnumber+prerelease+packagever+releasever) try: checkdeps() @@ -697,7 +695,6 @@ def deb(context): tarball = Scripting.dist('', VERSION) srcdir = "%s/%s-%s"%(outputdir,APPNAME,VERSION) - Utils.exec_command("mvn install -P deps") if _exists(srcdir): shutil.rmtree(srcdir) mkdir_p(outputdir) diff --git a/wscript_build b/wscript_build index 3598880f87f..354dc880a87 100644 --- a/wscript_build +++ b/wscript_build @@ -430,7 +430,9 @@ def build_usage_dir (): Utils.pprint ("GREEN", "Installed files of usage/") - +def install_mvn(): + Utils.exec_command("mvn install -P deps") +install_mvn() # Get started to execute here build_utils_docs () build_jars () From a7349eeefd1051bd7ca3c67787dba2647e1a30a5 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 05:06:06 -0700 Subject: [PATCH 06/37] don't call mvn in waf, so the build will take two steps, one is mvn install, another is waf rpm --- wscript_build | 3 --- 1 file changed, 3 deletions(-) diff --git a/wscript_build b/wscript_build index 354dc880a87..d8c9137a978 100644 --- a/wscript_build +++ b/wscript_build @@ -430,9 +430,6 @@ def build_usage_dir (): Utils.pprint ("GREEN", "Installed files of usage/") -def install_mvn(): - Utils.exec_command("mvn install -P deps") -install_mvn() # Get started to execute here build_utils_docs () build_jars () From cb0eb19bf02e9f46e87023869ee2729af2a00cee Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 7 Sep 2012 13:59:01 +0200 Subject: [PATCH 07/37] waf: Remove debuild, build with dpkg-buildpackage Call dpkg-buildpackage to build the packages WAF no prints an error when ./waf deb is being called so users know they have to use dpkg-buildpackage Before calling dpkg-buildpackage maven has to be called to install the JAR dependencies! --- wscript | 109 +++----------------------------------------------------- 1 file changed, 4 insertions(+), 105 deletions(-) diff --git a/wscript b/wscript index f46217d6e5a..60bc925f4f9 100644 --- a/wscript +++ b/wscript @@ -108,24 +108,6 @@ def getrpmdeps(): deps.add("ant") return deps -def getdebdeps(): - def debdeps(fileset): - for f in fileset: - lines = file(f).readlines() - lines = [ x[len("Build-Depends: "):] for x in lines if x.startswith("Build-Depends") ] - for l in lines: - deps = [ x.strip() for x in l.split(",") ] - for d in deps: - if "%s-"%APPNAME in d: continue - yield d - yield "build-essential" - yield "devscripts" - yield "debhelper" - - deps = set(debdeps(["debian/control"])) - deps.add("ant") - return deps - # CENTOS does not have this -- we have to put this here try: from subprocess import check_call as _check_call @@ -602,6 +584,10 @@ def bindist(ctx): z.close() _chdir(cwd) +@throws_command_errors +def deb(context): + raise Utils.WafError("Debian packages are no longer build with waf. Use dpkg-buildpackage instead.") + @throws_command_errors def rpm(context): buildnumber = Utils.getbuildnumber() @@ -647,74 +633,6 @@ def rpm(context): installrpmdeps(context) dorpm() -@throws_command_errors -def deb(context): - buildnumber = Utils.getbuildnumber() - if buildnumber: buildnumber = ["--set-envvar=BUILDNUMBER=%s"%buildnumber] - else: buildnumber = [] - - if Options.options.VERNUM: - VERSION = Options.options.VERNUM - else: - VERSION = SHORTVERSION - - version = ["--set-envvar=PACKAGEVERSION=%s"%VERSION] - - if Options.options.PRERELEASE: - if not buildnumber: - raise Utils.WafError("Please specify a build number to go along with --prerelease") - # version/release numbers are read by dpkg-buildpackage from line 1 of debian/changelog - # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version - tempchangelog = """%s (%s-~%s%s) unstable; urgency=low - - * Automatic prerelease build - - -- Automated build system %s"""%( - APPNAME, - VERSION, - Utils.getbuildnumber(), - Options.options.PRERELEASE, - email.Utils.formatdate(time.time()) - ) - else: - tempchangelog = """%s (%s-1) stable; urgency=low - - * Automatic release build - - -- Automated build system %s"""%( - APPNAME, - VERSION, - email.Utils.formatdate(time.time()) - ) - - # FIXME wrap the source tarball in POSIX locking! - if not Options.options.blddir: outputdir = _join(context.curdir,blddir,"debbuild") - else: outputdir = _join(_abspath(Options.options.blddir),"debbuild") - Utils.pprint("GREEN","Building DEBs") - - tarball = Scripting.dist('', VERSION) - srcdir = "%s/%s-%s"%(outputdir,APPNAME,VERSION) - - - if _exists(srcdir): shutil.rmtree(srcdir) - mkdir_p(outputdir) - - f = tarfile.open(tarball,'r:bz2') - f.extractall(path=outputdir) - if tempchangelog: - f = file(_join(srcdir,"debian","changelog"),"w") - f.write(tempchangelog) - f.flush() - f.close() - - checkdeps = lambda: c(["dpkg-checkbuilddeps"],srcdir) - dodeb = lambda: c(["debuild",'-e','WAFCACHE','--no-lintian', '--no-tgz-check']+buildnumber+version+["-us","-uc"],srcdir) - try: checkdeps() - except (CalledProcessError,OSError),e: - Utils.pprint("YELLOW","Dependencies might be missing. Trying to auto-install them...") - installdebdeps(context) - dodeb() - def uninstallrpms(context): """uninstalls any Cloud Stack RPMs on this system""" Utils.pprint("GREEN","Uninstalling any installed RPMs") @@ -722,21 +640,10 @@ def uninstallrpms(context): Utils.pprint("BLUE",cmd) system(cmd) -def uninstalldebs(context): - """uninstalls any Cloud Stack DEBs on this system""" - Utils.pprint("GREEN","Uninstalling any installed DEBs") - cmd = "dpkg -l '%s-*' | grep ^i | awk '{ print $2 } ' | xargs aptitude purge -y"%APPNAME - Utils.pprint("BLUE",cmd) - system(cmd) - def viewrpmdeps(context): """shows all the necessary dependencies to build the RPM packages of the stack""" for dep in getrpmdeps(): print dep -def viewdebdeps(context): - """shows all the necessary dependencies to build the DEB packages of the stack""" - for dep in getdebdeps(): print dep - @throws_command_errors def installrpmdeps(context): """installs all the necessary dependencies to build the RPM packages of the stack""" @@ -745,14 +652,6 @@ def installrpmdeps(context): Utils.pprint("BLUE"," ".join(runnable)) _check_call(runnable) -@throws_command_errors -def installdebdeps(context): - """installs all the necessary dependencies to build the DEB packages of the stack""" - runnable = ["sudo","aptitude","install","-y"]+list( [ x.split()[0] for x in getdebdeps() ] ) - Utils.pprint("GREEN","Installing DEB build dependencies") - Utils.pprint("BLUE"," ".join(runnable)) - _check_call(runnable) - @throws_command_errors def deploydb(ctx,virttech=None): if not virttech: raise Utils.WafError('use deploydb_xenserver, deploydb_vmware or deploydb_kvm rather than deploydb') From 664927948a3b2cf10320221db6247a4c20887ac2 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 7 Sep 2012 16:18:46 +0200 Subject: [PATCH 08/37] debian: Fix dependencies We depend on more packages and not ship these JAR files ourselfs --- debian/cloud-deps.install | 4 ---- debian/control | 6 +++--- wscript_configure | 1 + 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/debian/cloud-deps.install b/debian/cloud-deps.install index e11f7e034ad..370f5e2060d 100644 --- a/debian/cloud-deps.install +++ b/debian/cloud-deps.install @@ -15,9 +15,6 @@ # specific language governing permissions and limitations # under the License. -/usr/share/java/commons-codec-1.6.jar -/usr/share/java/commons-dbcp-1.4.jar -/usr/share/java/commons-pool-1.6.jar /usr/share/java/backport-util-concurrent-3.1.jar /usr/share/java/ehcache-1.5.0.jar /usr/share/java/mail-1.4.jar @@ -30,7 +27,6 @@ /usr/share/java/xmlrpc-client-3.*.jar /usr/share/java/jstl-1.2.jar /usr/share/java/axis2-1.5.1.jar -/usr/share/java/commons-discovery-0.5.jar /usr/share/java/wsdl4j-1.6.2.jar /usr/share/java/bcprov-jdk16-1.46.jar /usr/share/java/jsch-0.1.42.jar diff --git a/debian/control b/debian/control index e730becef4a..4a6399c0869 100644 --- a/debian/control +++ b/debian/control @@ -11,7 +11,7 @@ Provides: vmops-deps Conflicts: vmops-deps Replaces: vmops-deps Architecture: any -Depends: openjdk-6-jre +Depends: openjdk-6-jre, libcommons-discovery-java (>= 0.5), libcommons-dbcp-java (>= 1.4), libcommons-pool-java (>= 1.5.6), libcommons-codec-java (>= 1.5) Description: CloudStack library dependencies This package contains a number of third-party dependencies not shipped by distributions, required to run the CloudStack @@ -86,7 +86,7 @@ Provides: vmops-client Conflicts: vmops-client Replaces: vmops-client Architecture: any -Depends: openjdk-6-jre, cloud-deps (= ${source:Version}), cloud-utils (= ${source:Version}), cloud-server (= ${source:Version}), cloud-client-ui (= ${source:Version}), cloud-setup (= ${source:Version}), cloud-python (= ${source:Version}), tomcat6, libws-commons-util-java, libcommons-dbcp-java, libcommons-collections-java, libcommons-httpclient-java, sysvinit-utils, chkconfig, sudo, jsvc, python-mysqldb, python-paramiko, augeas-tools, genisoimage, cloud-system-iso, libmysql-java (>= 5.1) +Depends: openjdk-6-jre, cloud-deps (= ${source:Version}), cloud-utils (= ${source:Version}), cloud-server (= ${source:Version}), cloud-client-ui (= ${source:Version}), cloud-setup (= ${source:Version}), cloud-python (= ${source:Version}), tomcat6, libws-commons-util-java, sysvinit-utils, chkconfig, sudo, jsvc, python-mysqldb, python-paramiko, augeas-tools, genisoimage, cloud-system-iso, libmysql-java (>= 5.1) Description: CloudStack client The CloudStack management server is the central point of coordination, management, and intelligence in the CloudStack Cloud Stack. This package @@ -119,7 +119,7 @@ Provides: vmops-agent Conflicts: vmops-agent Replaces: vmops-agent Architecture: any -Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), libcommons-httpclient-java, libcommons-collections-java, libcommons-dbcp-java, libcommons-pool-java, libcommons-logging-java, libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, ebtables, vlan, libcglib-java, libcommons-httpclient-java, libservlet2.5-java, liblog4j1.2-java, libjna-java, wget, jsvc, lsb-base (>= 3.2) +Depends: openjdk-6-jre, cloud-utils (= ${source:Version}), cloud-core (= ${source:Version}), cloud-agent-deps (= ${source:Version}), python, cloud-python (= ${source:Version}), cloud-agent-libs (= ${source:Version}), cloud-agent-scripts (= ${source:Version}), libvirt0, sysvinit-utils, chkconfig, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, ebtables, vlan, libcglib-java, libcommons-httpclient-java, libservlet2.5-java, liblog4j1.2-java, libjna-java, wget, jsvc, lsb-base (>= 3.2) Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in a CloudStack powered cloud. Install this package if this computer diff --git a/wscript_configure b/wscript_configure index 2b253cf1c25..8077cc52c33 100644 --- a/wscript_configure +++ b/wscript_configure @@ -42,6 +42,7 @@ systemjars = { "commons-collections.jar", # "commons-daemon.jar", "commons-dbcp.jar", + "commons-codec.jar", "commons-logging.jar", "commons-logging-api.jar", "commons-pool.jar", From e77937d1cf0acfcdf09f90edb181a8f4ae4233c3 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 7 Sep 2012 16:20:17 +0200 Subject: [PATCH 09/37] debian: Fix homepage and maintainer We might want to change the maintainer to the dev list? --- debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 4a6399c0869..09f33772b0b 100644 --- a/debian/control +++ b/debian/control @@ -1,10 +1,10 @@ Source: cloud Section: libs Priority: extra -Maintainer: Manuel Amador (Rudd-O) +Maintainer: Wido den Hollander Build-Depends: debhelper (>= 7), openjdk-6-jdk, tomcat6, libws-commons-util-java, libcommons-dbcp-java, libcommons-collections-java, libcommons-httpclient-java, libservlet2.5-java, genisoimage, python-mysqldb Standards-Version: 3.8.1 -Homepage: http://techcenter.cloud.com/software/cloudstack +Homepage: http://www.cloudstack.org/ Package: cloud-deps Provides: vmops-deps From 975b16775d9537676942a5ecb155f0e235b12e36 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 12:05:23 -0400 Subject: [PATCH 10/37] Fixed artifact names in build_asf script --- tools/build/build_asf.sh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/build/build_asf.sh b/tools/build/build_asf.sh index f9e05dbbf41..d3354c14939 100755 --- a/tools/build/build_asf.sh +++ b/tools/build/build_asf.sh @@ -54,7 +54,7 @@ done shift `expr $OPTIND - 1` if [ $version == 'TESTBUILD' ]; then - echo >&2 "A version must be specified with the -v option: build_asf.sh -v 4.0.0RC1" + echo >&2 "A version must be specified with the -v option: build_asf.sh -v 4.0.0.RC1" exit 1 fi @@ -81,19 +81,19 @@ fi cp $sourcedir/KEYS $outputdir/KEYS cd $sourcedir -git archive --format=tar.gz --prefix=$version/ $branch > $outputdir/cloudstack-source-$version.tar.gz -git archive --format=zip --prefix=$version/ $branch > $outputdir/cloudstack-source-$version.zip +git archive --format=tar.gz --prefix=$version/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.tar.gz +git archive --format=zip --prefix=$version/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.zip cd $outputdir -gpg -v --armor --output cloudstack-source-$version.tar.gz.asc --detach-sig cloudstack-source-$version.tar.gz -gpg -v --armor --output cloudstack-source-$version.zip.asc --detach-sig cloudstack-source-$version.zip -gpg -v --print-md MD5 cloudstack-source-$version.tar.gz > cloudstack-source-$version.tar.gz.md5 -gpg -v --print-md MD5 cloudstack-source-$version.zip > cloudstack-source-$version.zip.md5 -gpg -v --print-md SHA512 cloudstack-source-$version.tar.gz > cloudstack-source-$version.tar.gz.sha -gpg -v --print-md SHA512 cloudstack-source-$version.zip > cloudstack-source-$version.zip.sha +gpg -v --armor --output apache-cloudstack-$version-incubating-src.tar.gz.asc --detach-sig apache-cloudstack-$version-incubating-src.tar.gz +gpg -v --armor --output apache-cloudstack-$version-incubating-src.zip.asc --detach-sig apache-cloudstack-$version-incubating-src.zip +gpg -v --print-md MD5 apache-cloudstack-$version.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.md5 +gpg -v --print-md MD5 apache-cloudstack-$version.zip > apache-cloudstack-$version-incubating-src.zip.md5 +gpg -v --print-md SHA512 apache-cloudstack-$version.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.sha +gpg -v --print-md SHA512 apache-cloudstack-$version.zip > apache-cloudstack-$version-incubating-src.zip.sha -gpg -v --verify cloudstack-source-$version.tar.gz.asc cloudstack-source-$version.tar.gz -gpg -v --verify cloudstack-source-$version.zip.asc cloudstack-source-$version.zip +gpg -v --verify apache-cloudstack-$version.tar.gz.asc apache-cloudstack-$version-incubating-src.tar.gz +gpg -v --verify apache-cloudstack-$version.zip.asc apache-cloudstack-$version-incubating-src.zip if [ $tag == 'yes' ]; then cd $sourcedir From 6ec623d2d529cf12b1bf9d73f9c94b58744cc74c Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 13:36:09 -0400 Subject: [PATCH 11/37] Fixed file names in the build_asf.sh script --- tools/build/build_asf.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/build/build_asf.sh b/tools/build/build_asf.sh index d3354c14939..2127d4bffa0 100755 --- a/tools/build/build_asf.sh +++ b/tools/build/build_asf.sh @@ -87,10 +87,10 @@ git archive --format=zip --prefix=$version/ $branch > $outputdir/apache-cloudsta cd $outputdir gpg -v --armor --output apache-cloudstack-$version-incubating-src.tar.gz.asc --detach-sig apache-cloudstack-$version-incubating-src.tar.gz gpg -v --armor --output apache-cloudstack-$version-incubating-src.zip.asc --detach-sig apache-cloudstack-$version-incubating-src.zip -gpg -v --print-md MD5 apache-cloudstack-$version.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.md5 -gpg -v --print-md MD5 apache-cloudstack-$version.zip > apache-cloudstack-$version-incubating-src.zip.md5 -gpg -v --print-md SHA512 apache-cloudstack-$version.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.sha -gpg -v --print-md SHA512 apache-cloudstack-$version.zip > apache-cloudstack-$version-incubating-src.zip.sha +gpg -v --print-md MD5 apache-cloudstack-$version-incubating-src.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.md5 +gpg -v --print-md MD5 apache-cloudstack-$version-incubating-src.zip > apache-cloudstack-$version-incubating-src.zip.md5 +gpg -v --print-md SHA512 apache-cloudstack-$version-incubating-src.tar.gz > apache-cloudstack-$version-incubating-src.tar.gz.sha +gpg -v --print-md SHA512 apache-cloudstack-$version-incubating-src.zip > apache-cloudstack-$version-incubating-src.zip.sha gpg -v --verify apache-cloudstack-$version.tar.gz.asc apache-cloudstack-$version-incubating-src.tar.gz gpg -v --verify apache-cloudstack-$version.zip.asc apache-cloudstack-$version-incubating-src.zip From a7b77f33169fd39d100cdf6fa1965341f3e24b53 Mon Sep 17 00:00:00 2001 From: frank Date: Fri, 7 Sep 2012 11:03:01 -0700 Subject: [PATCH 12/37] remove wrong storage network ip checking when setting internal ip route in NFS secondary storage resource. The bug prevent vmware setting static route to vcenter --- .../resource/NfsSecondaryStorageResource.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index a0873abbf95..155210df499 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -124,6 +124,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private String _storageIp; private String _storageNetmask; private String _storageGateway; + private List nfsIps = new ArrayList(); final private String _parent = "/mnt/SecStorage"; final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; @@ -611,6 +612,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S configCerts(cmd.getCerts()); + nfsIps.add(nfsHostIp); return new SecStorageSetupAnswer(dir); } catch (Exception e) { String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); @@ -730,6 +732,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S boolean success = true; StringBuilder result = new StringBuilder(); for (String cidr: cmd.getAllowedInternalSites()) { + if (nfsIps.contains(cidr)) { + /* + * if the internal download ip is the same with secondary storage ip, adding internal sites will flush + * ip route to nfs through storage ip. + */ + continue; + } String tmpresult = allowOutgoingOnPrivate(cidr); if (tmpresult != null) { result.append(", ").append(tmpresult); @@ -814,10 +823,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return "Error in allowing outgoing to " + destCidr + ", err=" + result; } - if (_storageIp == null) { - /* only set route when no storage network present */ - addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr); - } + addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, destCidr); return null; } From 75665f5b9583678fbb28b4949b6145fde498213a Mon Sep 17 00:00:00 2001 From: David Nalley Date: Fri, 7 Sep 2012 14:12:32 -0400 Subject: [PATCH 13/37] fixing line endings --- .../ConsoleProxyAuthenticationResult.java | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java index 6ed211a2d2f..0b9f797642b 100644 --- a/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java +++ b/agent/src/com/cloud/agent/resource/consoleproxy/ConsoleProxyAuthenticationResult.java @@ -14,67 +14,67 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.agent.resource.consoleproxy; - -public class ConsoleProxyAuthenticationResult { - private boolean success; - private boolean isReauthentication; - private String host; - private int port; - private String tunnelUrl; - private String tunnelSession; - - public ConsoleProxyAuthenticationResult() { - success = false; - isReauthentication = false; - port = 0; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public boolean isReauthentication() { - return isReauthentication; - } - - public void setReauthentication(boolean isReauthentication) { - this.isReauthentication = isReauthentication; - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getTunnelUrl() { - return tunnelUrl; - } - - public void setTunnelUrl(String tunnelUrl) { - this.tunnelUrl = tunnelUrl; - } - - public String getTunnelSession() { - return tunnelSession; - } - - public void setTunnelSession(String tunnelSession) { - this.tunnelSession = tunnelSession; - } -} +package com.cloud.agent.resource.consoleproxy; + +public class ConsoleProxyAuthenticationResult { + private boolean success; + private boolean isReauthentication; + private String host; + private int port; + private String tunnelUrl; + private String tunnelSession; + + public ConsoleProxyAuthenticationResult() { + success = false; + isReauthentication = false; + port = 0; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public boolean isReauthentication() { + return isReauthentication; + } + + public void setReauthentication(boolean isReauthentication) { + this.isReauthentication = isReauthentication; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getTunnelUrl() { + return tunnelUrl; + } + + public void setTunnelUrl(String tunnelUrl) { + this.tunnelUrl = tunnelUrl; + } + + public String getTunnelSession() { + return tunnelSession; + } + + public void setTunnelSession(String tunnelSession) { + this.tunnelSession = tunnelSession; + } +} From ff81d0000e6508e7b8e21af52d9108e038900b24 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 14:15:14 -0400 Subject: [PATCH 14/37] Resolving CLOUDSTACK-49 : Correct the source tar.gz and zip extract folder names to match the release artifact name. --- tools/build/build_asf.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/build/build_asf.sh b/tools/build/build_asf.sh index 2127d4bffa0..9d05f177247 100755 --- a/tools/build/build_asf.sh +++ b/tools/build/build_asf.sh @@ -81,8 +81,8 @@ fi cp $sourcedir/KEYS $outputdir/KEYS cd $sourcedir -git archive --format=tar.gz --prefix=$version/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.tar.gz -git archive --format=zip --prefix=$version/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.zip +git archive --format=tar.gz --prefix=apache-cloudstack-$version-incubating-src/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.tar.gz +git archive --format=zip --prefix=apache-cloudstack-$version-incubating-src/ $branch > $outputdir/apache-cloudstack-$version-incubating-src.zip cd $outputdir gpg -v --armor --output apache-cloudstack-$version-incubating-src.tar.gz.asc --detach-sig apache-cloudstack-$version-incubating-src.tar.gz From 2afd076921ecb04a6fb078413c66074f92a51c3e Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 14:24:26 -0400 Subject: [PATCH 15/37] CLOUDSTACK-48 : Removing stale documentation --- agent/doc/README-iscsi.txt | 247 ------------------------------------- agent/doc/README.txt | 211 ------------------------------- 2 files changed, 458 deletions(-) delete mode 100644 agent/doc/README-iscsi.txt delete mode 100644 agent/doc/README.txt diff --git a/agent/doc/README-iscsi.txt b/agent/doc/README-iscsi.txt deleted file mode 100644 index 03e6d00d4d1..00000000000 --- a/agent/doc/README-iscsi.txt +++ /dev/null @@ -1,247 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. - -0. Contents -=========== -../sbin/vnetd: userspace daemon that runs the vnet -../module/2.6.18/vnet_module.ko: kernel module (alternative to vnetd) -../vnetd.sh: init script for vnet -../vn: helper script to create vnets - -../id_rsa: the private key used to ssh to the routing domain - -createvm.sh: clones a vm image from a given template -mountvm.sh: script to mount a remote (nfs) image directory -runvm.sh: script to run a vm -rundomr.sh: script to run a routing domain (domR) for a given vnet -listvmdisk.sh: lists disks belonging to a vm -createtmplt.sh: installs a template -listvmdisksize.sh: lists actuala and total usage per disk -../ipassoc.sh: associate / de-associate a public ip with an instance -../firewall.sh: add or remove firewall rules -stopvm.sh: stop the vm and remove the entry from xend -../delvm.sh: delete the vm image from zfs -../listclones.sh: list all filesystems that are clones under a parent fs - -1. Install -========== -On the hosts that run the customer vms as well as the domR -a) Copy vn to /usr/sbin on dom0 -b) Copy module/2.6.18/vnet_module.ko to /lib/modules/`uname -r`/kernel -c) Run repos/vmdev/xen/xen-3.3.0/tools/vnet/examples/vnet-insert -Ensure that all iptables rules are flushed from domO before starting any domains -(use iptables -F) -d) Ensure that the ISCSI initiator is installed (yum install iscsi*) - - -2. Creating /deleting a vm image on Solaris ZFS -================ -The template image consists of a filesystem to hold kernel and ramdisk (linux) -or the pygrub file (linux) or nothing (windows). Contained within the template -filesystem (but not visible using 'ls') is the root volume. - -Use the createvm script to clone a template snapshot. For example: -./createvm.sh -t tank/volumes/demo/template/public/os/centos52-x86_64 -d /tank/volumes/demo/template/public/datadisk/ext3-8g -i /tank/demo/vm/chiradeep/i0007 -u /tank/demo/vm/chiradeep - -t: the template fs snapshot - -i: the target clone fs - -u: the user's fs under which the clone will be created. If the user fs does not exist, it will be created. - -d: the disk fs to be cloned under the image dir specified by -i -Once this is created, use the listvmdisk.sh to list the disks: -listvmdisk.sh -i tank/demo/vm/chiradeep/i0007 -r (for the root disk) -listvmdisk.sh -i tank/demo/vm/chiradeep/i0007 -w (for the data disk) -listvmdisk.sh -i tank/demo/vm/chiradeep/i0007 -d (for the data disks) - -This outputs the local target name (zfs name) and the ISCSI target name -separated by a comma: -tank/demo/vm/chiradeep/i0007/datadisk1-ext3-8g,iqn.1986-03.com.sun:02:0b6c18c9-7a13-e7c9-ce78-91af20023bb3 - -The local target name can be used to list total (-t)and actual(-a) disk usage: -./listvmdisksize.sh -d tank/demo/vm/chiradeep/i0007/datadisk1-ext3-8g -t -8589934592 - -Use the delvm.sh script to delete an instance. For example: -./delvm.sh -u tank/demo/vm/chiradeep -i tank/demo/vm/chiradeep/i0007 - -i: the instance fs to delete - -u: the user fs to delete -Either -i or -u or both can be supplied. - -Use the listclones.sh script to list all clones under a parent fs: -./listclones.sh -p tank/demo/vm - -3. Mounting an image -================== -The image directory resides on the NFS server, you can mount it with the -mountvm.sh script. For example: -./mountvm.sh -m -h 192.168.1.248 -t iqn.1986-03.com.sun:02:bf65dcfd-42b5-6e0e-e08e-99ae311b39ba -l /images/chiradeep/i0005 -n centos52 -r tank/demo/vm/chiradeep/i0005 -1 iqn.1986-03.com.sun:02:6d505eee-bf64-6729-e362-bab6c148bbc8 - -h : the nfs/iscsi server host - -l : the local directory - -r : the remote directory - -n : the vm name (the same name used in runvm or rundomr) - -r : the iscsi target name for the root volume (see listvmdisk above) - -w : the iscsi target name for the swap volume (see listvmdisk above) - -1 : the iscsi target name for the datadisk volume (see listvmdisk above) - [-m | -u] : mount or unmount - -4. Routing Domain (domR) -======================= -The routing domain for a customer needs to be started before any other VM in that vnet can start. To start a routing domain, for example: -./rundomr.sh -v 0008 -m 128 -i 192.168.1.33 -g 65.37.141.1 -a aa:00:00:05:00:33 -l "domR-vnet0008" -A 06:01:02:03:04:05 -p 02:01:02:03:04:05 -n 255.255.255.0 -I 65.37.141.33 -N 255.255.255.128 -b eth1 -d "dns1=192.168.1.254 dns2=207.69.188.186 domain=vmops.org" /images/chiradeep/router - -v : the is the 16-bit vnet-id specified in 4 hex characters - -m : the ram size for the domain in megabytes (128 is usually sufficient) - -a : the mac address of the eth0 of the domR - -A : the mac address of the eth1 of the domR - -p : the mac address of the eth2 of the domR - -i : the eth1 ip address in the datacenter LAN (e.g., 192.168.1.33) - -n : the netmask of eth1 - -I : the eth2 ip address in the public LAN (e.g., 65.37.141.33) - -N : the netmask of eth2 (e.g., 65.37.141.128) - -b : the Xen bridge (typ.eth1) that eth2 has to be enslaved to (public LAN) - -g : the default gateway in the public subnet (e.g., 65.37.141.1) - -l : the vm name for the doMR - -d : nameserver information in the format shown in the example -Note: -d option requires template tank/demo/template/public/t100001@12_16_2008 -or later - -5. Starting a vm -================ -The VM files are assumed to exist in a single image directory with the following conventions: - a) The kernel file begins with vmlinuz (e.g. vmlinuz-2.6.18.8-xen) (Linux) - b) The root volume begins with vmi-root (e.g.,vmi-root-centos52-x86_64-pv) - c) The data partition begins with datadisk1 (e.g., datadisk1-ext3-8g) - d) The swap partition contains "swap" (e.g., fedora-swap) (Linux only) - -If booting Linux using pygrub, only the root and data files are needed. An -empty file called 'pygrub' must be placed in the image directory - -To run the vm, see the following example -/runvm.sh -v 0005 -i 10.1.1.56 -m 256 -g 192.168.1.33 -a 02:00:00:05:00:56 -l "centos5-2" -c 11 -n 2 -u 66 /images/chiradeep/i0007 - - -v : the is the 16-bit vnet-id specified in 4 hex characters - -i : this is the host ip address in the 10.x.y.z subnet (cannot be 10.1.1.1) - -m : the ram size for the domain in megabytes - -g : the eth1 ip address of the routing domain - -a : the mac address of the eth0 of the vm - -l : the vm name. This is also the hostname, ensure it is is a legal hostname - -c : the VNC console id - -w : the VNC password. If not specified, defaults to 'password' - -n : the number of VCPUs (eq to number of cores) to allocate (default all) - -u : the percentage of one VCPU to allocate (integer) (default no cap) - : the absolute path of the directory holding the VM files/volumes - -The vncviewer can connect to the eth0 ip of dom0 and the specified vnc console number (e.g., 192.168.1.125:11). -The 'n' and 'u' parameters depends on the physical CPU of the host and the -number of compute units requested. For example, lets say 1 compute unit = 1Ghz -and the physical CPU is a quad-core CPU running at 3.0 Ghz. To request 2 cores -running 1 compute unit each, n = 2 and u= 2 x (1/3)*100 - -6. Associate a public Ip with a domR (source NAT) -=========================================== -The example below shows how to associate the public ip 65.37.141.33 the -routing domain. This has to be run on the dom0 of the host hosting the -routing domain. - -ipassoc.sh -A -r domR-vnet0007 -i 192.168.1.32 -l 65.37.141.33 -a 06:01:02:03:06:05 - -A|-D: create or delete an association - -r: the name (label) of the routing domain - -i: the eth1 ip of the routing domain - -a: the mac address of eth2 in the routing domain (not required for -D) - -l: the public ip to be used for source NAT - -7. Firewall rules -================= -Each instance can have firewall rules associated to allow -some ports through. By default, when created, an instance has all ports and -protocols blocked. In the following example, the 10.1.1.155 instance gets ssh -traffic and icmp pings opened up: -firewall.sh -A -i 192.168.1.133 -P tcp -p 22 -r 10.1.1.155 -l 65.37.141.33 -d -22 -firewall.sh -A -i 192.168.1.133 -P icmp -t echo-request -r 10.1.1.155 -l -65.37.141.33 - -A|-D: add or delete a rule - -i: the eth1 ip of the routing domain - -r: the local eth0 ip of the target instance - -l: the public ip - -P: the protocol (tcp, udp, icmp) - -t: (for icmp) the icmp type - -p: (for tcp and udp) the port (port range in the form of a:b) - -d: (for tcp and udp) the target port (port range in the form of a:b) - -8. Stopping and restarting a VM -=============================== -You can use 'xm reboot vmname' to reboot the VM. -To stop it (and delete it from Xend's internal database), use -stopvm.sh -l -This will not remove the vnet however. -The stopvm script will NOT attempt to umount the root and data disks as well -To explicitly unmount the root disk data disks from the NFS server, run -this on dom0: -mountvm.sh -u -l /images/u00000002/i0003 - -u: (no arguments) - -l: the local directory on the compute server - -9. Vnet cleanup -=============== -When you kill the vnet task, all vnif* interfaces will disappear but the -bridges will linger. -You can use vnetcleanup.sh to clean up the vnet -vnetcleanup.sh -a will clean up all vnets -vnetcleanup.sh -v 0005 will only cleanup vnet0005. - -10. VM Image Cleanup -=================== -On ZFS, run delvm.sh, for example: - ./delvm.sh -u tank/demo/vm/u00000003 -i tank/demo/vm/u00000003/i0001 - -u: the user fs (optional) - -i: the instance fs (optional) - -11. Template installation -========================= -Template installation involves copying the image file of the rootdisk to a -iscsi volume. For example: -createtmplt.sh -t rpool/volumes/demo/template/public/os/ubuntu8 -f -/rpool/volumes/demo/template/public/download/ubuntu8/ubuntu8.0.img -n ubuntu8 -s 12G - -t: the filesystem (created if non-existent) where the volume will be mounted - -f: the absolute path to the file containing the root disk image - -n: the name of the template. The create volume will be vmi-root-$name - -s: the size in gigabytes for the volume - -h: if a hvm image - -12. Mapping iscsi target names to VM names -========================================== -The mapiscsi.sh script maps iscsi names of targets logged in to by the routing -host/compute host: -[root@r-1-1-1 iscsi]# ./mapiscsi.sh -iqn.1986-03.com.sun:02:ef4942ec-9f7e-4d71-e994-bb670867053e r-870-TEST-0186-root -iqn.1986-03.com.sun:02:599f5cc5-2f90-c1c3-9c5e-fef252345e64 r-870-TEST-0186-swap -iqn.1986-03.com.sun:02:0e893b01-fa32-682e-976d-d15781cf1a44 r-872-TEST-0187-root -iqn.1986-03.com.sun:02:21225d22-479c-4a35-dca0-ad56e60aa6f4 r-872-TEST-0187-swap -iqn.1986-03.com.sun:02:55b1a6d4-d202-e565-ffe1-ee63e4a48210 r-875-TEST-0188-root -iqn.1986-03.com.sun:02:4fac467c-7b63-6ffb-c207-aa35ccecfcd5 r-875-TEST-0188-swap - -If no VM name can be found, the second field is blank - -13. OpenVZ patch workarounds -============================ -The openvz patch eliminates kernel oops related to bride reconfiguration. -However this requires an extra tickle to the bridge to make it actually send -packets to member port. The member port needs to be taken down (ifconfig down) -and up (ifconfig up). -This is done in -a) rundomr.sh -- on creation of vnet bridge, the vnif is taken down and up -b) runvm.sh -- ditto -c) /etc/xen/qemu-ifup -- the interface (tapX.0) is taken down and then up -after the interface is added to the bridge. diff --git a/agent/doc/README.txt b/agent/doc/README.txt deleted file mode 100644 index f36f50314ca..00000000000 --- a/agent/doc/README.txt +++ /dev/null @@ -1,211 +0,0 @@ -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. - -0. Contents -=========== -sbin/vnetd: userspace daemon that runs the vnet -module/2.6.18/vnet_module.ko: kernel module (alternative to vnetd) -vnetd.sh: init script for vnet -vn: helper script to create vnets - -id_rsa: the private key used to ssh to the routing domain - -createvm.sh: clones a vm image from a given template -mountvm.sh: script to mount a remote (nfs) image directory -runvm.sh: script to run a vm -rundomr.sh: script to run a routing domain (domR) for a given vnet -ipassoc.sh: associate / de-associate a public ip with an instance -firewall.sh: add or remove firewall rules -stopvm.sh: stop the vm and remove the entry from xend -delvm.sh: delete the vm image from zfs -loadbalancer.sh: configure the loadbalancer -listclones.sh: list all filesystems that are clones under a parent fs - -1. Install -========== -On the hosts that run the customer vms as well as the domR -a) Copy vn to /usr/sbin on dom0 -Either (vnetd): - 1) Copy sbin/vnetd to /usr/sbin on dom0 - 2) Copy vnetd.sh to /etc/init.d/vnetd on dom0 - 3) run chkconfig vnetd on -OR - 1) Copy module/2.6.18/vnet_module.ko to /lib/modules/`uname -r`/kernel - 2) Run repos/vmdev/xen/xen-3.3.0/tools/vnet/examples/vnet-insert -Ensure that all iptables rules are flushed from domO before starting any domains -(use iptables -F) - - -2. Creating /deleting a vm image on Solaris ZFS -================ -Use the createvm script to clone a template snapshot. For example: -createvm.sh -t tank/template/public/t100001@12_3_2008 -i tank/demo/vm/u00000002/i0001 -u tank/demo/vm/u00000002 -d /tank/demo/template/public/datadisk/ext3-8g - -t: the template fs snapshot - -i: the target clone fs - -u: the user's fs under which the clone will be created. If the user fs does not exist, it will be created. - -d: the disk fs to be cloned under the image dir specified by -i -Once this is created, use the listvmdisk.sh to list the disks: -listvmdisk.sh -i tank/demo/vm/u00000002/i0001 -r (for the root disk) -listvmdisk.sh -i tank/demo/vm/u00000002/i0001 -d (for the data disks) - -Use the delvm.sh script to delete an instance. For example: -./delvm.sh -u tank/demo/vm/u00000003 -i tank/demo/vm/u00000003/i0001 - -i: the instance fs to delete - -u: the user fs to delete -Either -i or -u or both can be supplied. - -Use the listclones.sh script to list all clones under a parent fs: -./listclones.sh -p tank/demo/vm - -3. Mounting an image -================== -If the image directory resides on the NFS server, you can mount it with the -mountvm.sh script. For example: -./mountvm.sh -h sol10-1.lab.vmops.com -l /images/u00000002/i0001 -r -/tank/vm/demo/u00000002/i0001 -m - -h : the nfs server host - -l : the local directory - -r : the remote directory - [-m | -u] : mount or unmount - - -4. Routing Domain (domR) -======================= -The routing domain for a customer needs to be started before any other VM in that vnet can start. To start a routing domain, for example: -./rundomr.sh -v 0008 -m 128 -i 192.168.1.33 -g 65.37.141.1 -a aa:00:00:05:00:33 -l "domR-vnet0008" -A 06:01:02:03:04:05 -p 02:01:02:03:04:05 -n 255.255.255.0 -I 65.37.141.33 -N 255.255.255.128 -b eth1 -d "dns1=192.168.1.254 dns2=207.69.188.186 domain=vmops.org" /images/templates/t100001 - -v : the is the 16-bit vnet-id specified in 4 hex characters - -m : the ram size for the domain in megabytes (128 is usually sufficient) - -a : the mac address of the eth0 of the domR - -A : the mac address of the eth1 of the domR - -p : the mac address of the eth2 of the domR - -i : the eth1 ip address in the datacenter LAN (e.g., 192.168.1.33) - -n : the netmask of eth1 - -I : the eth2 ip address in the public LAN (e.g., 65.37.141.33) - -N : the netmask of eth2 (e.g., 65.37.141.128) - -b : the Xen bridge (typ.eth1) that eth2 has to be enslaved to (public LAN) - -g : the default gateway in the public subnet (e.g., 65.37.141.1) - -l : the vm name for the doMR - -d : nameserver information in the format shown in the example -Note: -d option requires template tank/demo/template/public/t100001@12_16_2008 -or later - -5. Starting a vm -================ -The VM files are assumed to exist in a single image directory with the following conventions: - a) The kernel file begins with vmlinuz (e.g. vmlinuz-2.6.18.8-xen) (Linux) - b) The root filesystem begins with vmi-root (e.g., vmi-root-centos.5-2.64.img) - c) The data partition begins with vmi-data1 (e.g., vmi-data1.img) - d) The swap partition ends with ".swap" (e.g., centos64.swap) (Linux only) - -If booting Linux using pygrub, only the root and data files are needed. An -empty file called 'pygrub' must be placed in the image directory - -To run the vm, see the following example -/runvm.sh -v 0005 -i 10.1.1.122 -m 256 -g 192.168.1.108 -a 02:00:00:05:00:22 -l "centos.5-2.64" -c 11 -n 2 -u 66 /images/u00000002/i0003 - - -v : the is the 16-bit vnet-id specified in 4 hex characters - -i : this is the host ip address in the 10.x.y.z subnet (cannot be 10.1.1.1) - -m : the ram size for the domain in megabytes - -g : the eth1 ip address of the routing domain - -a : the mac address of the eth0 of the vm - -l : the vm name. This is also the hostname, ensure it is is a legal hostname - -c : the VNC console id - -w : the VNC password. If not specified, defaults to 'password' - -n : the number of VCPUs (eq to number of cores) to allocate (default all) - -u : the percentage of one VCPU to allocate (integer) (default no cap) - : the absolute path of the directory holding the VM files - -The vncviewer can connect to the eth0 ip of dom0 and the specified vnc console number (e.g., 192.168.1.125:11). -The 'n' and 'u' parameters depends on the physical CPU of the host and the -number of compute units requested. For example, lets say 1 compute unit = 1Ghz -and the physical CPU is a quad-core CPU running at 3.0 Ghz. To request 2 cores -running 1 compute unit each, n = 2 and u= 2 x (1/3)*100 - -6. Associate a public Ip with a domR (source NAT) -=========================================== -The example below shows how to associate the public ip 65.37.141.33 the -routing domain. This has to be run on the dom0 of the host hosting the -routing domain. - -ipassoc.sh -A -r domR-vnet0007 -i 192.168.1.32 -l 65.37.141.33 -a 06:01:02:03:06:05 - -A|-D: create or delete an association - -r: the name (label) of the routing domain - -i: the eth1 ip of the routing domain - -a: the mac address of eth2 in the routing domain (not required for -D) - -l: the public ip to be used for source NAT - -7. Firewall rules -================= -Each instance can have firewall rules associated to allow -some ports through. By default, when created, an instance has all ports and -protocols blocked. In the following example, the 10.1.1.155 instance gets ssh -traffic and icmp pings opened up: -firewall.sh -A -i 192.168.1.133 -P tcp -p 22 -r 10.1.1.155 -l 65.37.141.33 -d -22 -firewall.sh -A -i 192.168.1.133 -P icmp -t echo-request -r 10.1.1.155 -l -65.37.141.33 - -A|-D: add or delete a rule - -i: the eth1 ip of the routing domain - -r: the local eth0 ip of the target instance - -l: the public ip - -P: the protocol (tcp, udp, icmp) - -t: (for icmp) the icmp type - -p: (for tcp and udp) the port (port range in the form of a:b) - -d: (for tcp and udp) the target port (port range in the form of a:b) - -7.5 Loadbalancer rules -===================== -Loadbalancing is provided by HAProxy running within the routing domain. Because the rules are large and consist of many components, it is expected that the entire HAProxy configuration file is provided to the script. This is copied over to the routing domain and the haproxy process is restarted. -loadbalancer.sh -A -i 192.168.1.35 -l 65.37.141.30 -d 80 -f /tmp/haproxy.cfg -New haproxy instance successfully loaded, stopping previous one. - -A|-D: add or delete a rule - -i: the eth1 ip of the routing domain - -l: the public ip - -d: the target port - -f: the haproxy configuration file - -8. Stopping and restarting a VM -=============================== -You can use 'xm reboot vmname' to reboot the VM. -To stop it (and delete it from Xend's internal database), use -stopvm.sh -l -This will not remove the vnet however. -The stopvm script will attempt to umount the root and data disks as well -To explicitly unmount the root disk data disks from the NFS server, run -this on dom0: -mountvm.sh -u -l /images/u00000002/i0003 - -u: (no arguments) - -l: the local directory on the compute server - -9. Vnet cleanup -=============== -When you kill the vnet task, all vnif* interfaces will disappear but the -bridges will linger. -You can use vnetcleanup.sh to clean up the vnet -vnetcleanup.sh -a will clean up all vnets -vnetcleanup.sh -v 0005 will only cleanup vnet0005. - -10. VM Image Cleanup -=================== -On ZFS, run delvm.sh, for example: - ./delvm.sh -u tank/demo/vm/u00000003 -i tank/demo/vm/u00000003/i0001 - -u: the user fs (optional) - -i: the instance fs (optional) - -10. TODO -======= -5. Automatic install instead of manual steps of (1) From c979425ce317af7af772aa5dbd5f3985c9afba9e Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 14:31:02 -0400 Subject: [PATCH 16/37] CLOUDSTACK-46 : Removing mycloud, due to the agreed on deprecation of that feature. --- agent/bindir/mycloud-setup-agent | 153 ------------------------------- 1 file changed, 153 deletions(-) delete mode 100755 agent/bindir/mycloud-setup-agent diff --git a/agent/bindir/mycloud-setup-agent b/agent/bindir/mycloud-setup-agent deleted file mode 100755 index 30fd9a024bc..00000000000 --- a/agent/bindir/mycloud-setup-agent +++ /dev/null @@ -1,153 +0,0 @@ -#!/usr/bin/python -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -import os -import logging -import sys -import socket -import subprocess -import time - -from cloudutils.cloudException import CloudRuntimeException, CloudInternalException -from cloudutils.utilities import initLoging, bash -from cloudutils.configFileOps import configFileOps -from cloudutils.globalEnv import globalEnv -from cloudutils.networkConfig import networkConfig -from cloudutils.syscfg import sysConfigFactory - -from optparse import OptionParser - -url="http://rightscale-cloudstack.s3.amazonaws.com/kvm/centos/5.4/RightImage_CentOS_5.4_x64_v5.6.34.qcow2.bz2" -destFolder="/mnt/template/tmpl/1/4/" -metaFile="template.properties" - -def getUserInputs(): - print "Welcome to myCloud Setup:" - - mgtSvr = "myagent.cloud.com" - - cfo = configFileOps("/etc/cloud/agent/agent.properties") - oldToken = cfo.getEntry("zone") - if oldToken == "default": - oldToken = "" - zoneToken = raw_input("Please input the Zone Token:[%s]"%oldToken) - - if zoneToken == "": - if oldToken == "": - print "Please input a valid zone token" - exit(1) - zoneToken = oldToken - - try: - defaultNic = networkConfig.getDefaultNetwork() - except: - print "Failed to get default route. Please configure your network to add a default route" - exit(1) - - network = defaultNic.name - - return [mgtSvr, zoneToken, network] - -def downloadTemplate(): - if not os.path.exists(destFolder): - os.makedirs(destFolder) - oldName =url.split("/")[-1] - templateFile=url.split("/")[-1].replace(".bz2","") - - templateFullPath = destFolder + templateFile - metaFullPath = destFolder + metaFile - if os.path.exists(templateFullPath): - if os.path.exists(metaFullPath): - return True - os.remove(templateFullPath) - - print "Need to download myCloud template into your local disk, from " + url + " to " + destFolder + " :" - try: - proc = subprocess.Popen(["/bin/bash", "-c", "wget -O - " + url + " | bunzip2 > " + destFolder + templateFile]) - proc.communicate() - ret = proc.poll() - if ret is None or ret < 0: - raise CloudRuntimeException("Failed to download template") - except KeyboardInterrupt: - if os.path.exists(templateFullPath): - os.remove(templateFullPath) - raise CloudRuntimeException("Downloading process is interrupted") - - file = open(metaFullPath, "w") - physicalSize = os.stat(templateFullPath).st_size - virtualSize = bash("qemu-img info " + templateFullPath + " |grep virtual").getStdout().split("(")[1].split(" ")[0] - cfo = configFileOps(metaFullPath) - cfo.addEntry("filename", templateFile) - cfo.addEntry("id", "4") - cfo.addEntry("qcow2.size", str(physicalSize)) - cfo.addEntry("public", "true") - cfo.addEntry("uniquename", "Rightscale CentOS 5.4") - cfo.addEntry("qcow2.virtualsize", virtualSize) - cfo.addEntry("virtualsize", virtualSize) - cfo.addEntry("hvm", "true") - cfo.addEntry("description", "Rightscale CentOS 5.4") - cfo.addEntry("qcow2", "true") - cfo.addEntry("qcow2.filename", templateFile) - cfo.addEntry("size", str(physicalSize)) - cfo.save() - - -if __name__ == '__main__': - initLoging("/var/log/cloud/setupAgent.log") - - glbEnv = globalEnv() - - glbEnv.mode = "Agent" - glbEnv.agentMode = "myCloud" - parser = OptionParser() - parser.add_option("-z", "--zone-token", dest="zone", help="zone token") - - (options, args) = parser.parse_args() - if options.zone is None: - userInputs = getUserInputs() - glbEnv.mgtSvr = userInputs[0] - glbEnv.zone = userInputs[1] - glbEnv.defaultNic = userInputs[2] - else: - glbEnv.zone = options.zone - try: - defaultNic = networkConfig.getDefaultNetwork() - glbEnv.defaultNic = defaultNic.name - except: - print "Failed to get default route. Please configure your network to have a default route" - sys.exit(2) - - #generate UUID - glbEnv.uuid = configFileOps("/etc/cloud/agent/agent.properties").getEntry("guid") - if glbEnv.uuid == "": - glbEnv.uuid = bash("uuidgen").getStdout() - - print "Starting to configure your system:" - syscfg = sysConfigFactory.getSysConfigFactory(glbEnv) - try: - syscfg.config() - downloadTemplate() - syscfg.svo.stopService("cloud-agent") - syscfg.svo.enableService("cloud-agent") - print "myCloud setup is Done!" - except (CloudRuntimeException,CloudInternalException), e: - print e - print "Try to restore your system:" - try: - syscfg.restore() - except: - pass From d1d9cacbfbd15bc10fb7c199d131d70df8710ae7 Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 14:43:41 -0400 Subject: [PATCH 17/37] CLOUDSTACK-46 : Missed a reference to the mycloud setup script in cloud.spec --- cloud.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/cloud.spec b/cloud.spec index 4bbff9af42c..ab445ff2a62 100644 --- a/cloud.spec +++ b/cloud.spec @@ -554,7 +554,6 @@ fi %attr(0755,root,root) %{_initrddir}/%{name}-agent %attr(0755,root,root) %{_bindir}/%{name}-setup-agent %dir %attr(0770,root,root) %{_localstatedir}/log/%{name}/agent -%attr(0755,root,root) %{_bindir}/mycloud-setup-agent %files cli %{_bindir}/%{name}-tool From 8746e902e4c5ba43c669305c60411b74e207e23f Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 17:03:53 -0400 Subject: [PATCH 18/37] CLOUDSTACK-56 : fixing license headers --- .../com/cloud/bridge/model/BucketPolicyVO.java | 16 ++++++++++++++++ .../cloud/bridge/model/CloudStackAccountVO.java | 16 ++++++++++++++++ .../bridge/model/CloudStackConfigurationVO.java | 16 ++++++++++++++++ .../model/CloudStackServiceOfferingVO.java | 16 ++++++++++++++++ .../com/cloud/bridge/model/MultiPartPartsVO.java | 16 ++++++++++++++++ .../cloud/bridge/model/MultiPartUploadsVO.java | 16 ++++++++++++++++ .../com/cloud/bridge/model/MultipartMetaVO.java | 16 ++++++++++++++++ .../com/cloud/bridge/model/OfferingBundleVO.java | 16 ++++++++++++++++ .../bridge/persist/dao/BucketPolicyDao.java | 16 ++++++++++++++++ .../bridge/persist/dao/CloudStackAccountDao.java | 16 ++++++++++++++++ .../persist/dao/CloudStackAccountDaoImpl.java | 16 ++++++++++++++++ .../persist/dao/CloudStackConfigurationDao.java | 16 ++++++++++++++++ .../dao/CloudStackConfigurationDaoImpl.java | 16 ++++++++++++++++ .../persist/dao/CloudStackSvcOfferingDao.java | 16 ++++++++++++++++ .../com/cloud/bridge/persist/dao/MHostDao.java | 16 ++++++++++++++++ .../cloud/bridge/persist/dao/MHostMountDao.java | 16 ++++++++++++++++ .../bridge/persist/dao/MultiPartPartsDao.java | 16 ++++++++++++++++ .../persist/dao/MultiPartPartsDaoImpl.java | 16 ++++++++++++++++ .../bridge/persist/dao/MultiPartUploadsDao.java | 16 ++++++++++++++++ .../persist/dao/MultiPartUploadsDaoImpl.java | 16 ++++++++++++++++ .../bridge/persist/dao/MultipartMetaDao.java | 16 ++++++++++++++++ .../bridge/persist/dao/MultipartMetaDaoImpl.java | 16 ++++++++++++++++ .../cloud/bridge/persist/dao/OfferingDao.java | 16 ++++++++++++++++ .../com/cloud/bridge/persist/dao/SAclDao.java | 16 ++++++++++++++++ .../com/cloud/bridge/persist/dao/SBucketDao.java | 16 ++++++++++++++++ .../com/cloud/bridge/persist/dao/SHostDao.java | 16 ++++++++++++++++ .../com/cloud/bridge/persist/dao/SMetaDao.java | 16 ++++++++++++++++ .../com/cloud/bridge/persist/dao/SObjectDao.java | 16 ++++++++++++++++ .../cloud/bridge/persist/dao/SObjectItemDao.java | 16 ++++++++++++++++ .../bridge/persist/dao/UserCredentialsDao.java | 16 ++++++++++++++++ 30 files changed, 480 insertions(+) diff --git a/awsapi/src/com/cloud/bridge/model/BucketPolicyVO.java b/awsapi/src/com/cloud/bridge/model/BucketPolicyVO.java index c4be142d5c7..0d41137e6eb 100644 --- a/awsapi/src/com/cloud/bridge/model/BucketPolicyVO.java +++ b/awsapi/src/com/cloud/bridge/model/BucketPolicyVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import javax.persistence.Column; diff --git a/awsapi/src/com/cloud/bridge/model/CloudStackAccountVO.java b/awsapi/src/com/cloud/bridge/model/CloudStackAccountVO.java index 5737abb9e79..940c00621ef 100644 --- a/awsapi/src/com/cloud/bridge/model/CloudStackAccountVO.java +++ b/awsapi/src/com/cloud/bridge/model/CloudStackAccountVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import javax.persistence.Column; diff --git a/awsapi/src/com/cloud/bridge/model/CloudStackConfigurationVO.java b/awsapi/src/com/cloud/bridge/model/CloudStackConfigurationVO.java index 982969f73dd..8500a9b1ef7 100644 --- a/awsapi/src/com/cloud/bridge/model/CloudStackConfigurationVO.java +++ b/awsapi/src/com/cloud/bridge/model/CloudStackConfigurationVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import javax.persistence.Column; diff --git a/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java b/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java index 23e0cc850d2..de2941e23db 100644 --- a/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java +++ b/awsapi/src/com/cloud/bridge/model/CloudStackServiceOfferingVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import javax.persistence.Column; diff --git a/awsapi/src/com/cloud/bridge/model/MultiPartPartsVO.java b/awsapi/src/com/cloud/bridge/model/MultiPartPartsVO.java index d622e47a691..a33fcbb45e0 100644 --- a/awsapi/src/com/cloud/bridge/model/MultiPartPartsVO.java +++ b/awsapi/src/com/cloud/bridge/model/MultiPartPartsVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import java.util.Date; diff --git a/awsapi/src/com/cloud/bridge/model/MultiPartUploadsVO.java b/awsapi/src/com/cloud/bridge/model/MultiPartUploadsVO.java index fd0bb42f4c2..495e9884aef 100644 --- a/awsapi/src/com/cloud/bridge/model/MultiPartUploadsVO.java +++ b/awsapi/src/com/cloud/bridge/model/MultiPartUploadsVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import java.util.Date; diff --git a/awsapi/src/com/cloud/bridge/model/MultipartMetaVO.java b/awsapi/src/com/cloud/bridge/model/MultipartMetaVO.java index ca2b69ee64f..44f8c9779d6 100644 --- a/awsapi/src/com/cloud/bridge/model/MultipartMetaVO.java +++ b/awsapi/src/com/cloud/bridge/model/MultipartMetaVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import javax.persistence.Column; diff --git a/awsapi/src/com/cloud/bridge/model/OfferingBundleVO.java b/awsapi/src/com/cloud/bridge/model/OfferingBundleVO.java index 4c41cff451a..b87681abf7a 100644 --- a/awsapi/src/com/cloud/bridge/model/OfferingBundleVO.java +++ b/awsapi/src/com/cloud/bridge/model/OfferingBundleVO.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.model; import javax.persistence.Column; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDao.java b/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDao.java index f23db439203..081958ea451 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/BucketPolicyDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.BucketPolicyVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDao.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDao.java index bf8c97a2db7..ec3e22c3851 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.CloudStackAccountVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java index be3cd778e40..bca12f6b3e8 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackAccountDaoImpl.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import javax.ejb.Local; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDao.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDao.java index 8c2c1850247..97e76ef765b 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.CloudStackConfigurationVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java index 1e7a70fdba2..c49f612bb43 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackConfigurationDaoImpl.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.sql.Connection; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDao.java b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDao.java index 4b0c9e16a56..47b5f913272 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/CloudStackSvcOfferingDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.CloudStackServiceOfferingVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MHostDao.java b/awsapi/src/com/cloud/bridge/persist/dao/MHostDao.java index a4b65d757f2..dbb56d9e220 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MHostDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MHostDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.MHostVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDao.java b/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDao.java index 7a02c4e884d..b554e424709 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MHostMountDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.MHostMountVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDao.java b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDao.java index 399e820731d..8ffe2ece478 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java index 91e43984d4d..23bee42acc2 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartPartsDaoImpl.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDao.java b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDao.java index 4c52958290b..d77063d1505 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java index b6ad611b28a..ce2928db1c4 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultiPartUploadsDaoImpl.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.ArrayList; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDao.java b/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDao.java index 449ce442dc6..68b77e83381 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java b/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java index cfe56c0dc08..2bcd6260920 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/MultipartMetaDaoImpl.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/OfferingDao.java b/awsapi/src/com/cloud/bridge/persist/dao/OfferingDao.java index c46b015deb7..a41b8af4b54 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/OfferingDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/OfferingDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.OfferingBundleVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SAclDao.java b/awsapi/src/com/cloud/bridge/persist/dao/SAclDao.java index 5a5be6e856a..4c62e111190 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SAclDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SAclDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SBucketDao.java b/awsapi/src/com/cloud/bridge/persist/dao/SBucketDao.java index 0f4220019d1..2298479b05a 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SBucketDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SBucketDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SHostDao.java b/awsapi/src/com/cloud/bridge/persist/dao/SHostDao.java index fc8865c90f5..ffe8ca95330 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SHostDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SHostDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.SHostVO; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SMetaDao.java b/awsapi/src/com/cloud/bridge/persist/dao/SMetaDao.java index 225138e6351..65f66a258ea 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SMetaDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SMetaDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SObjectDao.java b/awsapi/src/com/cloud/bridge/persist/dao/SObjectDao.java index 42fcd02260d..1d0de2ee073 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SObjectDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SObjectDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDao.java b/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDao.java index 2258309744d..aead893a4f0 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/SObjectItemDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import java.util.List; diff --git a/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDao.java b/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDao.java index c178bf8ef45..5d37da825ee 100644 --- a/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDao.java +++ b/awsapi/src/com/cloud/bridge/persist/dao/UserCredentialsDao.java @@ -1,3 +1,19 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. package com.cloud.bridge.persist.dao; import com.cloud.bridge.model.UserCredentialsVO; From a19d7ab00bebc447cf85f807bc305e59f056a0dd Mon Sep 17 00:00:00 2001 From: David Nalley Date: Fri, 7 Sep 2012 17:32:39 -0400 Subject: [PATCH 19/37] fixing more line encodings --- console-proxy/js/handler.js | 106 ++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/console-proxy/js/handler.js b/console-proxy/js/handler.js index 6b9ac440c48..d22ff079ee6 100644 --- a/console-proxy/js/handler.js +++ b/console-proxy/js/handler.js @@ -17,56 +17,56 @@ specific language governing permissions and limitations under the License. */ -// -// Callback handlers for AJAX viewer -// Author -// Kelven Yang -// 11/18/2009 -// -function onKickoff() { - ajaxViewer.stop(); - $('#toolbar').remove(); - $('#main_panel').html('

This session is terminated because a session for the same VM has been created elsewhere.

'); -} - -function onDisconnect() { - ajaxViewer.stop(); - $('#toolbar').remove(); - $('#main_panel').html('

This session is terminated as the machine you are accessing has terminated the connection.

'); -} - -function onClientError() { - ajaxViewer.stop(); - $('#toolbar').remove(); - $('#main_panel').html('

Client communication error, please retry later.

'); -} - -function onCanvasSizeChange(width, height) { - $('#toolbar').width(width); -} - -function onStatusNotify(status) { - if(status == ajaxViewer.STATUS_SENDING || status == ajaxViewer.STATUS_RECEIVING) - $('#light').removeClass('dark').addClass('bright'); - else - $('#light').removeClass('bright').addClass('dark'); -} - -function sendCtrlAltDel() { - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 45, ajaxViewer.CTRL_KEY | ajaxViewer.ALT_KEY); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 45, ajaxViewer.CTRL_KEY | ajaxViewer.ALT_KEY); -} - -function sendCtrlEsc() { - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 17, 0); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 27, ajaxViewer.CTRL_KEY); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 27, ajaxViewer.CTRL_KEY); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 17, 0); -} - -function sendAltTab() { - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 18, 0); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 9, ajaxViewer.ALT_KEY); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 9, ajaxViewer.ALT_KEY); - ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 18, 0); -} +// +// Callback handlers for AJAX viewer +// Author +// Kelven Yang +// 11/18/2009 +// +function onKickoff() { + ajaxViewer.stop(); + $('#toolbar').remove(); + $('#main_panel').html('

This session is terminated because a session for the same VM has been created elsewhere.

'); +} + +function onDisconnect() { + ajaxViewer.stop(); + $('#toolbar').remove(); + $('#main_panel').html('

This session is terminated as the machine you are accessing has terminated the connection.

'); +} + +function onClientError() { + ajaxViewer.stop(); + $('#toolbar').remove(); + $('#main_panel').html('

Client communication error, please retry later.

'); +} + +function onCanvasSizeChange(width, height) { + $('#toolbar').width(width); +} + +function onStatusNotify(status) { + if(status == ajaxViewer.STATUS_SENDING || status == ajaxViewer.STATUS_RECEIVING) + $('#light').removeClass('dark').addClass('bright'); + else + $('#light').removeClass('bright').addClass('dark'); +} + +function sendCtrlAltDel() { + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 45, ajaxViewer.CTRL_KEY | ajaxViewer.ALT_KEY); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 45, ajaxViewer.CTRL_KEY | ajaxViewer.ALT_KEY); +} + +function sendCtrlEsc() { + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 17, 0); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 27, ajaxViewer.CTRL_KEY); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 27, ajaxViewer.CTRL_KEY); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 17, 0); +} + +function sendAltTab() { + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 18, 0); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_DOWN, 9, ajaxViewer.ALT_KEY); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 9, ajaxViewer.ALT_KEY); + ajaxViewer.sendKeyboardEvent(ajaxViewer.KEY_UP, 18, 0); +} From 24fa14845b69dd1e56b9da6a5b713051f088f049 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 7 Sep 2012 14:35:31 -0700 Subject: [PATCH 20/37] Add KVM to hypervisor types allowed in VPC RB: https://reviews.apache.org/r/6926/ Send-by: Marcus Sorensen --- server/src/com/cloud/network/vpc/VpcManagerImpl.java | 1 + server/src/com/cloud/vm/UserVmManagerImpl.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index d24009ddbe8..08a03b1a181 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -1963,6 +1963,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ List hTypes = new ArrayList(); hTypes.add(HypervisorType.XenServer); hTypes.add(HypervisorType.VMware); + hTypes.add(HypervisorType.KVM); return hTypes; } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 183617667cc..cc48b2f9c12 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2240,7 +2240,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager throw new InvalidParameterValueException("Unable to find network by id " + networkIdList.get(0).longValue()); } if (network.getVpcId() != null) { - //Only XenServer and VmWare hypervisors are supported for vpc networks + //Only XenServer, KVM, and VmWare hypervisors are supported for vpc networks if (!vpcSupportedHTypes.contains(template.getHypervisorType())) { throw new InvalidParameterValueException("Can't create vm from template with hypervisor " + template.getHypervisorType() + " in vpc network " + network); From f9e91a9f967fe159a2ec7a09e4cb457aa8dcbd0c Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 16:31:47 -0700 Subject: [PATCH 21/37] Removing the older xenapi jar and adding an ant target to build one from the source. provided-by : Devdeep Singh --- build/build-cloud.xml | 14 ++++++++++++-- deps/.classpath | 1 - 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/build/build-cloud.xml b/build/build-cloud.xml index 10f4809267b..014c75ba15b 100755 --- a/build/build-cloud.xml +++ b/build/build-cloud.xml @@ -78,6 +78,7 @@ + @@ -129,6 +130,7 @@ + @@ -215,12 +217,20 @@ - + + + + + + + + + - + diff --git a/deps/.classpath b/deps/.classpath index 1376b4fb907..14dd132dae8 100755 --- a/deps/.classpath +++ b/deps/.classpath @@ -40,7 +40,6 @@ under the License. - From b52bd1fc5a00a3e1443e0cd30707ed961ea2a6f3 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 16:36:38 -0700 Subject: [PATCH 22/37] The file scripts/storage/secondary/cloud-install-sys-tmplt had a syntax error, provided-by : Marcus Sorensen --- scripts/storage/secondary/cloud-install-sys-tmplt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt index 55f3d18c93f..d744b56e4d6 100755 --- a/scripts/storage/secondary/cloud-install-sys-tmplt +++ b/scripts/storage/secondary/cloud-install-sys-tmplt @@ -106,7 +106,7 @@ fi if [ "$oflag" != 1 ]; then dbHost=$(sed '/^\#/d' /etc/cloud/management/db.properties | grep 'db.cloud.host' | tail -n 1 | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') fi -if [ "$rflag" != 1]; then +if [ "$rflag" != 1 ]; then dbUser=$(sed '/^\#/d' /etc/cloud/management/db.properties | grep 'db.cloud.username' | tail -n 1 | cut -d "=" -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') fi From 3cfe01d07cefc7094ce4ed2a9dde28c88437b1d1 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 17:03:12 -0700 Subject: [PATCH 23/37] VPC : by default , outgoing traffic is allowed out, once egress rules are added, only traffic specified in those are allowed out, others are blocked --- .../systemvm/debian/config/opt/cloud/bin/vpc_acl.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh index fa57c043570..4ebed3abdf9 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh @@ -126,6 +126,7 @@ acl_entry_for_guest_network() { sudo iptables -I ACL_INBOUND_$dev -p $prot -s $lcidr \ --icmp-type $typecode -j ACCEPT else + let egress++ sudo iptables -t mangle -I ACL_OUTBOUND_$dev -p $prot -d $lcidr \ --icmp-type $typecode -j ACCEPT fi @@ -135,6 +136,7 @@ acl_entry_for_guest_network() { sudo iptables -I ACL_INBOUND_$dev -p $prot -s $lcidr \ $DPORT -j ACCEPT else + let egress++ sudo iptables -t mangle -I ACL_OUTBOUND_$dev -p $prot -d $lcidr \ $DPORT -j ACCEPT fi @@ -199,7 +201,7 @@ fi success=0 acl_chain_for_guest_network - +egress=0 for r in $rules_list do acl_entry_for_guest_network $r @@ -219,6 +221,12 @@ then acl_restore else logger -t cloud "$(basename $0): deleting backup for guest network: $gcidr" + if [ $egress -eq 0 ] + then + sudo iptables -t mangle -A ACL_OUTBOUND_$dev -j ACCEPT 2>/dev/null + else + sudo iptables -t mangle -A ACL_OUTBOUND_$dev -j DROP 2>/dev/null + fi acl_switch_to_new fi unlock_exit $success $lock $locked From 33fdcf104782fc9f0b0ff402d77d013811dfa4ce Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 17:07:10 -0700 Subject: [PATCH 24/37] CS-16261: egress_vmchain doesn't exist in 2.2.*, create it automatically after upgrade --- scripts/vm/hypervisor/xenserver/vmops | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index ed7e7ca8450..79b67e71380 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -1380,10 +1380,20 @@ def network_rules(session, args): cmds.append(iptables) util.SMlog(iptables) - vmchain = chain_name(vm_name) - util.pread2(['iptables', '-F', vmchain]) - egress_vmchain = egress_chain_name(vm_name) - util.pread2(['iptables', '-F', egress_vmchain]) + vmchain = chain_name(vm_name) + try: + util.pread2(['iptables', '-F', vmchain]) + except: + util.SMlog("Ignoring failure to delete chain " + vmchain) + util.pread2(['iptables', '-N', vmchain]) + + egress_vmchain = egress_chain_name(vm_name) + try: + util.pread2(['iptables', '-F', egress_vmchain]) + except: + util.SMlog("Ignoring failure to delete chain " + egress_vmchain) + util.pread2(['iptables', '-N', egress_vmchain]) + for cmd in cmds: util.pread2(cmd) From 4a0e645e28d3a0c1fb563ce9c0070225cd9be4c9 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 17:10:54 -0700 Subject: [PATCH 25/37] CS-16254: passwd_server listen on every interface, but only guest interface is enabled for that port --- patches/systemvm/debian/config/opt/cloud/bin/passwd_server | 3 +-- patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server index 596715e0bd0..7e93b679c6e 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/passwd_server +++ b/patches/systemvm/debian/config/opt/cloud/bin/passwd_server @@ -1,11 +1,10 @@ #!/bin/bash . /etc/default/cloud-passwd-srvr -guestIp=$(ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}') while [ "$ENABLED" == "1" ] do - socat -lf /var/log/cloud.log TCP4-LISTEN:8080,reuseaddr,crnl,bind=$guestIp SYSTEM:"/opt/cloud/bin/serve_password.sh \"\$SOCAT_PEERADDR\"" + socat -lf /var/log/cloud.log TCP4-LISTEN:8080,reuseaddr,crnl,bind=0.0.0.0 SYSTEM:"/opt/cloud/bin/serve_password.sh \"\$SOCAT_PEERADDR\"" rc=$? if [ $rc -ne 0 ] diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh index cb98fd419d0..ee9960c6253 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh @@ -124,6 +124,10 @@ create_guest_network() { sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT sudo iptables -A INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT sudo iptables -A INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT + sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 8080 -j ACCEPT + sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 80 -j ACCEPT + sudo iptables -A INPUT -i $dev -p tcp -m state --state NEW --dport 8080 -j ACCEPT + sudo iptables -A INPUT -i $dev -p tcp -m state --state NEW --dport 80 -j ACCEPT # restore mark from connection mark local tableName="Table_$dev" sudo ip route add $subnet/$mask dev $dev table $tableName proto static @@ -141,6 +145,8 @@ destroy_guest_network() { sudo ip addr del dev $dev $ip/$mask sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT sudo iptables -D INPUT -i $dev -p udp -m udp --dport 53 -j ACCEPT + sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 8080 -j ACCEPT + sudo iptables -D INPUT -i $dev -p tcp -m state --state NEW --dport 80 -j ACCEPT sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark sudo iptables -t nat -A POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip destroy_acl_chain From 56a1da9f1e4cd6f4d7e6592f2b30eb5210edcedd Mon Sep 17 00:00:00 2001 From: Chip Childers Date: Fri, 7 Sep 2012 20:09:40 -0400 Subject: [PATCH 26/37] Correcting NOTICE file to include jquery 1.3.2, as well as some minor character fixes. --- LICENSE | 2 +- NOTICE | 365 ++++++++++++++++++----------------- tools/whisker/descriptor.xml | 25 ++- 3 files changed, 209 insertions(+), 183 deletions(-) diff --git a/LICENSE b/LICENSE index 7ec1f009eb7..210f282912a 100644 --- a/LICENSE +++ b/LICENSE @@ -250,7 +250,7 @@ Within the awsapi directory Within the console-proxy/js directory licensed under the MIT License http://www.opensource.org/licenses/mit-license.php (as follows) - Copyright © 2011, John Resig + Copyright © 2009, John Resig Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/NOTICE b/NOTICE index 9c124abc09f..34bcc3ac367 100644 --- a/NOTICE +++ b/NOTICE @@ -30,6 +30,181 @@ with venue lying in Santa Clara County, California. + For + cloud-javax.persistence-2.0.0.jar + + + EclipseLink 2.0.0 + + Dec 10th, 2009 + + About + + The EclipseLink project's goal is to provide a complete persistence framework + that is both comprehensive and universal. It will run in any Java environment + and read and write objects to virtually any type of data source, including + relational databases, and XML. EclipseLink will focus on providing leading edge + support, including advanced feature extensions, for the dominant persistence + standards for each target data source; Java Persistence API (JPA) for relational + databases, Java API for XML Binding (JAXB) for XML, Service Data Objects (SDO), + and Database Web services (DBWS). + + For tips on getting started with EclipseLink, please see the following + resources: + + EclipseLink 2.0.0 Release Notes Documentation Examples and How To License + + The Eclipse Foundation makes available all content in this plug-in ("Content"). + Unless otherwise indicated below, the Content is provided to you under the terms + and conditions of the Eclipse Public License Version 1.0 ("EPL") and Eclipse + Distribution License Version 1.0 ("EDL"). A copy of the EPL is available at + http://www.eclipse.org/legal/epl-v10.html and a copy of the EDL is available at + http://www.eclipse.org/org/documents/edl-v10.php. For purposes of the EPL, + "Program" will mean the Content. + + If you did not receive this Content directly from the Eclipse Foundation, the + Content is being redistributed by another party ("Redistributor") and different + terms and conditions may apply to your use of any object code in the Content. + Check the Redistributor's license that was provided with the Content. If no such + license exists, contact the Redistributor. Unless otherwise indicated below, the + terms and conditions of the EPL and EDL still apply to any source code in the + Content and such source code may be obtained at http://www.eclipse.org. + + Third Party Content + + The Content includes items that have been sourced from third parties as set out + below. If you did not receive this Content directly from the Eclipse Foundation, + the following is provided for informational purposes only, and you should look + to the Redistributor's license for terms and conditions of use. + + Foundation Dependencies ASM EclipseLink JPA ANTLR Java Persistence API (JPA) 1.0 + - EJB 3.0 Java Persistence API (JPA) 2.0 EARLY ACCESS EclipseLink MOXy Java + Architecture for XML Binding (JAXB) Java Mail Java Activation Framework + Streaming API for XML (StAX) EclipseLink SDO Service Data Objects (SDO) + Utilities Java Connector Xerces WSDL4J 1.6.2 ASM v1.5.3 + + The EclipseLink Project includes ASM for the purpose of byte code weaving. The + AMS library is re-packaged within the source of the project + (org.persistence.eclipse.internal.libraries.asm.*) to avoid version collisions + with other usage of ASM. A custom patch has been added to the ASM 1.5.3 source + to handle an issue with other usages. This fix has also been contributed back to + the ASM project for inclusion in later projects. + + The source code is available within the project's subversion repository. The + binaries are distributed within the eclipselink.jar and in the + org.eclipse.persistence.asm_2.0.0.v*.jar bundle. + + http://asm.objectweb.org/license.html + + Copyright (c) 2000-2005 INRIA, France Telecom, All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. Redistributions in binary form must + reproduce the above copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with the + distribution. Neither the name of the copyright holders nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY + THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE DISCLAIMED. IN NO EVENT + SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OFTHE POSSIBILITY OF SUCH DAMAGE. + + ANTLR v3.0 + + The ANTLR library (license) is included within EclipseLink Project to enable + parsing of the Java Persistence Query language (JP QL). The ANTLR library is re- + packaged within the project in the + org.eclipse.persistence.internal.libraries.antlr.* packages. + + The source is available with the project's subversion repository. The binaries + are distributed within the eclipselink.jar and in the + org.eclipse.persistence.antlr_2.0.0.v*.jar bundle. + + Java Architecture for XML Binding (JAXB) v2.0.5 + + The JAXB libraries distributed under CDDL v1.0 are included within the + EclipseLink Project to enable the MOXY component's implementation of JAXB. + + JAXB Libraries: + + /jlib/moxy/javax.xml.bind_2.1.12.v20090708-1500.jar /jlib/moxy/jaxb-impl.jar + /jlib/moxy/jaxb.xjc.jar Java Persistence (JPA) 1.0 - EJB 3.0 + + The Java Persistence API, included with EJB 3.0, is available for download from + the ejb-api directory in the glassfish CVS repository.It is distributed under + CDDLv1.0 . The jar is being shipped as an OSGi bundle and is required for + compilation of some container based fuctionality. + + Java Persistence (JPA) 2.0. + + EclipseLink is the Java Persistence (JPA) 2.0 Reference Implementation (JSR + 317). The JPA 2.0 specification API is included in EclipseLink under the EPL and + EDL licenses. + + Java Mail v1.4 + + The Java Mail library (mail.jar) is distributed with the JAXB v2.0.5 under CDDL + v1.0 and is included within the EclipseLink Project distribution to support Web + Services attachment handling in the MOXy component. It is only required when + using Java SE 5 (Java Mail is included in Java SE 6). + + Java Activation Framework v1.1 + + The Java Activation Framework (activation.jar) is distributed with the JAXB + v2.0.5 under CDDL v1.0 and is included within the EclipseLink Project + distribution to support Web Services attachment handling in the MOXy component. + It is only required when using Java SE 5 (The Java Activation Framework is + included in Java SE 6). + + Streaming API for XML (StAX) v1.0 + + The Streaming API for XML (StAX) library (jsr173_1.0_api.jar) is distributed + with the JAXB v2.0.5 under CDDL v1.0 and is included within the EclipseLink + Project distribution as an optional XML processing approach in the MOXy + component. + + Service Data Objects (SDO) v2.1.1 + + The Service Data Objects (SDO) API is distributed under a CDDLv1.0 and custom + license. It provides the standard API implemented by the EclipseLink Project's + SDO component. + + Java Connector v1.5 + + The JCA 1.5 API is available for download from the connector-api directory in + the glassfish CVS repository. It is distributed under CDDLv1.0 . + + This jar is being shipped and required by the Workbench only. When using + EclipseLink in a container where JCA integration is required that container will + provide the necessary API libraries. + + Xerces v2.9.0 + + Xerces 2.9.0 is available from the Xerces home page. It is distributed under + Apache 2.0. + + This jar is shipped for the Workbench's use only in the reading and writing of + XML configuration files. + + WSDL4j v1.6.2 + + WSDL4J 1.6.2 is available for download from the wsdl4j project. It distributed + under CPLv1.0 . + + This jar is being shipped as a OSGi bundle and is only required for the DBWS + Builder utility. + + For cloud-commons-logging-1.1.1.jar commons-logging-1.1.1.jar @@ -255,6 +430,21 @@ THE SOFTWARE. + For + jquery.js + + + jQuery JavaScript Library v1.3.2 + http://jquery.com/ + + Copyright (c) 2009 John Resig + Dual licensed under the MIT and GPL licenses. + http://docs.jquery.com/License + + Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + Revision: 6246 + + For axis2-1.5.1.jar axis2-adb-1.5.1.jar @@ -320,181 +510,6 @@ - software copyright (c) 2000 World Wide Web Consortium, http://www.w3.org - For - cloud-javax.persistence-2.0.0.jar - - - EclipseLink 2.0.0 - - Dec 10th, 2009 - - About - - The EclipseLink project's goal is to provide a complete persistence framework - that is both comprehensive and universal. It will run in any Java environment - and read and write objects to virtually any type of data source, including - relational databases, and XML. EclipseLink will focus on providing leading edge - support, including advanced feature extensions, for the dominant persistence - standards for each target data source; Java Persistence API (JPA) for relational - databases, Java API for XML Binding (JAXB) for XML, Service Data Objects (SDO), - and Database Web services (DBWS). - - For tips on getting started with EclipseLink, please see the following - resources: - - EclipseLink 2.0.0 Release Notes Documentation Examples and How To License - - The Eclipse Foundation makes available all content in this plug-in ("Content"). - Unless otherwise indicated below, the Content is provided to you under the terms - and conditions of the Eclipse Public License Version 1.0 ("EPL") and Eclipse - Distribution License Version 1.0 (“EDLâ€). A copy of the EPL is available at - http://www.eclipse.org/legal/epl-v10.html and a copy of the EDL is available at - http://www.eclipse.org/org/documents/edl-v10.php. For purposes of the EPL, - "Program" will mean the Content. - - If you did not receive this Content directly from the Eclipse Foundation, the - Content is being redistributed by another party ("Redistributor") and different - terms and conditions may apply to your use of any object code in the Content. - Check the Redistributor’s license that was provided with the Content. If no such - license exists, contact the Redistributor. Unless otherwise indicated below, the - terms and conditions of the EPL and EDL still apply to any source code in the - Content and such source code may be obtained at http://www.eclipse.org. - - Third Party Content - - The Content includes items that have been sourced from third parties as set out - below. If you did not receive this Content directly from the Eclipse Foundation, - the following is provided for informational purposes only, and you should look - to the Redistributor’s license for terms and conditions of use. - - Foundation Dependencies ASM EclipseLink JPA ANTLR Java Persistence API (JPA) 1.0 - - EJB 3.0 Java Persistence API (JPA) 2.0 EARLY ACCESS EclipseLink MOXy Java - Architecture for XML Binding (JAXB) Java Mail Java Activation Framework - Streaming API for XML (StAX) EclipseLink SDO Service Data Objects (SDO) - Utilities Java Connector Xerces WSDL4J 1.6.2 ASM v1.5.3 - - The EclipseLink Project includes ASM for the purpose of byte code weaving. The - AMS library is re-packaged within the source of the project - (org.persistence.eclipse.internal.libraries.asm.*) to avoid version collisions - with other usage of ASM. A custom patch has been added to the ASM 1.5.3 source - to handle an issue with other usages. This fix has also been contributed back to - the ASM project for inclusion in later projects. - - The source code is available within the project's subversion repository. The - binaries are distributed within the eclipselink.jar and in the - org.eclipse.persistence.asm_2.0.0.v*.jar bundle. - - http://asm.objectweb.org/license.html - - Copyright (c) 2000-2005 INRIA, France Telecom, All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. Redistributions in binary form must - reproduce the above copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided with the - distribution. Neither the name of the copyright holders nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY - THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE DISCLAIMED. IN NO EVENT - SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - OFTHE POSSIBILITY OF SUCH DAMAGE. - - ANTLR v3.0 - - The ANTLR library (license) is included within EclipseLink Project to enable - parsing of the Java Persistence Query language (JP QL). The ANTLR library is re- - packaged within the project in the - org.eclipse.persistence.internal.libraries.antlr.* packages. - - The source is available with the project's subversion repository. The binaries - are distributed within the eclipselink.jar and in the - org.eclipse.persistence.antlr_2.0.0.v*.jar bundle. - - Java Architecture for XML Binding (JAXB) v2.0.5 - - The JAXB libraries distributed under CDDL v1.0 are included within the - EclipseLink Project to enable the MOXY component's implementation of JAXB. - - JAXB Libraries: - - /jlib/moxy/javax.xml.bind_2.1.12.v20090708-1500.jar /jlib/moxy/jaxb-impl.jar - /jlib/moxy/jaxb.xjc.jar Java Persistence (JPA) 1.0 - EJB 3.0 - - The Java Persistence API, included with EJB 3.0, is available for download from - the ejb-api directory in the glassfish CVS repository.It is distributed under - CDDLv1.0 . The jar is being shipped as an OSGi bundle and is required for - compilation of some container based fuctionality. - - Java Persistence (JPA) 2.0. - - EclipseLink is the Java Persistence (JPA) 2.0 Reference Implementation (JSR - 317). The JPA 2.0 specification API is included in EclipseLink under the EPL and - EDL licenses. - - Java Mail v1.4 - - The Java Mail library (mail.jar) is distributed with the JAXB v2.0.5 under CDDL - v1.0 and is included within the EclipseLink Project distribution to support Web - Services attachment handling in the MOXy component. It is only required when - using Java SE 5 (Java Mail is included in Java SE 6). - - Java Activation Framework v1.1 - - The Java Activation Framework (activation.jar) is distributed with the JAXB - v2.0.5 under CDDL v1.0 and is included within the EclipseLink Project - distribution to support Web Services attachment handling in the MOXy component. - It is only required when using Java SE 5 (The Java Activation Framework is - included in Java SE 6). - - Streaming API for XML (StAX) v1.0 - - The Streaming API for XML (StAX) library (jsr173_1.0_api.jar) is distributed - with the JAXB v2.0.5 under CDDL v1.0 and is included within the EclipseLink - Project distribution as an optional XML processing approach in the MOXy - component. - - Service Data Objects (SDO) v2.1.1 - - The Service Data Objects (SDO) API is distributed under a CDDLv1.0 and custom - license. It provides the standard API implemented by the EclipseLink Project's - SDO component. - - Java Connector v1.5 - - The JCA 1.5 API is available for download from the connector-api directory in - the glassfish CVS repository. It is distributed under CDDLv1.0 . - - This jar is being shipped and required by the Workbench only. When using - EclipseLink in a container where JCA integration is required that container will - provide the necessary API libraries. - - Xerces v2.9.0 - - Xerces 2.9.0 is available from the Xerces home page. It is distributed under - Apache 2.0. - - This jar is shipped for the Workbench's use only in the reading and writing of - XML configuration files. - - WSDL4j v1.6.2 - - WSDL4J 1.6.2 is available for download from the wsdl4j project. It distributed - under CPLv1.0 . - - This jar is being shipped as a OSGi bundle and is only required for the DBWS - Builder utility. - - For cloud-commons-codec-1.5.jar commons-codec-1.4.jar diff --git a/tools/whisker/descriptor.xml b/tools/whisker/descriptor.xml index b2eb90da35e..ad29c693ba3 100644 --- a/tools/whisker/descriptor.xml +++ b/tools/whisker/descriptor.xml @@ -1805,7 +1805,18 @@ this License shall be subject to the jurisdiction of the Federal Courts of the Northern District of California and the state courts of the State of California, with venue lying in Santa Clara County, California. - + +jQuery JavaScript Library v1.3.2 +http://jquery.com/ + +Copyright (c) 2009 John Resig +Dual licensed under the MIT and GPL licenses. +http://docs.jquery.com/License + +Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) +Revision: 6246 + + jQuery JavaScript Library v1.6.1 http://jquery.com/ @@ -1954,7 +1965,7 @@ EclipseLink 2.0.0 Release Notes Documentation Examples and How To License The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the Eclipse Public License Version 1.0 ("EPL") and Eclipse -Distribution License Version 1.0 (“EDLâ€). A copy of the EPL is available at +Distribution License Version 1.0 ("EDL"). A copy of the EPL is available at http://www.eclipse.org/legal/epl-v10.html and a copy of the EDL is available at http://www.eclipse.org/org/documents/edl-v10.php. For purposes of the EPL, "Program" will mean the Content. @@ -1962,7 +1973,7 @@ http://www.eclipse.org/org/documents/edl-v10.php. For purposes of the EPL, If you did not receive this Content directly from the Eclipse Foundation, the Content is being redistributed by another party ("Redistributor") and different terms and conditions may apply to your use of any object code in the Content. -Check the Redistributor’s license that was provided with the Content. If no such +Check the Redistributor's license that was provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise indicated below, the terms and conditions of the EPL and EDL still apply to any source code in the Content and such source code may be obtained at http://www.eclipse.org. @@ -1972,7 +1983,7 @@ Third Party Content The Content includes items that have been sourced from third parties as set out below. If you did not receive this Content directly from the Eclipse Foundation, the following is provided for informational purposes only, and you should look -to the Redistributor’s license for terms and conditions of use. +to the Redistributor's license for terms and conditions of use. Foundation Dependencies ASM EclipseLink JPA ANTLR Java Persistence API (JPA) 1.0 - EJB 3.0 Java Persistence API (JPA) 2.0 EARLY ACCESS EclipseLink MOXy Java @@ -2437,10 +2448,10 @@ All rights reserved. -Copyright © 2011, John Resig +Copyright © 2009, John Resig - + @@ -2450,7 +2461,7 @@ Copyright © 2011, John Resig Copyright © 2011, John Resig - + From 9214fa0af6ec03b933a283a1f0dfdb8dc0fe6c63 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 17:21:14 -0700 Subject: [PATCH 27/37] CS-15542: UnPlugNicCommand return success if vif doesn't exist --- .../com/cloud/hypervisor/vmware/resource/VmwareResource.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index ba71fafcfef..da7f901cf39 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1295,7 +1295,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } VirtualDevice nic = findVirtualNicDevice(vmMo, cmd.getNic().getMac()); - + if ( nic == null ) { + return new UnPlugNicAnswer(cmd, true, "success"); + } VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); From b58123e075a69e923483b3f9ee51a1fe9cb19350 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 17:25:41 -0700 Subject: [PATCH 28/37] CS-15921 : in 2.1 timeframe, -untagged string is appended to the end of instance name, in cleanup_rules function, we need to convert chain name to vm name correclty --- scripts/vm/hypervisor/xenserver/vmops | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 79b67e71380..05a2ccf6949 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -1087,17 +1087,13 @@ def cleanup_rules(session, args): cleaned = 0 cleanup = [] for chain in vmchains: - vm = session.xenapi.VM.get_by_name_label(chain) - if len(vm) != 1: - vm = session.xenapi.VM.get_by_name_label(chain + "-untagged") - if len(vm) != 1: - util.SMlog("chain " + chain + " does not correspond to a vm, cleaning up") + vmname = chain + if vmname not in resident_vms: + vmname = chain + "-untagged" + if vmname not in resident_vms: + util.SMlog("vm " + chain + " is not running on this host, cleaning up") cleanup.append(chain) - continue - if chain not in resident_vms: - util.SMlog("vm " + chain + " is not running, cleaning up") - cleanup.append(chain) - + for vm_name in cleanup: destroy_network_rules_for_vm(session, {'vmName':vm_name}) From fbba8c2ef3a34bfa5fcb02b40f61c9c5dd48f4b8 Mon Sep 17 00:00:00 2001 From: Anthony Xu Date: Fri, 7 Sep 2012 17:29:49 -0700 Subject: [PATCH 29/37] CS-15542, return success when vif is not there on deipassoc --- .../cloud/hypervisor/vmware/resource/VmwareResource.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index da7f901cf39..cf4f335ba82 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1326,7 +1326,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa int ethDeviceNum = this.findRouterEthDeviceIndex(domrName, routerIp, ip.getVifMacAddress()); if (ethDeviceNum < 0) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + return; + } } String args = ""; From 541fec8b46f2e3f6da93f15c8f3b19b52eb6e4a0 Mon Sep 17 00:00:00 2001 From: anthony Date: Wed, 22 Aug 2012 15:31:31 -0700 Subject: [PATCH 30/37] Bug 13734 : after upgrade, dhcp traffic is allowed for all VMs reviewed-by: kelven --- scripts/vm/hypervisor/xenserver/vmops | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 05a2ccf6949..e3f3e336e92 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -426,6 +426,19 @@ def can_bridge_firewall(session, args): util.pread2(['iptables', '-D', 'FORWARD', '-j', 'RH-Firewall-1-INPUT']) except: util.SMlog('Chain BRIDGE-FIREWALL already exists') + + try: + util.pread2(['iptables', '-N', 'BRIDGE-DEFAULT-FIREWALL']) + util.pread2(['iptables', '-A', 'BRIDGE-DEFAULT-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-DEFAULT-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-A', 'BRIDGE-DEFAULT-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '-j', 'BRIDGE-DEFAULT-FIREWALL']) + util.pread2(['iptables', '-D', 'BRIDGE-FIREWALL', '-m', 'state', '--state', 'RELATED,ESTABLISHED', '-j', 'ACCEPT']) + util.pread2(['iptables', '-D', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '67', '--sport', '68', '-j', 'ACCEPT']) + util.pread2(['iptables', '-D', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '-p', 'udp', '--dport', '68', '--sport', '67', '-j', 'ACCEPT']) + except: + util.SMlog('Chain BRIDGE-DEFAULT-FIREWALL already exists') + privnic = get_private_nic(session, args) result = 'true' try: @@ -751,7 +764,7 @@ def default_network_rules_systemvm(session, args): for vif in vifs: try: util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', vif, '-j', vmchain]) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '4', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', vmchain]) util.pread2(['iptables', '-I', vmchain, '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', vif, '-j', 'RETURN']) except: util.SMlog("Failed to program default rules") @@ -823,7 +836,7 @@ def default_network_rules(session, args): try: for v in vifs: util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '4', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) #don't let vm spoof its ip address for v in vifs: @@ -927,7 +940,7 @@ def network_rules_for_rebooted_vm(session, vmName): for v in vifs: util.pread2(['iptables', '-A', 'BRIDGE-FIREWALL', '-m', 'physdev', '--physdev-is-bridged', '--physdev-out', v, '-j', vmchain_default]) - util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '4', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) + util.pread2(['iptables', '-I', 'BRIDGE-FIREWALL', '2', '-m', 'physdev', '--physdev-is-bridged', '--physdev-in', v, '-j', vmchain_default]) #change antispoof rule in vmchain try: From 6c96e638be74657db4fd65586493dea73f081c81 Mon Sep 17 00:00:00 2001 From: anthony Date: Mon, 2 Jul 2012 17:42:10 -0700 Subject: [PATCH 31/37] VPC : static route, add route table in cloud-early-config --- .../systemvm/debian/config/etc/init.d/cloud-early-config | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 4bf4d6b0920..656d75e9a7e 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -600,7 +600,12 @@ EOF fi ip route delete default + # create route table for static route + sudo echo "251 static_route_back" >> /etc/iproute2/rt_tables 2>/dev/null + sudo echo "252 static_route" >> /etc/iproute2/rt_tables 2>/dev/null + sudo ip rule add from $VPCCIDR table static_route_back 2>/dev/null + sudo ip rule add from $VPCCIDR table static_route 2>/dev/null sed -i /gateway/d /etc/hosts @@ -951,6 +956,9 @@ for i in $CMDLINE vmpassword) VM_PASSWORD=$VALUE ;; + vpccidr) + VPCCIDR=$VALUE + ;; esac done } From 5756a2a73b558e95905f3f01cce1453a2ee552cd Mon Sep 17 00:00:00 2001 From: anthony Date: Tue, 3 Jul 2012 12:25:05 -0700 Subject: [PATCH 32/37] VPC : clean up rt_table when stop domr --- patches/systemvm/debian/config/etc/init.d/cloud-early-config | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 656d75e9a7e..236abbd2729 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -602,10 +602,10 @@ EOF ip route delete default # create route table for static route - sudo echo "251 static_route_back" >> /etc/iproute2/rt_tables 2>/dev/null sudo echo "252 static_route" >> /etc/iproute2/rt_tables 2>/dev/null - sudo ip rule add from $VPCCIDR table static_route_back 2>/dev/null + sudo echo "251 static_route_back" >> /etc/iproute2/rt_tables 2>/dev/null sudo ip rule add from $VPCCIDR table static_route 2>/dev/null + sudo ip rule add from $VPCCIDR table static_route_back 2>/dev/null sed -i /gateway/d /etc/hosts @@ -777,6 +777,7 @@ setup_default() { auto lo iface lo inet loopback EOF + cp -f /etc/iptables/rt_tables_init /etc/iproute2/rt_tables } change_password() { From ba0522461dd100dfdb16869b40b41003561b05e6 Mon Sep 17 00:00:00 2001 From: anthony Date: Fri, 6 Jul 2012 16:08:34 -0700 Subject: [PATCH 33/37] VPC : configure apache2 for each guest network --- .../config/etc/init.d/cloud-early-config | 21 +++++++++++++++++++ .../debian/config/opt/cloud/bin/vpc_acl.sh | 1 - .../config/opt/cloud/bin/vpc_guestnw.sh | 12 ----------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/patches/systemvm/debian/config/etc/init.d/cloud-early-config b/patches/systemvm/debian/config/etc/init.d/cloud-early-config index 236abbd2729..a7f9b702e62 100755 --- a/patches/systemvm/debian/config/etc/init.d/cloud-early-config +++ b/patches/systemvm/debian/config/etc/init.d/cloud-early-config @@ -394,6 +394,26 @@ setup_sshd(){ [ -f /etc/ssh/sshd_config ] && sed -i -e "s/^[#]*ListenAddress.*$/ListenAddress $ip/" /etc/ssh/sshd_config } + +setup_vpc_apache2() { + log_it "Setting up apache web server for VPC" + chkconfig apache2 off + rm -f /etc/apache2/conf.d/vhost*.conf + [ -f /etc/apache2/sites-available/default ] && echo "" >/etc/apache2/sites-available/default + [ -f /etc/apache2/sites-available/default-ssl ] && echo "">/etc/apache2/sites-available/default-ssl + [ -f /etc/apache2/ports.conf ] && echo "">/etc/apache2/ports.conf + [ -f /etc/apache2/ports.conf ] && echo "">/etc/apache2/ports.conf + [ -f /etc/apache2/ports.conf ] && echo "">/etc/apache2/ports.conf + [ -f /etc/apache2/conf.d/security ] && sed -i -e "s/^ServerTokens .*/ServerTokens Prod/g" /etc/apache2/conf.d/security + [ -f /etc/apache2/conf.d/security ] && sed -i -e "s/^ServerSignature .*/ServerSignature Off/g" /etc/apache2/conf.d/security + + # Disable listing of http://SSVM-IP/icons folder for security issue. see article http://www.i-lateral.com/tutorials/disabling-the-icons-folder-on-an-ubuntu-web-server/ + [ -f /etc/apache2/mods-available/alias.conf ] && sed -i s/"Options Indexes MultiViews"/"Options -Indexes MultiViews"/ /etc/apache2/mods-available/alias.conf + + echo "Options -Indexes" > /var/www/html/.htaccess +} + + setup_apache2() { log_it "Setting up apache web server" local ip=$1 @@ -611,6 +631,7 @@ EOF echo "$ETH0_IP $NAME" >> /etc/hosts setup_sshd $ETH0_IP + setup_vpc_apache2 enable_svc dnsmasq 1 enable_svc haproxy 1 diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh index 4ebed3abdf9..8a207e880be 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_acl.sh @@ -89,7 +89,6 @@ acl_chain_for_guest_network () { sudo iptables -A FORWARD -o $dev -d $gcidr -j ACL_INBOUND_$dev 2>/dev/null # outbound sudo iptables -t mangle -N ACL_OUTBOUND_$dev 2>/dev/null - sudo iptables -t mangle -A ACL_OUTBOUND_$dev -j DROP 2>/dev/null sudo iptables -t mangle -A PREROUTING -m state --state NEW -i $dev -s $gcidr ! -d $ip -j ACL_OUTBOUND_$dev 2>/dev/null } diff --git a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh index ee9960c6253..7331c53ea67 100755 --- a/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh +++ b/patches/systemvm/debian/config/opt/cloud/bin/vpc_guestnw.sh @@ -65,18 +65,6 @@ setup_apache2() { sed -i -e "s/\tServerName.*/\tServerName vhost$dev.cloudinternal.com/" /etc/apache2/conf.d/vhost$dev.conf sed -i -e "s/Listen .*:80/Listen $ip:80/g" /etc/apache2/conf.d/vhost$dev.conf sed -i -e "s/Listen .*:443/Listen $ip:443/g" /etc/apache2/conf.d/vhost$dev.conf - if [ -e "/etc/apache2/sites-enabled/000-default" ] - then - sed -i -e "s/^#*/#/g" /etc/apache2/sites-enabled/000-default - fi - if [ -e "/etc/apache2/sites-enabled/default-ssl" ] - then - sed -i -e "s/^#*/#/g" /etc/apache2/sites-enabled/default-ssl - fi - if [ -e "/etc/apache2/ports.conf" ] - then - sed -i -e "s/^#*/#/g" /etc/apache2/ports.conf - fi service apache2 restart sudo iptables -A INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT } From f03d438c4c819b5507247c6a11b583a74f60afe6 Mon Sep 17 00:00:00 2001 From: Mice Xia Date: Sat, 8 Sep 2012 09:23:35 +0800 Subject: [PATCH 34/37] CLOUDSTACK-59 missing license header. --- client/cloudstack-ui.launch | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/client/cloudstack-ui.launch b/client/cloudstack-ui.launch index b47097c33cf..1943d17aebd 100644 --- a/client/cloudstack-ui.launch +++ b/client/cloudstack-ui.launch @@ -1,4 +1,22 @@ + From 0bf8c5a18f6eb964ee70387d8eb5c30cc47ea0fc Mon Sep 17 00:00:00 2001 From: Mice Xia Date: Sat, 8 Sep 2012 09:24:34 +0800 Subject: [PATCH 35/37] CLOUDSTACK-61 Console proxy has plenty of files with CRLF line ending. --- console-proxy/.classpath | 50 +- console-proxy/.project | 82 +- console-proxy/conf.dom0/agent.properties.in | 92 +- .../conf.dom0/consoleproxy.properties.in | 46 +- console-proxy/conf/agent.properties | 38 +- console-proxy/conf/consoleproxy.properties | 46 +- console-proxy/css/ajaxviewer.css | 288 ++-- console-proxy/js/ajaxviewer.js | 1220 ++++++++--------- console-proxy/scripts/run.bat | 36 +- .../consoleproxy/AjaxFIFOImageCache.java | 88 +- .../consoleproxy/AuthenticationException.java | 32 +- .../consoleproxy/ConsoleProxyAjaxHandler.java | 752 +++++----- .../ConsoleProxyAjaxImageHandler.java | 246 ++-- .../ConsoleProxyAuthenticationResult.java | 130 +- .../ConsoleProxyBaseServerFactoryImpl.java | 50 +- .../ConsoleProxyClientListener.java | 18 +- .../consoleproxy/ConsoleProxyCmdHandler.java | 106 +- .../ConsoleProxyHttpHandlerHelper.java | 116 +- .../ConsoleProxyLoggerFactory.java | 140 +- .../consoleproxy/ConsoleProxyMonitor.java | 226 +-- .../ConsoleProxyResourceHandler.java | 328 ++--- .../ConsoleProxySecureServerFactoryImpl.java | 214 +-- .../ConsoleProxyServerFactory.java | 14 +- .../ConsoleProxyThumbnailHandler.java | 386 +++--- .../cloud/consoleproxy/InputEventType.java | 84 +- .../consoleproxy/util/ITileScanListener.java | 18 +- .../cloud/consoleproxy/util/ImageHelper.java | 32 +- .../com/cloud/consoleproxy/util/Logger.java | 414 +++--- .../consoleproxy/util/LoggerFactory.java | 10 +- .../com/cloud/consoleproxy/util/RawHTTP.java | 466 +++---- .../com/cloud/consoleproxy/util/Region.java | 148 +- .../consoleproxy/util/RegionClassifier.java | 84 +- .../com/cloud/consoleproxy/util/TileInfo.java | 78 +- .../cloud/consoleproxy/util/TileTracker.java | 506 +++---- .../consoleproxy/vnc/BufferedImageCanvas.java | 212 ++- .../consoleproxy/vnc/FrameBufferCanvas.java | 26 +- .../vnc/FrameBufferUpdateListener.java | 10 +- .../vnc/PaintNotificationListener.java | 10 +- .../cloud/consoleproxy/vnc/RfbConstants.java | 91 +- .../com/cloud/consoleproxy/vnc/VncClient.java | 751 +++++----- .../vnc/VncClientPacketSender.java | 420 +++--- .../vnc/VncScreenDescription.java | 99 +- .../vnc/VncServerPacketReceiver.java | 172 +-- .../vnc/packet/client/ClientPacket.java | 2 +- .../FramebufferUpdateRequestPacket.java | 37 +- .../packet/client/KeyboardEventPacket.java | 26 +- .../vnc/packet/client/MouseEventPacket.java | 26 +- .../vnc/packet/client/SetEncodingsPacket.java | 35 +- .../packet/client/SetPixelFormatPacket.java | 82 +- .../vnc/packet/server/AbstractRect.java | 52 +- .../vnc/packet/server/CopyRect.java | 20 +- .../server/FrameBufferSizeChangeRequest.java | 22 +- .../server/FramebufferUpdatePacket.java | 129 +- .../vnc/packet/server/RawRect.java | 79 +- .../consoleproxy/vnc/packet/server/Rect.java | 15 +- .../vnc/packet/server/ServerCutText.java | 32 +- console-proxy/ui/viewer-update.ftl | 48 +- 57 files changed, 4486 insertions(+), 4494 deletions(-) diff --git a/console-proxy/.classpath b/console-proxy/.classpath index 1a61b023647..eeed44e009b 100644 --- a/console-proxy/.classpath +++ b/console-proxy/.classpath @@ -1,25 +1,25 @@ - - - - - - - - + + + + + + + + diff --git a/console-proxy/.project b/console-proxy/.project index d3efcb5b448..5fae244dad4 100644 --- a/console-proxy/.project +++ b/console-proxy/.project @@ -1,41 +1,41 @@ - - - - console-proxy - - - - - - org.eclipse.wst.jsdt.core.javascriptValidator - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.wst.jsdt.core.jsNature - - + + + + console-proxy + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/console-proxy/conf.dom0/agent.properties.in b/console-proxy/conf.dom0/agent.properties.in index 285587a44cb..1920481c03f 100644 --- a/console-proxy/conf.dom0/agent.properties.in +++ b/console-proxy/conf.dom0/agent.properties.in @@ -1,46 +1,46 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Sample configuration file for VMOPS console proxy - -instance=ConsoleProxy -consoleproxy.httpListenPort=8002 - -#resource= the java class, which agent load to execute -resource=com.cloud.agent.resource.consoleproxy.ConsoleProxyResource - -#host= The IP address of management server -host=localhost - -#port = The port management server listening on, default is 8250 -port=8250 - -#pod= The pod, which agent belonged to -pod=default - -#zone= The zone, which agent belonged to -zone=default - -#private.network.device= the private nic device -# if this is commented, it is autodetected on service startup -# private.network.device=cloudbr0 - -#public.network.device= the public nic device -# if this is commented, it is autodetected on service startup -# public.network.device=cloudbr0 - -#guid= a GUID to identify the agent +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Sample configuration file for VMOPS console proxy + +instance=ConsoleProxy +consoleproxy.httpListenPort=8002 + +#resource= the java class, which agent load to execute +resource=com.cloud.agent.resource.consoleproxy.ConsoleProxyResource + +#host= The IP address of management server +host=localhost + +#port = The port management server listening on, default is 8250 +port=8250 + +#pod= The pod, which agent belonged to +pod=default + +#zone= The zone, which agent belonged to +zone=default + +#private.network.device= the private nic device +# if this is commented, it is autodetected on service startup +# private.network.device=cloudbr0 + +#public.network.device= the public nic device +# if this is commented, it is autodetected on service startup +# public.network.device=cloudbr0 + +#guid= a GUID to identify the agent diff --git a/console-proxy/conf.dom0/consoleproxy.properties.in b/console-proxy/conf.dom0/consoleproxy.properties.in index 858ef444cd3..a3cddbcab96 100644 --- a/console-proxy/conf.dom0/consoleproxy.properties.in +++ b/console-proxy/conf.dom0/consoleproxy.properties.in @@ -1,23 +1,23 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -consoleproxy.tcpListenPort=0 -consoleproxy.httpListenPort=80 -consoleproxy.httpCmdListenPort=8001 -consoleproxy.jarDir=./applet/ -consoleproxy.viewerLinger=180 -consoleproxy.reconnectMaxRetry=5 +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +consoleproxy.tcpListenPort=0 +consoleproxy.httpListenPort=80 +consoleproxy.httpCmdListenPort=8001 +consoleproxy.jarDir=./applet/ +consoleproxy.viewerLinger=180 +consoleproxy.reconnectMaxRetry=5 diff --git a/console-proxy/conf/agent.properties b/console-proxy/conf/agent.properties index 11853ba6ca9..4e217f21100 100644 --- a/console-proxy/conf/agent.properties +++ b/console-proxy/conf/agent.properties @@ -1,19 +1,19 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -instance=ConsoleProxy -resource=com.cloud.agent.resource.consoleproxy.ConsoleProxyResource +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +instance=ConsoleProxy +resource=com.cloud.agent.resource.consoleproxy.ConsoleProxyResource diff --git a/console-proxy/conf/consoleproxy.properties b/console-proxy/conf/consoleproxy.properties index 3e5f69ab241..bb452f5823c 100644 --- a/console-proxy/conf/consoleproxy.properties +++ b/console-proxy/conf/consoleproxy.properties @@ -1,23 +1,23 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -consoleproxy.tcpListenPort=0 -consoleproxy.httpListenPort=8088 -consoleproxy.httpCmdListenPort=8001 -consoleproxy.jarDir=./applet/ -consoleproxy.viewerLinger=180 -consoleproxy.reconnectMaxRetry=5 +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +consoleproxy.tcpListenPort=0 +consoleproxy.httpListenPort=8088 +consoleproxy.httpCmdListenPort=8001 +consoleproxy.jarDir=./applet/ +consoleproxy.viewerLinger=180 +consoleproxy.reconnectMaxRetry=5 diff --git a/console-proxy/css/ajaxviewer.css b/console-proxy/css/ajaxviewer.css index 90c1a63bb29..5ea552b176f 100644 --- a/console-proxy/css/ajaxviewer.css +++ b/console-proxy/css/ajaxviewer.css @@ -1,144 +1,144 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. -*/ - -body { - margin:0 0; - text-align: center; -} - -#main_panel { - clear:both; - margin: 0 auto; - text-align: left; -} - -.canvas_tile { - cursor:crosshair; -} - -#toolbar { - font:normal 12px 'Trebuchet MS','Arial'; - margin:0 auto; - text-align: left; - padding:0 0; - height:32px; - background-image:url(/resource/images/back.gif); - background-repeat:repeat-x; -} - -#toolbar ul { - margin:0 0; - padding:0 10px 0 10px; - float:left; - display:block; - line-height:32px; - list-style:none; -} - -#toolbar li { - float:left; - display:inline; - padding:0; - height:32px; -} - -#toolbar a { - color:white; - float:left; - display:block; - padding:0 3px 0 3px; - text-decoration:none; - line-height:32px; -} - -#toolbar a span { - display:block; - float:none; - padding:0 10px 0 7px; -} - -#toolbar a span img { - border:none; - margin:8px 4px 0 0; -} - -#toolbar a:hover { - background: url(/resource/images/left.png) no-repeat left center; -} - -#toolbar a:hover span { - background:url(/resource/images/right.png) no-repeat right center; -} - - -#toolbar ul li ul { - position: absolute; - top:32; - width: 260; - height: 65; - display: block; - display: none; - border-top: 1px solid black; - background-image:url(/resource/images/back.gif); - background-repeat:repeat-x repeat-y; -} - -#toolbar ul li ul li { - display: list-item; - float:none; - padding-left: 20; -} - -#toolbar ul li ul li.current { - background: url(/resource/images/cad.gif) no-repeat left center; -} - -#toolbar ul li ul li a { - display:block; - padding:0 3px 0 3px; - text-decoration:none; - line-height:32px; - vertical-align: bottom; /* this is to fix the list gap in IE */ -} - -#toolbar ul li ul li a:hover { - background: url(/resource/images/left.png) no-repeat left center; -} - -#toolbar ul li ul li a:hover span { - background: url(/resource/images/right2.png) no-repeat right center; -} - -span.dark { - margin-right:20px; - float:right; - display:block; - width:32px; - height:30px; - background:url(/resource/images/gray-green.png) no-repeat center center; -} - -span.bright { - margin-right:20px; - float:right; - display:block; - width:32px; - height:30px; - background:url(/resource/images/bright-green.png) no-repeat center center; -} +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +body { + margin:0 0; + text-align: center; +} + +#main_panel { + clear:both; + margin: 0 auto; + text-align: left; +} + +.canvas_tile { + cursor:crosshair; +} + +#toolbar { + font:normal 12px 'Trebuchet MS','Arial'; + margin:0 auto; + text-align: left; + padding:0 0; + height:32px; + background-image:url(/resource/images/back.gif); + background-repeat:repeat-x; +} + +#toolbar ul { + margin:0 0; + padding:0 10px 0 10px; + float:left; + display:block; + line-height:32px; + list-style:none; +} + +#toolbar li { + float:left; + display:inline; + padding:0; + height:32px; +} + +#toolbar a { + color:white; + float:left; + display:block; + padding:0 3px 0 3px; + text-decoration:none; + line-height:32px; +} + +#toolbar a span { + display:block; + float:none; + padding:0 10px 0 7px; +} + +#toolbar a span img { + border:none; + margin:8px 4px 0 0; +} + +#toolbar a:hover { + background: url(/resource/images/left.png) no-repeat left center; +} + +#toolbar a:hover span { + background:url(/resource/images/right.png) no-repeat right center; +} + + +#toolbar ul li ul { + position: absolute; + top:32; + width: 260; + height: 65; + display: block; + display: none; + border-top: 1px solid black; + background-image:url(/resource/images/back.gif); + background-repeat:repeat-x repeat-y; +} + +#toolbar ul li ul li { + display: list-item; + float:none; + padding-left: 20; +} + +#toolbar ul li ul li.current { + background: url(/resource/images/cad.gif) no-repeat left center; +} + +#toolbar ul li ul li a { + display:block; + padding:0 3px 0 3px; + text-decoration:none; + line-height:32px; + vertical-align: bottom; /* this is to fix the list gap in IE */ +} + +#toolbar ul li ul li a:hover { + background: url(/resource/images/left.png) no-repeat left center; +} + +#toolbar ul li ul li a:hover span { + background: url(/resource/images/right2.png) no-repeat right center; +} + +span.dark { + margin-right:20px; + float:right; + display:block; + width:32px; + height:30px; + background:url(/resource/images/gray-green.png) no-repeat center center; +} + +span.bright { + margin-right:20px; + float:right; + display:block; + width:32px; + height:30px; + background:url(/resource/images/bright-green.png) no-repeat center center; +} diff --git a/console-proxy/js/ajaxviewer.js b/console-proxy/js/ajaxviewer.js index b15642a1da1..355cc827ba2 100644 --- a/console-proxy/js/ajaxviewer.js +++ b/console-proxy/js/ajaxviewer.js @@ -22,27 +22,27 @@ var g_logger; ///////////////////////////////////////////////////////////////////////////// // class StringBuilder // -function StringBuilder(initStr) { - this.strings = new Array(""); - this.append(initStr); -} - -StringBuilder.prototype = { - append : function (str) { - if (str) { - this.strings.push(str); - } - return this; - }, - - clear : function() { - this.strings.length = 1; - return this; - }, - - toString: function() { - return this.strings.join(""); - } +function StringBuilder(initStr) { + this.strings = new Array(""); + this.append(initStr); +} + +StringBuilder.prototype = { + append : function (str) { + if (str) { + this.strings.push(str); + } + return this; + }, + + clear : function() { + this.strings.length = 1; + return this; + }, + + toString: function() { + return this.strings.join(""); + } }; @@ -335,36 +335,36 @@ function AjaxViewer(panelId, imageUrl, updateUrl, tileMap, width, height, tileWi // g_logger.enable(true); // g_logger.open(); - var ajaxViewer = this; - this.imageLoaded = false; - this.fullImage = true; - this.imgUrl = imageUrl; - this.img = new Image(); - $(this.img).attr('src', imageUrl).load(function() { - ajaxViewer.imageLoaded = true; - }); - - this.updateUrl = updateUrl; - this.tileMap = tileMap; - this.dirty = true; - this.width = width; - this.height = height; - this.tileWidth = tileWidth; + var ajaxViewer = this; + this.imageLoaded = false; + this.fullImage = true; + this.imgUrl = imageUrl; + this.img = new Image(); + $(this.img).attr('src', imageUrl).load(function() { + ajaxViewer.imageLoaded = true; + }); + + this.updateUrl = updateUrl; + this.tileMap = tileMap; + this.dirty = true; + this.width = width; + this.height = height; + this.tileWidth = tileWidth; this.tileHeight = tileHeight; this.maxTileZIndex = 1; this.currentKeyboard = AjaxViewer.KEYBOARD_TYPE_ENGLISH; this.keyboardMappers = []; - this.timer = 0; - this.eventQueue = []; - this.sendingEventInProgress = false; - - this.lastClickEvent = { x: 0, y: 0, button: 0, modifiers: 0, time: new Date().getTime() }; - - if(window.onStatusNotify == undefined) - window.onStatusNotify = function(status) {}; - + this.timer = 0; + this.eventQueue = []; + this.sendingEventInProgress = false; + + this.lastClickEvent = { x: 0, y: 0, button: 0, modifiers: 0, time: new Date().getTime() }; + + if(window.onStatusNotify == undefined) + window.onStatusNotify = function(status) {}; + this.panel = this.generateCanvas(panelId, width, height, tileWidth, tileHeight); this.setupKeyboardTranslationTable(); @@ -569,86 +569,86 @@ AjaxViewer.getEventName = function(type) { return "N/A"; }; - -AjaxViewer.prototype = { - setDirty: function(value) { - this.dirty = value; - }, - - isDirty: function() { - return this.dirty; - }, - - isImageLoaded: function() { - return this.imageLoaded; - }, - - refresh: function(imageUrl, tileMap, fullImage) { - var ajaxViewer = this; - var img = $(this.img); - this.fullImage = fullImage; - this.imgUrl=imageUrl; - - img.attr('src', imageUrl).load(function() { - ajaxViewer.imageLoaded = true; - }); - this.tileMap = tileMap; - }, - - resize: function(panelId, width, height, tileWidth, tileHeight) { - $(".canvas_tile", document.body).each(function() { - $(this).remove(); - }); - $("table", $("#" + panelId)).remove(); - - this.width = width; - this.height = height; - this.tileWidth = tileWidth; - this.tileHeight = tileHeight; - this.panel = this.generateCanvas(panelId, width, height, tileWidth, tileHeight); - }, - - start: function() { - var ajaxViewer = this; - this.timer = setInterval(function() { ajaxViewer.heartbeat(); }, 50); - - $(document).bind("ajaxError", function(event, XMLHttpRequest, ajaxOptions, thrownError) { - ajaxViewer.onAjaxError(event, XMLHttpRequest, ajaxOptions, thrownError); - }); - - this.eventQueue = []; // reset event queue - this.sendingEventInProgress = false; - ajaxViewer.installMouseHook(); - ajaxViewer.installKeyboardHook(); - - $(window).bind("resize", function() { - ajaxViewer.onWindowResize(); - }); - }, - - stop: function() { - clearInterval(this.timer); - this.deleteCanvas(); - - this.uninstallMouseHook(); - this.uninstallKeyboardHook(); - this.eventQueue = []; - this.sendingEventInProgress = false; - - $(document).unbind("ajaxError"); - $(window).unbind("resize"); - }, - - sendMouseEvent: function(event, x, y, whichButton, modifiers) { - this.eventQueue.push({ - type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT, - event: event, - x: x, - y: y, - code: whichButton, - modifiers: modifiers - }); - this.checkEventQueue(); + +AjaxViewer.prototype = { + setDirty: function(value) { + this.dirty = value; + }, + + isDirty: function() { + return this.dirty; + }, + + isImageLoaded: function() { + return this.imageLoaded; + }, + + refresh: function(imageUrl, tileMap, fullImage) { + var ajaxViewer = this; + var img = $(this.img); + this.fullImage = fullImage; + this.imgUrl=imageUrl; + + img.attr('src', imageUrl).load(function() { + ajaxViewer.imageLoaded = true; + }); + this.tileMap = tileMap; + }, + + resize: function(panelId, width, height, tileWidth, tileHeight) { + $(".canvas_tile", document.body).each(function() { + $(this).remove(); + }); + $("table", $("#" + panelId)).remove(); + + this.width = width; + this.height = height; + this.tileWidth = tileWidth; + this.tileHeight = tileHeight; + this.panel = this.generateCanvas(panelId, width, height, tileWidth, tileHeight); + }, + + start: function() { + var ajaxViewer = this; + this.timer = setInterval(function() { ajaxViewer.heartbeat(); }, 50); + + $(document).bind("ajaxError", function(event, XMLHttpRequest, ajaxOptions, thrownError) { + ajaxViewer.onAjaxError(event, XMLHttpRequest, ajaxOptions, thrownError); + }); + + this.eventQueue = []; // reset event queue + this.sendingEventInProgress = false; + ajaxViewer.installMouseHook(); + ajaxViewer.installKeyboardHook(); + + $(window).bind("resize", function() { + ajaxViewer.onWindowResize(); + }); + }, + + stop: function() { + clearInterval(this.timer); + this.deleteCanvas(); + + this.uninstallMouseHook(); + this.uninstallKeyboardHook(); + this.eventQueue = []; + this.sendingEventInProgress = false; + + $(document).unbind("ajaxError"); + $(window).unbind("resize"); + }, + + sendMouseEvent: function(event, x, y, whichButton, modifiers) { + this.eventQueue.push({ + type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT, + event: event, + x: x, + y: y, + code: whichButton, + modifiers: modifiers + }); + this.checkEventQueue(); }, setupKeyboardTranslationTable : function() { @@ -799,487 +799,487 @@ AjaxViewer.prototype = { } } - var len; + var len; g_logger.log(Logger.LEVEL_INFO, "Keyboard event: " + AjaxViewer.getEventName(event) + ", code: " + code + ", modifiers: " + modifiers + ', char: ' + String.fromCharCode(code)); - this.eventQueue.push({ - type: AjaxViewer.EVENT_QUEUE_KEYBOARD_EVENT, - event: event, - code: code, - modifiers: modifiers + this.eventQueue.push({ + type: AjaxViewer.EVENT_QUEUE_KEYBOARD_EVENT, + event: event, + code: code, + modifiers: modifiers }); - if(event != AjaxViewer.KEY_DOWN) - this.checkEventQueue(); - }, - - aggregateEvents: function() { - var ajaxViewer = this; - var aggratedQueue = []; - - var aggregating = false; - var mouseX; - var mouseY; - $.each(ajaxViewer.eventQueue, function(index, item) { - if(item.type != AjaxViewer.EVENT_QUEUE_MOUSE_EVENT) { - aggratedQueue.push(item); - } else { - if(!aggregating) { - if(item.event == AjaxViewer.MOUSE_MOVE) { - aggregating = true; - mouseX = item.x; - mouseY = item.y; - } else { - aggratedQueue.push(item); - } - } else { - if(item.event == AjaxViewer.MOUSE_MOVE) { - // continue to aggregate mouse move event - mouseX = item.x; - mouseY = item.y; - } else { - aggratedQueue.push({ - type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT, - event: AjaxViewer.MOUSE_MOVE, - x: mouseX, - y: mouseY, - code: 0, - modifiers: 0 - }); - aggregating = false; - - aggratedQueue.push(item); - } - } - } - }); - - if(aggregating) { - aggratedQueue.push({ - type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT, - event: AjaxViewer.MOUSE_MOVE, - x: mouseX, - y: mouseY, - code: 0, - modifiers: 0 - }); - } - - this.eventQueue = aggratedQueue; - }, - - checkEventQueue: function() { + if(event != AjaxViewer.KEY_DOWN) + this.checkEventQueue(); + }, + + aggregateEvents: function() { var ajaxViewer = this; - + var aggratedQueue = []; + + var aggregating = false; + var mouseX; + var mouseY; + $.each(ajaxViewer.eventQueue, function(index, item) { + if(item.type != AjaxViewer.EVENT_QUEUE_MOUSE_EVENT) { + aggratedQueue.push(item); + } else { + if(!aggregating) { + if(item.event == AjaxViewer.MOUSE_MOVE) { + aggregating = true; + mouseX = item.x; + mouseY = item.y; + } else { + aggratedQueue.push(item); + } + } else { + if(item.event == AjaxViewer.MOUSE_MOVE) { + // continue to aggregate mouse move event + mouseX = item.x; + mouseY = item.y; + } else { + aggratedQueue.push({ + type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT, + event: AjaxViewer.MOUSE_MOVE, + x: mouseX, + y: mouseY, + code: 0, + modifiers: 0 + }); + aggregating = false; + + aggratedQueue.push(item); + } + } + } + }); + + if(aggregating) { + aggratedQueue.push({ + type: AjaxViewer.EVENT_QUEUE_MOUSE_EVENT, + event: AjaxViewer.MOUSE_MOVE, + x: mouseX, + y: mouseY, + code: 0, + modifiers: 0 + }); + } + + this.eventQueue = aggratedQueue; + }, + + checkEventQueue: function() { + var ajaxViewer = this; + if(!this.sendingEventInProgress && this.eventQueue.length > 0) { - var sb = new StringBuilder(); - sb.append(""+this.eventQueue.length).append("|"); - $.each(this.eventQueue, function() { - var item = this; - if(item.type == AjaxViewer.EVENT_QUEUE_MOUSE_EVENT) { - sb.append(""+item.type).append("|"); - sb.append(""+item.event).append("|"); - sb.append(""+item.x).append("|"); - sb.append(""+item.y).append("|"); - sb.append(""+item.code).append("|"); - sb.append(""+item.modifiers).append("|"); - } else { - sb.append(""+item.type).append("|"); - sb.append(""+item.event).append("|"); - sb.append(""+item.code).append("|"); - sb.append(""+item.modifiers).append("|"); - } - }); - this.eventQueue.length = 0; - + var sb = new StringBuilder(); + sb.append(""+this.eventQueue.length).append("|"); + $.each(this.eventQueue, function() { + var item = this; + if(item.type == AjaxViewer.EVENT_QUEUE_MOUSE_EVENT) { + sb.append(""+item.type).append("|"); + sb.append(""+item.event).append("|"); + sb.append(""+item.x).append("|"); + sb.append(""+item.y).append("|"); + sb.append(""+item.code).append("|"); + sb.append(""+item.modifiers).append("|"); + } else { + sb.append(""+item.type).append("|"); + sb.append(""+item.event).append("|"); + sb.append(""+item.code).append("|"); + sb.append(""+item.modifiers).append("|"); + } + }); + this.eventQueue.length = 0; + var url = ajaxViewer.updateUrl + "&event=" + AjaxViewer.EVENT_BAG; g_logger.log(Logger.LEVEL_TRACE, "Posting client event " + sb.toString() + "..."); - - ajaxViewer.sendingEventInProgress = true; - window.onStatusNotify(AjaxViewer.STATUS_SENDING); + + ajaxViewer.sendingEventInProgress = true; + window.onStatusNotify(AjaxViewer.STATUS_SENDING); $.post(url, {data: sb.toString()}, function(data, textStatus) { g_logger.log(Logger.LEVEL_TRACE, "Client event " + sb.toString() + " is posted"); - - ajaxViewer.sendingEventInProgress = false; - window.onStatusNotify(AjaxViewer.STATUS_SENT); - - ajaxViewer.checkUpdate(); - }, 'html'); - } - }, - - onAjaxError: function(event, XMLHttpRequest, ajaxOptions, thrownError) { - if(window.onClientError != undefined && jQuery.isFunction(window.onClientError)) { - window.onClientError(); - } - }, - - onWindowResize: function() { - var offset = this.panel.offset(); - - var row = $('tr:first', this.panel); - var cell = $('td:first', row); - var tile = this.getTile(cell, 'tile'); - - var tileOffset = tile.offset(); - var deltaX = offset.left - tileOffset.left; - var deltaY = offset.top - tileOffset.top; - - if(deltaX != 0 || deltaY != 0) { - $(".canvas_tile").each(function() { - var offsetFrom = $(this).offset(); - $(this).css('left', offsetFrom.left + deltaX).css('top', offsetFrom.top + deltaY); - }); - } - }, - - deleteCanvas: function() { - $('.canvas_tile', $(document.body)).each(function() { - $(this).remove(); - }); - }, - - generateCanvas: function(wrapperDivId, width, height, tileWidth, tileHeight) { - var canvasParent = $('#' + wrapperDivId); - canvasParent.width(width); - canvasParent.height(height); - - if(window.onCanvasSizeChange != undefined && jQuery.isFunction(window.onCanvasSizeChange)) - window.onCanvasSizeChange(width, height); - - var tableDef = '\r\n'; - var i = 0; - var j = 0; - for(i = 0; i < Math.ceil((height + tileHeight - 1) / tileHeight); i++) { - var rowHeight = Math.min(height - i*tileHeight, tileHeight); - tableDef += '\r\n'; - - for(j = 0; j < Math.ceil((width + tileWidth - 1) / tileWidth); j++) { - var colWidth = Math.min(width - j*tileWidth, tileWidth); - tableDef += '\r\n'; - } - tableDef += '\r\n'; - } - tableDef += '
\r\n'; - - return $(tableDef).appendTo(canvasParent); - }, - - getTile: function(cell, name) { - var clonedDiv = cell.data(name); - if(!clonedDiv) { - var offset = cell.offset(); - var divDef = "
"; - - clonedDiv = $(divDef).appendTo($(document.body)); - cell.data(name, clonedDiv); - } - - return clonedDiv; - }, - - initCell: function(cell) { - if(!cell.data("init")) { - cell.data("init", true); - - cell.data("current", 0); - this.getTile(cell, "tile2"); - this.getTile(cell, "tile"); - } - }, - - displayCell: function(cell, bg) { - var div; - var divPrev; - if(!cell.data("current")) { - cell.data("current", 1); - - divPrev = this.getTile(cell, "tile"); - div = this.getTile(cell, "tile2"); - } else { - cell.data("current", 0); - divPrev = this.getTile(cell, "tile2"); - div = this.getTile(cell, "tile"); - } + + ajaxViewer.sendingEventInProgress = false; + window.onStatusNotify(AjaxViewer.STATUS_SENT); + + ajaxViewer.checkUpdate(); + }, 'html'); + } + }, + + onAjaxError: function(event, XMLHttpRequest, ajaxOptions, thrownError) { + if(window.onClientError != undefined && jQuery.isFunction(window.onClientError)) { + window.onClientError(); + } + }, + + onWindowResize: function() { + var offset = this.panel.offset(); + + var row = $('tr:first', this.panel); + var cell = $('td:first', row); + var tile = this.getTile(cell, 'tile'); + + var tileOffset = tile.offset(); + var deltaX = offset.left - tileOffset.left; + var deltaY = offset.top - tileOffset.top; + + if(deltaX != 0 || deltaY != 0) { + $(".canvas_tile").each(function() { + var offsetFrom = $(this).offset(); + $(this).css('left', offsetFrom.left + deltaX).css('top', offsetFrom.top + deltaY); + }); + } + }, + + deleteCanvas: function() { + $('.canvas_tile', $(document.body)).each(function() { + $(this).remove(); + }); + }, + + generateCanvas: function(wrapperDivId, width, height, tileWidth, tileHeight) { + var canvasParent = $('#' + wrapperDivId); + canvasParent.width(width); + canvasParent.height(height); + + if(window.onCanvasSizeChange != undefined && jQuery.isFunction(window.onCanvasSizeChange)) + window.onCanvasSizeChange(width, height); + + var tableDef = '\r\n'; + var i = 0; + var j = 0; + for(i = 0; i < Math.ceil((height + tileHeight - 1) / tileHeight); i++) { + var rowHeight = Math.min(height - i*tileHeight, tileHeight); + tableDef += '\r\n'; + + for(j = 0; j < Math.ceil((width + tileWidth - 1) / tileWidth); j++) { + var colWidth = Math.min(width - j*tileWidth, tileWidth); + tableDef += '\r\n'; + } + tableDef += '\r\n'; + } + tableDef += '
\r\n'; + + return $(tableDef).appendTo(canvasParent); + }, + + getTile: function(cell, name) { + var clonedDiv = cell.data(name); + if(!clonedDiv) { + var offset = cell.offset(); + var divDef = "
"; + + clonedDiv = $(divDef).appendTo($(document.body)); + cell.data(name, clonedDiv); + } + + return clonedDiv; + }, + + initCell: function(cell) { + if(!cell.data("init")) { + cell.data("init", true); + + cell.data("current", 0); + this.getTile(cell, "tile2"); + this.getTile(cell, "tile"); + } + }, + + displayCell: function(cell, bg) { + var div; + var divPrev; + if(!cell.data("current")) { + cell.data("current", 1); + + divPrev = this.getTile(cell, "tile"); + div = this.getTile(cell, "tile2"); + } else { + cell.data("current", 0); + divPrev = this.getTile(cell, "tile2"); + div = this.getTile(cell, "tile"); + } var zIndex = parseInt(divPrev.css("z-index")) + 1; - this.maxTileZIndex = Math.max(this.maxTileZIndex, zIndex); - div.css("z-index", zIndex); - div.css("background", bg); - }, - - updateTile: function() { - if(this.dirty) { - var ajaxViewer = this; - var tileWidth = this.tileWidth; - var tileHeight = this.tileHeight; - var imgUrl = this.imgUrl; - var panel = this.panel; - - if(this.fullImage) { - $.each(this.tileMap, function() { - var i = $(this)[0]; - var j = $(this)[1]; - var row = $("TR:eq("+i+")", panel); - var cell = $("TD:eq("+j+")", row); - var attr = "url(" + imgUrl + ") -"+j*tileWidth+"px -"+i*tileHeight + "px"; - - ajaxViewer.initCell(cell); - ajaxViewer.displayCell(cell, attr); - }); - } else { - $.each(this.tileMap, function(index) { - var i = $(this)[0]; - var j = $(this)[1]; - var offset = index*tileWidth; - var attr = "url(" + imgUrl + ") no-repeat -"+offset+"px 0px"; - var row = $("TR:eq("+i+")", panel); - var cell = $("TD:eq("+j+")", row); - - ajaxViewer.initCell(cell); - ajaxViewer.displayCell(cell, attr); - }); - } - - this.dirty = false; - } - }, - - heartbeat: function() { - this.checkEventQueue(); - this.checkUpdate(); - }, - - checkUpdate: function() { - if(!this.isDirty()) - return; - - if(this.isImageLoaded()) { - this.updateTile(); - var url = this.updateUrl; - var ajaxViewer = this; - - window.onStatusNotify(AjaxViewer.STATUS_RECEIVING); - $.getScript(url, function(data, textStatus) { - if(/^/.test(data)) { - ajaxViewer.stop(); - $(document.body).html(data); - } else { - eval(data); - ajaxViewer.setDirty(true); - window.onStatusNotify(AjaxViewer.STATUS_RECEIVED); - - ajaxViewer.checkUpdate(); - } - }); - } - }, - - ptInPanel: function(pageX, pageY) { - var mainPanel = this.panel; - - var offset = mainPanel.offset(); - var x = pageX - offset.left; - var y = pageY - offset.top; - - if(x < 0 || y < 0 || x > mainPanel.width() - 1 || y > mainPanel.height() - 1) - return false; - return true; - }, - - pageToPanel: function(pageX, pageY) { - var mainPanel = this.panel; - - var offset = mainPanel.offset(); - var x = pageX - offset.left; - var y = pageY - offset.top; - - if(x < 0) - x = 0; - if(x > mainPanel.width() - 1) - x = mainPanel.width() - 1; - - if(y < 0) - y = 0; - if(y > mainPanel.height() - 1) - y = mainPanel.height() - 1; - - return { x: Math.ceil(x), y: Math.ceil(y) }; - }, - - installMouseHook: function() { - var ajaxViewer = this; - var target = $(document.body); - - target.mousemove(function(e) { - if(!ajaxViewer.ptInPanel(e.pageX, e.pageY)) - return true; - - var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY); - ajaxViewer.onMouseMove(pt.x, pt.y); - - e.stopPropagation(); - return false; - }); - - target.mousedown(function(e) { - ajaxViewer.panel.parent().focus(); - - if(!ajaxViewer.ptInPanel(e.pageX, e.pageY)) - return true; + this.maxTileZIndex = Math.max(this.maxTileZIndex, zIndex); + div.css("z-index", zIndex); + div.css("background", bg); + }, + + updateTile: function() { + if(this.dirty) { + var ajaxViewer = this; + var tileWidth = this.tileWidth; + var tileHeight = this.tileHeight; + var imgUrl = this.imgUrl; + var panel = this.panel; - var modifiers = ajaxViewer.getKeyModifiers(e); - var whichButton = e.button; - - var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY); - ajaxViewer.onMouseDown(pt.x, pt.y, whichButton, modifiers); - - e.stopPropagation(); - return false; - }); - - target.mouseup(function(e) { - if(!ajaxViewer.ptInPanel(e.pageX, e.pageY)) - return true; - - var modifiers = ajaxViewer.getKeyModifiers(e); - var whichButton = e.button; - - var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY); + if(this.fullImage) { + $.each(this.tileMap, function() { + var i = $(this)[0]; + var j = $(this)[1]; + var row = $("TR:eq("+i+")", panel); + var cell = $("TD:eq("+j+")", row); + var attr = "url(" + imgUrl + ") -"+j*tileWidth+"px -"+i*tileHeight + "px"; + + ajaxViewer.initCell(cell); + ajaxViewer.displayCell(cell, attr); + }); + } else { + $.each(this.tileMap, function(index) { + var i = $(this)[0]; + var j = $(this)[1]; + var offset = index*tileWidth; + var attr = "url(" + imgUrl + ") no-repeat -"+offset+"px 0px"; + var row = $("TR:eq("+i+")", panel); + var cell = $("TD:eq("+j+")", row); + + ajaxViewer.initCell(cell); + ajaxViewer.displayCell(cell, attr); + }); + } + + this.dirty = false; + } + }, + + heartbeat: function() { + this.checkEventQueue(); + this.checkUpdate(); + }, + + checkUpdate: function() { + if(!this.isDirty()) + return; + + if(this.isImageLoaded()) { + this.updateTile(); + var url = this.updateUrl; + var ajaxViewer = this; + + window.onStatusNotify(AjaxViewer.STATUS_RECEIVING); + $.getScript(url, function(data, textStatus) { + if(/^/.test(data)) { + ajaxViewer.stop(); + $(document.body).html(data); + } else { + eval(data); + ajaxViewer.setDirty(true); + window.onStatusNotify(AjaxViewer.STATUS_RECEIVED); + + ajaxViewer.checkUpdate(); + } + }); + } + }, + + ptInPanel: function(pageX, pageY) { + var mainPanel = this.panel; + + var offset = mainPanel.offset(); + var x = pageX - offset.left; + var y = pageY - offset.top; + + if(x < 0 || y < 0 || x > mainPanel.width() - 1 || y > mainPanel.height() - 1) + return false; + return true; + }, + + pageToPanel: function(pageX, pageY) { + var mainPanel = this.panel; + + var offset = mainPanel.offset(); + var x = pageX - offset.left; + var y = pageY - offset.top; + + if(x < 0) + x = 0; + if(x > mainPanel.width() - 1) + x = mainPanel.width() - 1; + + if(y < 0) + y = 0; + if(y > mainPanel.height() - 1) + y = mainPanel.height() - 1; + + return { x: Math.ceil(x), y: Math.ceil(y) }; + }, + + installMouseHook: function() { + var ajaxViewer = this; + var target = $(document.body); + + target.mousemove(function(e) { + if(!ajaxViewer.ptInPanel(e.pageX, e.pageY)) + return true; + + var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY); + ajaxViewer.onMouseMove(pt.x, pt.y); + + e.stopPropagation(); + return false; + }); + + target.mousedown(function(e) { + ajaxViewer.panel.parent().focus(); + + if(!ajaxViewer.ptInPanel(e.pageX, e.pageY)) + return true; + + var modifiers = ajaxViewer.getKeyModifiers(e); + var whichButton = e.button; + + var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY); + ajaxViewer.onMouseDown(pt.x, pt.y, whichButton, modifiers); + + e.stopPropagation(); + return false; + }); + + target.mouseup(function(e) { + if(!ajaxViewer.ptInPanel(e.pageX, e.pageY)) + return true; + + var modifiers = ajaxViewer.getKeyModifiers(e); + var whichButton = e.button; + + var pt = ajaxViewer.pageToPanel(e.pageX, e.pageY); + + ajaxViewer.onMouseUp(pt.x, pt.y, whichButton, modifiers); + e.stopPropagation(); + return false; + }); + + // disable browser right-click context menu + target.bind("contextmenu", function() { return false; }); + }, + + uninstallMouseHook : function() { + var target = $(document); + target.unbind("mousemove"); + target.unbind("mousedown"); + target.unbind("mouseup"); + target.unbind("contextmenu"); + }, + + requiresDefaultKeyProcess : function(e) { + switch(e.which) { + case 8 : // backspace + case 9 : // TAB + case 19 : // PAUSE/BREAK + case 20 : // CAPSLOCK + case 27 : // ESCAPE + case 16 : // SHIFT key + case 17 : // CTRL key + case 18 : // ALT key + case 33 : // PGUP + case 34 : // PGDN + case 35 : // END + case 36 : // HOME + case 37 : // LEFT + case 38 : // UP + case 39 : // RIGHT + case 40 : // DOWN + return false; + } + + if(this.getKeyModifiers(e) == AjaxViewer.SHIFT_KEY_MASK) + return true; + + if(this.getKeyModifiers(e) != 0) + return false; + + return true; + }, + + installKeyboardHook: function() { + var ajaxViewer = this; + var target = $(document); - ajaxViewer.onMouseUp(pt.x, pt.y, whichButton, modifiers); - e.stopPropagation(); - return false; - }); - - // disable browser right-click context menu - target.bind("contextmenu", function() { return false; }); - }, - - uninstallMouseHook : function() { - var target = $(document); - target.unbind("mousemove"); - target.unbind("mousedown"); - target.unbind("mouseup"); - target.unbind("contextmenu"); - }, - - requiresDefaultKeyProcess : function(e) { - switch(e.which) { - case 8 : // backspace - case 9 : // TAB - case 19 : // PAUSE/BREAK - case 20 : // CAPSLOCK - case 27 : // ESCAPE - case 16 : // SHIFT key - case 17 : // CTRL key - case 18 : // ALT key - case 33 : // PGUP - case 34 : // PGDN - case 35 : // END - case 36 : // HOME - case 37 : // LEFT - case 38 : // UP - case 39 : // RIGHT - case 40 : // DOWN - return false; - } - - if(this.getKeyModifiers(e) == AjaxViewer.SHIFT_KEY_MASK) - return true; - - if(this.getKeyModifiers(e) != 0) - return false; - - return true; - }, - - installKeyboardHook: function() { - var ajaxViewer = this; - var target = $(document); - target.keypress(function(e) { - ajaxViewer.onKeyPress(e.which, ajaxViewer.getKeyModifiers(e)); - - e.stopPropagation(); - if(ajaxViewer.requiresDefaultKeyProcess(e)) - return true; - - e.preventDefault(); - return false; - }); - - target.keydown(function(e) { + ajaxViewer.onKeyPress(e.which, ajaxViewer.getKeyModifiers(e)); + + e.stopPropagation(); + if(ajaxViewer.requiresDefaultKeyProcess(e)) + return true; + + e.preventDefault(); + return false; + }); + + target.keydown(function(e) { ajaxViewer.onKeyDown(e.which, ajaxViewer.getKeyModifiers(e)); - - e.stopPropagation(); - if(ajaxViewer.requiresDefaultKeyProcess(e)) - return true; - - e.preventDefault(); - return false; - }); - - target.keyup(function(e) { - ajaxViewer.onKeyUp(e.which, ajaxViewer.getKeyModifiers(e)); - - e.stopPropagation(); - if(ajaxViewer.requiresDefaultKeyProcess(e)) - return true; - - e.preventDefault(); - return false; - }); - }, - - uninstallKeyboardHook : function() { - var target = $(document); - target.unbind("keypress"); - target.unbind("keydown"); - target.unbind("keyup"); - }, - - onMouseMove: function(x, y) { - this.sendMouseEvent(AjaxViewer.MOUSE_MOVE, x, y, 0, 0); - }, - - onMouseDown: function(x, y, whichButton, modifiers) { - this.sendMouseEvent(AjaxViewer.MOUSE_DOWN, x, y, whichButton, modifiers); - }, - - onMouseUp: function(x, y, whichButton, modifiers) { - this.sendMouseEvent(AjaxViewer.MOUSE_UP, x, y, whichButton, modifiers); - - var curTick = new Date().getTime(); - if(this.lastClickEvent.time && (curTick - this.lastClickEvent.time < 300)) { - this.onMouseDblClick(this.lastClickEvent.x, this.lastClickEvent.y, - this.lastClickEvent.button, this.lastClickEvent.modifiers); - } - - this.lastClickEvent.x = x; - this.lastClickEvent.y = y; - this.lastClickEvent.button = whichButton; - this.lastClickEvent.modifiers = modifiers; - this.lastClickEvent.time = curTick; - }, - - onMouseDblClick: function(x, y, whichButton, modifiers) { - this.sendMouseEvent(AjaxViewer.MOUSE_DBLCLK, x, y, whichButton, modifiers); - }, - + + e.stopPropagation(); + if(ajaxViewer.requiresDefaultKeyProcess(e)) + return true; + + e.preventDefault(); + return false; + }); + + target.keyup(function(e) { + ajaxViewer.onKeyUp(e.which, ajaxViewer.getKeyModifiers(e)); + + e.stopPropagation(); + if(ajaxViewer.requiresDefaultKeyProcess(e)) + return true; + + e.preventDefault(); + return false; + }); + }, + + uninstallKeyboardHook : function() { + var target = $(document); + target.unbind("keypress"); + target.unbind("keydown"); + target.unbind("keyup"); + }, + + onMouseMove: function(x, y) { + this.sendMouseEvent(AjaxViewer.MOUSE_MOVE, x, y, 0, 0); + }, + + onMouseDown: function(x, y, whichButton, modifiers) { + this.sendMouseEvent(AjaxViewer.MOUSE_DOWN, x, y, whichButton, modifiers); + }, + + onMouseUp: function(x, y, whichButton, modifiers) { + this.sendMouseEvent(AjaxViewer.MOUSE_UP, x, y, whichButton, modifiers); + + var curTick = new Date().getTime(); + if(this.lastClickEvent.time && (curTick - this.lastClickEvent.time < 300)) { + this.onMouseDblClick(this.lastClickEvent.x, this.lastClickEvent.y, + this.lastClickEvent.button, this.lastClickEvent.modifiers); + } + + this.lastClickEvent.x = x; + this.lastClickEvent.y = y; + this.lastClickEvent.button = whichButton; + this.lastClickEvent.modifiers = modifiers; + this.lastClickEvent.time = curTick; + }, + + onMouseDblClick: function(x, y, whichButton, modifiers) { + this.sendMouseEvent(AjaxViewer.MOUSE_DBLCLK, x, y, whichButton, modifiers); + }, + onKeyPress: function(code, modifiers) { g_logger.log(Logger.LEVEL_WARN, "RAW KEYBOARD EVENT. KEY-PRESS: " + code + ", modifers: " + modifiers); this.dispatchKeyboardInput(AjaxViewer.KEY_PRESS, code, modifiers); - }, - + }, + onKeyDown: function(code, modifiers) { g_logger.log(Logger.LEVEL_WARN, "RAW KEYBOARD EVENT. KEY-DOWN: " + code + ", modifers: " + modifiers); this.dispatchKeyboardInput(AjaxViewer.KEY_DOWN, code, modifiers); - }, - + }, + onKeyUp: function(code, modifiers) { g_logger.log(Logger.LEVEL_WARN, "RAW KEYBOARD EVENT. KEY-UP: " + code + ", modifers: " + modifiers); @@ -1308,32 +1308,32 @@ AjaxViewer.prototype = { break; } } - }, - - getKeyModifiers: function(e) { - var modifiers = 0; - if(e.altKey) - modifiers |= AjaxViewer.ALT_KEY_MASK; - - if(e.altLeft) - modifiers |= AjaxViewer.LEFT_ALT_MASK; - - if(e.ctrlKey) - modifiers |= AjaxViewer.CTRL_KEY_MASK; - - if(e.ctrlLeft) - modifiers |= AjaxViewer.LEFT_CTRL_MASK; - - if(e.shiftKey) - modifiers |= AjaxViewer.SHIFT_KEY_MASK; - - if(e.shiftLeft) - modifiers |= AjaxViewer.LEFT_SHIFT_MASK; - - if(e.metaKey) - modifiers |= AjaxViewer.META_KEY_MASK; - - return modifiers; - } -}; + }, + + getKeyModifiers: function(e) { + var modifiers = 0; + if(e.altKey) + modifiers |= AjaxViewer.ALT_KEY_MASK; + + if(e.altLeft) + modifiers |= AjaxViewer.LEFT_ALT_MASK; + + if(e.ctrlKey) + modifiers |= AjaxViewer.CTRL_KEY_MASK; + + if(e.ctrlLeft) + modifiers |= AjaxViewer.LEFT_CTRL_MASK; + + if(e.shiftKey) + modifiers |= AjaxViewer.SHIFT_KEY_MASK; + + if(e.shiftLeft) + modifiers |= AjaxViewer.LEFT_SHIFT_MASK; + + if(e.metaKey) + modifiers |= AjaxViewer.META_KEY_MASK; + + return modifiers; + } +}; diff --git a/console-proxy/scripts/run.bat b/console-proxy/scripts/run.bat index 39655f9f09f..ce6dc404574 100644 --- a/console-proxy/scripts/run.bat +++ b/console-proxy/scripts/run.bat @@ -1,18 +1,18 @@ -rem Licensed to the Apache Software Foundation (ASF) under one -rem or more contributor license agreements. See the NOTICE file -rem distributed with this work for additional information -rem regarding copyright ownership. The ASF licenses this file -rem to you under the Apache License, Version 2.0 (the -rem "License"); you may not use this file except in compliance -rem with the License. You may obtain a copy of the License at -rem -rem http://www.apache.org/licenses/LICENSE-2.0 -rem -rem Unless required by applicable law or agreed to in writing, -rem software distributed under the License is distributed on an -rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -rem KIND, either express or implied. See the License for the -rem specific language governing permissions and limitations -rem under the License. - -java -mx700m -cp cloud-console-proxy.jar;;cloud-console-common.jar;log4j-1.2.15.jar;apache-log4j-extras-1.0.jar;gson-1.3.jar;commons-logging-1.1.1.jar;.;.\conf; com.cloud.consoleproxy.ConsoleProxy %* +rem Licensed to the Apache Software Foundation (ASF) under one +rem or more contributor license agreements. See the NOTICE file +rem distributed with this work for additional information +rem regarding copyright ownership. The ASF licenses this file +rem to you under the Apache License, Version 2.0 (the +rem "License"); you may not use this file except in compliance +rem with the License. You may obtain a copy of the License at +rem +rem http://www.apache.org/licenses/LICENSE-2.0 +rem +rem Unless required by applicable law or agreed to in writing, +rem software distributed under the License is distributed on an +rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +rem KIND, either express or implied. See the License for the +rem specific language governing permissions and limitations +rem under the License. + +java -mx700m -cp cloud-console-proxy.jar;;cloud-console-common.jar;log4j-1.2.15.jar;apache-log4j-extras-1.0.jar;gson-1.3.jar;commons-logging-1.1.1.jar;.;.\conf; com.cloud.consoleproxy.ConsoleProxy %* diff --git a/console-proxy/src/com/cloud/consoleproxy/AjaxFIFOImageCache.java b/console-proxy/src/com/cloud/consoleproxy/AjaxFIFOImageCache.java index a745d0d9e81..cff00b3317d 100644 --- a/console-proxy/src/com/cloud/consoleproxy/AjaxFIFOImageCache.java +++ b/console-proxy/src/com/cloud/consoleproxy/AjaxFIFOImageCache.java @@ -14,53 +14,53 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +package com.cloud.consoleproxy; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import com.cloud.consoleproxy.util.Logger; - -public class AjaxFIFOImageCache { - private static final Logger s_logger = Logger.getLogger(AjaxFIFOImageCache.class); - - private List fifoQueue; - private Map cache; - private int cacheSize; + +public class AjaxFIFOImageCache { + private static final Logger s_logger = Logger.getLogger(AjaxFIFOImageCache.class); + + private List fifoQueue; + private Map cache; + private int cacheSize; private int nextKey = 0; - - public AjaxFIFOImageCache(int cacheSize) { - this.cacheSize = cacheSize; - fifoQueue = new ArrayList(); - cache = new HashMap(); - } - - public synchronized void clear() { - fifoQueue.clear(); - cache.clear(); - } - - public synchronized int putImage(byte[] image) { - while(cache.size() >= cacheSize) { - Integer keyToRemove = fifoQueue.remove(0); - cache.remove(keyToRemove); - - if(s_logger.isTraceEnabled()) - s_logger.trace("Remove image from cache, key: " + keyToRemove); - } - - int key = getNextKey(); - - if(s_logger.isTraceEnabled()) - s_logger.trace("Add image to cache, key: " + key); - - cache.put(key, image); - fifoQueue.add(key); - return key; - } - + + public AjaxFIFOImageCache(int cacheSize) { + this.cacheSize = cacheSize; + fifoQueue = new ArrayList(); + cache = new HashMap(); + } + + public synchronized void clear() { + fifoQueue.clear(); + cache.clear(); + } + + public synchronized int putImage(byte[] image) { + while(cache.size() >= cacheSize) { + Integer keyToRemove = fifoQueue.remove(0); + cache.remove(keyToRemove); + + if(s_logger.isTraceEnabled()) + s_logger.trace("Remove image from cache, key: " + keyToRemove); + } + + int key = getNextKey(); + + if(s_logger.isTraceEnabled()) + s_logger.trace("Add image to cache, key: " + key); + + cache.put(key, image); + fifoQueue.add(key); + return key; + } + public synchronized byte[] getImage(int key) { if (key == 0) { key = nextKey; diff --git a/console-proxy/src/com/cloud/consoleproxy/AuthenticationException.java b/console-proxy/src/com/cloud/consoleproxy/AuthenticationException.java index aaf8e44eb0a..3fa266792ae 100644 --- a/console-proxy/src/com/cloud/consoleproxy/AuthenticationException.java +++ b/console-proxy/src/com/cloud/consoleproxy/AuthenticationException.java @@ -14,20 +14,20 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -public class AuthenticationException extends Exception { - private static final long serialVersionUID = -393139302884898842L; - public AuthenticationException() { - super(); - } - public AuthenticationException(String s) { - super(s); - } - public AuthenticationException(String message, Throwable cause) { - super(message, cause); - } - public AuthenticationException(Throwable cause) { - super(cause); - } +package com.cloud.consoleproxy; + +public class AuthenticationException extends Exception { + private static final long serialVersionUID = -393139302884898842L; + public AuthenticationException() { + super(); + } + public AuthenticationException(String s) { + super(s); + } + public AuthenticationException(String message, Throwable cause) { + super(message, cause); + } + public AuthenticationException(Throwable cause) { + super(cause); + } } \ No newline at end of file diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java index d91a198a103..6cadeca1f4a 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java @@ -14,8 +14,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - +package com.cloud.consoleproxy; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -30,377 +30,377 @@ import com.cloud.consoleproxy.util.Logger; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; - -public class ConsoleProxyAjaxHandler implements HttpHandler { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyAjaxHandler.class); - - public ConsoleProxyAjaxHandler() { - } - - public void handle(HttpExchange t) throws IOException { - try { - if(s_logger.isTraceEnabled()) - s_logger.trace("AjaxHandler " + t.getRequestURI()); - - long startTick = System.currentTimeMillis(); - - doHandle(t); - - if(s_logger.isTraceEnabled()) - s_logger.trace(t.getRequestURI() + " process time " + (System.currentTimeMillis() - startTick) + " ms"); - } catch (IOException e) { - throw e; - } catch (IllegalArgumentException e) { - s_logger.warn("Exception, ", e); - t.sendResponseHeaders(400, -1); // bad request - } catch(Throwable e) { - s_logger.error("Unexpected exception, ", e); - t.sendResponseHeaders(500, -1); // server error - } finally { - t.close(); - } - } - - private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException { - String queries = t.getRequestURI().getQuery(); - if(s_logger.isTraceEnabled()) - s_logger.trace("Handle AJAX request: " + queries); - - Map queryMap = ConsoleProxyHttpHandlerHelper.getQueryMap(queries); - - String host = queryMap.get("host"); - String portStr = queryMap.get("port"); - String sid = queryMap.get("sid"); - String tag = queryMap.get("tag"); - String ticket = queryMap.get("ticket"); - String ajaxSessionIdStr = queryMap.get("sess"); - String eventStr = queryMap.get("event"); - String console_url = queryMap.get("consoleurl"); - String console_host_session = queryMap.get("sessionref"); - - if(tag == null) - tag = ""; - - long ajaxSessionId = 0; - int event = 0; - - int port; - - if(host == null || portStr == null || sid == null) - throw new IllegalArgumentException(); - - try { - port = Integer.parseInt(portStr); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + portStr); - throw new IllegalArgumentException(e); - } - - if(ajaxSessionIdStr != null) { - try { - ajaxSessionId = Long.parseLong(ajaxSessionIdStr); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + ajaxSessionIdStr); - throw new IllegalArgumentException(e); - } - } - - if(eventStr != null) { - try { - event = Integer.parseInt(eventStr); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + eventStr); - throw new IllegalArgumentException(e); - } - } - - ConsoleProxyClient viewer = null; - try { - ConsoleProxyClientParam param = new ConsoleProxyClientParam(); - param.setClientHostAddress(host); - param.setClientHostPort(port); - param.setClientHostPassword(sid); - param.setClientTag(tag); - param.setTicket(ticket); - param.setClientTunnelUrl(console_url); - param.setClientTunnelSession(console_host_session); - - viewer = ConsoleProxy.getAjaxVncViewer(param, ajaxSessionIdStr); - } catch(Exception e) { - - s_logger.warn("Failed to create viewer due to " + e.getMessage(), e); - - String[] content = new String[] { - "", - "
", - "

Access is denied for the console session. Please close the window and retry again

", - "
" - }; - - StringBuffer sb = new StringBuffer(); - for(int i = 0; i < content.length; i++) - sb.append(content[i]); - - sendResponse(t, "text/html", sb.toString()); - return; - } - - if(event != 0) { - if(ajaxSessionId != 0 && ajaxSessionId == viewer.getAjaxSessionId()) { - if(event == 7) { - // client send over an event bag - InputStream is = t.getRequestBody(); - handleClientEventBag(viewer, convertStreamToString(is, true)); - } else { - handleClientEvent(viewer, event, queryMap); - } - sendResponse(t, "text/html", "OK"); - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("Ajax request comes from a different session, id in request: " + ajaxSessionId + ", id in viewer: " + viewer.getAjaxSessionId()); - - sendResponse(t, "text/html", "Invalid ajax client session id"); - } - } else { - if(ajaxSessionId != 0 && ajaxSessionId != viewer.getAjaxSessionId()) { - s_logger.info("Ajax request comes from a different session, id in request: " + ajaxSessionId + ", id in viewer: " + viewer.getAjaxSessionId()); - handleClientKickoff(t, viewer); - } else if(ajaxSessionId == 0) { - if(s_logger.isDebugEnabled()) - s_logger.debug("Ajax request indicates a fresh client start"); - - String title = queryMap.get("t"); - String guest = queryMap.get("guest"); - handleClientStart(t, viewer, title != null ? title : "", guest); - } else { - - if(s_logger.isTraceEnabled()) - s_logger.trace("Ajax request indicates client update"); - - handleClientUpdate(t, viewer); - } - } - } - - private static String convertStreamToString(InputStream is, boolean closeStreamAfterRead) { - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - StringBuilder sb = new StringBuilder(); - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb.append(line + "\n"); - } - } catch (IOException e) { - s_logger.warn("Exception while reading request body: ", e); - } finally { - if(closeStreamAfterRead) { - try { - is.close(); - } catch (IOException e) { - } - } - } - return sb.toString(); - } - - private void sendResponse(HttpExchange t, String contentType, String response) throws IOException { - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", contentType); - - t.sendResponseHeaders(200, response.length()); - OutputStream os = t.getResponseBody(); - try { - os.write(response.getBytes()); - } finally { - os.close(); - } - } - - @SuppressWarnings("deprecation") - private void handleClientEventBag(ConsoleProxyClient viewer, String requestData) { - if(s_logger.isTraceEnabled()) - s_logger.trace("Handle event bag, event bag: " + requestData); - - int start = requestData.indexOf("="); - if(start < 0) - start = 0; - else if(start > 0) - start++; - String data = URLDecoder.decode(requestData.substring(start)); - String[] tokens = data.split("\\|"); - if(tokens != null && tokens.length > 0) { - int count = 0; - try { - count = Integer.parseInt(tokens[0]); - int parsePos = 1; - int type, event, x, y, code, modifiers; - for(int i = 0; i < count; i++) { - type = Integer.parseInt(tokens[parsePos++]); - if(type == 1) { - // mouse event - event = Integer.parseInt(tokens[parsePos++]); - x = Integer.parseInt(tokens[parsePos++]); - y = Integer.parseInt(tokens[parsePos++]); - code = Integer.parseInt(tokens[parsePos++]); - modifiers = Integer.parseInt(tokens[parsePos++]); - - Map queryMap = new HashMap(); - queryMap.put("event", String.valueOf(event)); - queryMap.put("x", String.valueOf(x)); - queryMap.put("y", String.valueOf(y)); - queryMap.put("code", String.valueOf(code)); - queryMap.put("modifier", String.valueOf(modifiers)); - handleClientEvent(viewer, event, queryMap); - } else { - // keyboard event - event = Integer.parseInt(tokens[parsePos++]); - code = Integer.parseInt(tokens[parsePos++]); - modifiers = Integer.parseInt(tokens[parsePos++]); - - Map queryMap = new HashMap(); - queryMap.put("event", String.valueOf(event)); - queryMap.put("code", String.valueOf(code)); - queryMap.put("modifier", String.valueOf(modifiers)); - handleClientEvent(viewer, event, queryMap); - } - } - } catch(NumberFormatException e) { - s_logger.warn("Exception in handle client event bag: " + data + ", ", e); - } catch(Exception e) { - s_logger.warn("Exception in handle client event bag: " + data + ", ", e); - } catch(OutOfMemoryError e) { - s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); - System.exit(1); - } - } - } - - private void handleClientEvent(ConsoleProxyClient viewer, int event, Map queryMap) { - int code = 0; - int x = 0, y = 0; - int modifiers = 0; - - String str; - switch(event) { - case 1: // mouse move - case 2: // mouse down - case 3: // mouse up - case 8: // mouse double click - str = queryMap.get("x"); - if(str != null) { - try { - x = Integer.parseInt(str); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + str); - throw new IllegalArgumentException(e); - } - } - str = queryMap.get("y"); - if(str != null) { - try { - y = Integer.parseInt(str); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + str); - throw new IllegalArgumentException(e); - } - } - - if(event != 1) { - str = queryMap.get("code"); - try { - code = Integer.parseInt(str); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + str); - throw new IllegalArgumentException(e); - } - - str = queryMap.get("modifier"); - try { - modifiers = Integer.parseInt(str); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + str); - throw new IllegalArgumentException(e); - } - - if(s_logger.isTraceEnabled()) - s_logger.trace("Handle client mouse event. event: " + event + ", x: " + x + ", y: " + y + ", button: " + code + ", modifier: " + modifiers); - } else { - if(s_logger.isTraceEnabled()) - s_logger.trace("Handle client mouse move event. x: " + x + ", y: " + y); - } - viewer.sendClientMouseEvent(InputEventType.fromEventCode(event), x, y, code, modifiers); - break; - - case 4: // key press - case 5: // key down - case 6: // key up - str = queryMap.get("code"); - try { - code = Integer.parseInt(str); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + str); - throw new IllegalArgumentException(e); - } - - str = queryMap.get("modifier"); - try { - modifiers = Integer.parseInt(str); - } catch (NumberFormatException e) { - s_logger.warn("Invalid number parameter in query string: " + str); - throw new IllegalArgumentException(e); - } - - if(s_logger.isDebugEnabled()) - s_logger.debug("Handle client keyboard event. event: " + event + ", code: " + code + ", modifier: " + modifiers); - viewer.sendClientRawKeyboardEvent(InputEventType.fromEventCode(event), code, modifiers); - break; - - default : - break; - } - } - - private void handleClientKickoff(HttpExchange t, ConsoleProxyClient viewer) throws IOException { - String response = viewer.onAjaxClientKickoff(); - t.sendResponseHeaders(200, response.length()); - OutputStream os = t.getResponseBody(); - try { - os.write(response.getBytes()); - } finally { - os.close(); - } - } - - private void handleClientStart(HttpExchange t, ConsoleProxyClient viewer, String title, String guest) throws IOException { - List languages = t.getRequestHeaders().get("Accept-Language"); - String response = viewer.onAjaxClientStart(title, languages, guest); - - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "text/html"); - hds.set("Cache-Control", "no-cache"); - hds.set("Cache-Control", "no-store"); - t.sendResponseHeaders(200, response.length()); - - OutputStream os = t.getResponseBody(); - try { - os.write(response.getBytes()); - } finally { - os.close(); - } - } - - private void handleClientUpdate(HttpExchange t, ConsoleProxyClient viewer) throws IOException { - String response = viewer.onAjaxClientUpdate(); - - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "text/javascript"); - t.sendResponseHeaders(200, response.length()); - - OutputStream os = t.getResponseBody(); - try { - os.write(response.getBytes()); - } finally { - os.close(); - } - } -} + +public class ConsoleProxyAjaxHandler implements HttpHandler { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyAjaxHandler.class); + + public ConsoleProxyAjaxHandler() { + } + + public void handle(HttpExchange t) throws IOException { + try { + if(s_logger.isTraceEnabled()) + s_logger.trace("AjaxHandler " + t.getRequestURI()); + + long startTick = System.currentTimeMillis(); + + doHandle(t); + + if(s_logger.isTraceEnabled()) + s_logger.trace(t.getRequestURI() + " process time " + (System.currentTimeMillis() - startTick) + " ms"); + } catch (IOException e) { + throw e; + } catch (IllegalArgumentException e) { + s_logger.warn("Exception, ", e); + t.sendResponseHeaders(400, -1); // bad request + } catch(Throwable e) { + s_logger.error("Unexpected exception, ", e); + t.sendResponseHeaders(500, -1); // server error + } finally { + t.close(); + } + } + + private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException { + String queries = t.getRequestURI().getQuery(); + if(s_logger.isTraceEnabled()) + s_logger.trace("Handle AJAX request: " + queries); + + Map queryMap = ConsoleProxyHttpHandlerHelper.getQueryMap(queries); + + String host = queryMap.get("host"); + String portStr = queryMap.get("port"); + String sid = queryMap.get("sid"); + String tag = queryMap.get("tag"); + String ticket = queryMap.get("ticket"); + String ajaxSessionIdStr = queryMap.get("sess"); + String eventStr = queryMap.get("event"); + String console_url = queryMap.get("consoleurl"); + String console_host_session = queryMap.get("sessionref"); + + if(tag == null) + tag = ""; + + long ajaxSessionId = 0; + int event = 0; + + int port; + + if(host == null || portStr == null || sid == null) + throw new IllegalArgumentException(); + + try { + port = Integer.parseInt(portStr); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + portStr); + throw new IllegalArgumentException(e); + } + + if(ajaxSessionIdStr != null) { + try { + ajaxSessionId = Long.parseLong(ajaxSessionIdStr); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + ajaxSessionIdStr); + throw new IllegalArgumentException(e); + } + } + + if(eventStr != null) { + try { + event = Integer.parseInt(eventStr); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + eventStr); + throw new IllegalArgumentException(e); + } + } + + ConsoleProxyClient viewer = null; + try { + ConsoleProxyClientParam param = new ConsoleProxyClientParam(); + param.setClientHostAddress(host); + param.setClientHostPort(port); + param.setClientHostPassword(sid); + param.setClientTag(tag); + param.setTicket(ticket); + param.setClientTunnelUrl(console_url); + param.setClientTunnelSession(console_host_session); + + viewer = ConsoleProxy.getAjaxVncViewer(param, ajaxSessionIdStr); + } catch(Exception e) { + + s_logger.warn("Failed to create viewer due to " + e.getMessage(), e); + + String[] content = new String[] { + "", + "
", + "

Access is denied for the console session. Please close the window and retry again

", + "
" + }; + + StringBuffer sb = new StringBuffer(); + for(int i = 0; i < content.length; i++) + sb.append(content[i]); + + sendResponse(t, "text/html", sb.toString()); + return; + } + + if(event != 0) { + if(ajaxSessionId != 0 && ajaxSessionId == viewer.getAjaxSessionId()) { + if(event == 7) { + // client send over an event bag + InputStream is = t.getRequestBody(); + handleClientEventBag(viewer, convertStreamToString(is, true)); + } else { + handleClientEvent(viewer, event, queryMap); + } + sendResponse(t, "text/html", "OK"); + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("Ajax request comes from a different session, id in request: " + ajaxSessionId + ", id in viewer: " + viewer.getAjaxSessionId()); + + sendResponse(t, "text/html", "Invalid ajax client session id"); + } + } else { + if(ajaxSessionId != 0 && ajaxSessionId != viewer.getAjaxSessionId()) { + s_logger.info("Ajax request comes from a different session, id in request: " + ajaxSessionId + ", id in viewer: " + viewer.getAjaxSessionId()); + handleClientKickoff(t, viewer); + } else if(ajaxSessionId == 0) { + if(s_logger.isDebugEnabled()) + s_logger.debug("Ajax request indicates a fresh client start"); + + String title = queryMap.get("t"); + String guest = queryMap.get("guest"); + handleClientStart(t, viewer, title != null ? title : "", guest); + } else { + + if(s_logger.isTraceEnabled()) + s_logger.trace("Ajax request indicates client update"); + + handleClientUpdate(t, viewer); + } + } + } + + private static String convertStreamToString(InputStream is, boolean closeStreamAfterRead) { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + String line = null; + try { + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + } catch (IOException e) { + s_logger.warn("Exception while reading request body: ", e); + } finally { + if(closeStreamAfterRead) { + try { + is.close(); + } catch (IOException e) { + } + } + } + return sb.toString(); + } + + private void sendResponse(HttpExchange t, String contentType, String response) throws IOException { + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", contentType); + + t.sendResponseHeaders(200, response.length()); + OutputStream os = t.getResponseBody(); + try { + os.write(response.getBytes()); + } finally { + os.close(); + } + } + + @SuppressWarnings("deprecation") + private void handleClientEventBag(ConsoleProxyClient viewer, String requestData) { + if(s_logger.isTraceEnabled()) + s_logger.trace("Handle event bag, event bag: " + requestData); + + int start = requestData.indexOf("="); + if(start < 0) + start = 0; + else if(start > 0) + start++; + String data = URLDecoder.decode(requestData.substring(start)); + String[] tokens = data.split("\\|"); + if(tokens != null && tokens.length > 0) { + int count = 0; + try { + count = Integer.parseInt(tokens[0]); + int parsePos = 1; + int type, event, x, y, code, modifiers; + for(int i = 0; i < count; i++) { + type = Integer.parseInt(tokens[parsePos++]); + if(type == 1) { + // mouse event + event = Integer.parseInt(tokens[parsePos++]); + x = Integer.parseInt(tokens[parsePos++]); + y = Integer.parseInt(tokens[parsePos++]); + code = Integer.parseInt(tokens[parsePos++]); + modifiers = Integer.parseInt(tokens[parsePos++]); + + Map queryMap = new HashMap(); + queryMap.put("event", String.valueOf(event)); + queryMap.put("x", String.valueOf(x)); + queryMap.put("y", String.valueOf(y)); + queryMap.put("code", String.valueOf(code)); + queryMap.put("modifier", String.valueOf(modifiers)); + handleClientEvent(viewer, event, queryMap); + } else { + // keyboard event + event = Integer.parseInt(tokens[parsePos++]); + code = Integer.parseInt(tokens[parsePos++]); + modifiers = Integer.parseInt(tokens[parsePos++]); + + Map queryMap = new HashMap(); + queryMap.put("event", String.valueOf(event)); + queryMap.put("code", String.valueOf(code)); + queryMap.put("modifier", String.valueOf(modifiers)); + handleClientEvent(viewer, event, queryMap); + } + } + } catch(NumberFormatException e) { + s_logger.warn("Exception in handle client event bag: " + data + ", ", e); + } catch(Exception e) { + s_logger.warn("Exception in handle client event bag: " + data + ", ", e); + } catch(OutOfMemoryError e) { + s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); + System.exit(1); + } + } + } + + private void handleClientEvent(ConsoleProxyClient viewer, int event, Map queryMap) { + int code = 0; + int x = 0, y = 0; + int modifiers = 0; + + String str; + switch(event) { + case 1: // mouse move + case 2: // mouse down + case 3: // mouse up + case 8: // mouse double click + str = queryMap.get("x"); + if(str != null) { + try { + x = Integer.parseInt(str); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + str); + throw new IllegalArgumentException(e); + } + } + str = queryMap.get("y"); + if(str != null) { + try { + y = Integer.parseInt(str); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + str); + throw new IllegalArgumentException(e); + } + } + + if(event != 1) { + str = queryMap.get("code"); + try { + code = Integer.parseInt(str); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + str); + throw new IllegalArgumentException(e); + } + + str = queryMap.get("modifier"); + try { + modifiers = Integer.parseInt(str); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + str); + throw new IllegalArgumentException(e); + } + + if(s_logger.isTraceEnabled()) + s_logger.trace("Handle client mouse event. event: " + event + ", x: " + x + ", y: " + y + ", button: " + code + ", modifier: " + modifiers); + } else { + if(s_logger.isTraceEnabled()) + s_logger.trace("Handle client mouse move event. x: " + x + ", y: " + y); + } + viewer.sendClientMouseEvent(InputEventType.fromEventCode(event), x, y, code, modifiers); + break; + + case 4: // key press + case 5: // key down + case 6: // key up + str = queryMap.get("code"); + try { + code = Integer.parseInt(str); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + str); + throw new IllegalArgumentException(e); + } + + str = queryMap.get("modifier"); + try { + modifiers = Integer.parseInt(str); + } catch (NumberFormatException e) { + s_logger.warn("Invalid number parameter in query string: " + str); + throw new IllegalArgumentException(e); + } + + if(s_logger.isDebugEnabled()) + s_logger.debug("Handle client keyboard event. event: " + event + ", code: " + code + ", modifier: " + modifiers); + viewer.sendClientRawKeyboardEvent(InputEventType.fromEventCode(event), code, modifiers); + break; + + default : + break; + } + } + + private void handleClientKickoff(HttpExchange t, ConsoleProxyClient viewer) throws IOException { + String response = viewer.onAjaxClientKickoff(); + t.sendResponseHeaders(200, response.length()); + OutputStream os = t.getResponseBody(); + try { + os.write(response.getBytes()); + } finally { + os.close(); + } + } + + private void handleClientStart(HttpExchange t, ConsoleProxyClient viewer, String title, String guest) throws IOException { + List languages = t.getRequestHeaders().get("Accept-Language"); + String response = viewer.onAjaxClientStart(title, languages, guest); + + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "text/html"); + hds.set("Cache-Control", "no-cache"); + hds.set("Cache-Control", "no-store"); + t.sendResponseHeaders(200, response.length()); + + OutputStream os = t.getResponseBody(); + try { + os.write(response.getBytes()); + } finally { + os.close(); + } + } + + private void handleClientUpdate(HttpExchange t, ConsoleProxyClient viewer) throws IOException { + String response = viewer.onAjaxClientUpdate(); + + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "text/javascript"); + t.sendResponseHeaders(200, response.length()); + + OutputStream os = t.getResponseBody(); + try { + os.write(response.getBytes()); + } finally { + os.close(); + } + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java index 9c0094839cf..5e1014963f3 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAjaxImageHandler.java @@ -14,87 +14,87 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - +package com.cloud.consoleproxy; + import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Map; - +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; + import com.cloud.consoleproxy.util.Logger; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -public class ConsoleProxyAjaxImageHandler implements HttpHandler { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyAjaxImageHandler.class); - - public void handle(HttpExchange t) throws IOException { - try { - if(s_logger.isDebugEnabled()) - s_logger.debug("AjaxImageHandler " + t.getRequestURI()); - - long startTick = System.currentTimeMillis(); - - doHandle(t); - - if(s_logger.isDebugEnabled()) - s_logger.debug(t.getRequestURI() + "Process time " + (System.currentTimeMillis() - startTick) + " ms"); - } catch (IOException e) { - throw e; - } catch (IllegalArgumentException e) { - s_logger.warn("Exception, ", e); - t.sendResponseHeaders(400, -1); // bad request - } catch(OutOfMemoryError e) { - s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); - System.exit(1); - } catch(Throwable e) { - s_logger.error("Unexpected exception, ", e); - t.sendResponseHeaders(500, -1); // server error - } finally { - t.close(); - } - } - - private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException { - String queries = t.getRequestURI().getQuery(); - Map queryMap = ConsoleProxyHttpHandlerHelper.getQueryMap(queries); - - String host = queryMap.get("host"); - String portStr = queryMap.get("port"); - String sid = queryMap.get("sid"); - String tag = queryMap.get("tag"); - String ticket = queryMap.get("ticket"); - String keyStr = queryMap.get("key"); - String console_url = queryMap.get("consoleurl"); - String console_host_session = queryMap.get("sessionref"); - String w = queryMap.get("w"); +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class ConsoleProxyAjaxImageHandler implements HttpHandler { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyAjaxImageHandler.class); + + public void handle(HttpExchange t) throws IOException { + try { + if(s_logger.isDebugEnabled()) + s_logger.debug("AjaxImageHandler " + t.getRequestURI()); + + long startTick = System.currentTimeMillis(); + + doHandle(t); + + if(s_logger.isDebugEnabled()) + s_logger.debug(t.getRequestURI() + "Process time " + (System.currentTimeMillis() - startTick) + " ms"); + } catch (IOException e) { + throw e; + } catch (IllegalArgumentException e) { + s_logger.warn("Exception, ", e); + t.sendResponseHeaders(400, -1); // bad request + } catch(OutOfMemoryError e) { + s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); + System.exit(1); + } catch(Throwable e) { + s_logger.error("Unexpected exception, ", e); + t.sendResponseHeaders(500, -1); // server error + } finally { + t.close(); + } + } + + private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException { + String queries = t.getRequestURI().getQuery(); + Map queryMap = ConsoleProxyHttpHandlerHelper.getQueryMap(queries); + + String host = queryMap.get("host"); + String portStr = queryMap.get("port"); + String sid = queryMap.get("sid"); + String tag = queryMap.get("tag"); + String ticket = queryMap.get("ticket"); + String keyStr = queryMap.get("key"); + String console_url = queryMap.get("consoleurl"); + String console_host_session = queryMap.get("sessionref"); + String w = queryMap.get("w"); String h = queryMap.get("h"); - + int key = 0; int width = 144; int height = 110; - - if(tag == null) - tag = ""; - - int port; - if(host == null || portStr == null || sid == null) - throw new IllegalArgumentException(); - - try { - port = Integer.parseInt(portStr); - } catch (NumberFormatException e) { - s_logger.warn("Invalid numeric parameter in query string: " + portStr); - throw new IllegalArgumentException(e); - } - - try { + + if(tag == null) + tag = ""; + + int port; + if(host == null || portStr == null || sid == null) + throw new IllegalArgumentException(); + + try { + port = Integer.parseInt(portStr); + } catch (NumberFormatException e) { + s_logger.warn("Invalid numeric parameter in query string: " + portStr); + throw new IllegalArgumentException(e); + } + + try { if (keyStr != null) - key = Integer.parseInt(keyStr); + key = Integer.parseInt(keyStr); if(null != w) width = Integer.parseInt(w); @@ -102,58 +102,58 @@ public class ConsoleProxyAjaxImageHandler implements HttpHandler { height = Integer.parseInt(h); } catch (NumberFormatException e) { - s_logger.warn("Invalid numeric parameter in query string: " + keyStr); - throw new IllegalArgumentException(e); - } + s_logger.warn("Invalid numeric parameter in query string: " + keyStr); + throw new IllegalArgumentException(e); + } - ConsoleProxyClientParam param = new ConsoleProxyClientParam(); - param.setClientHostAddress(host); - param.setClientHostPort(port); - param.setClientHostPassword(sid); - param.setClientTag(tag); - param.setTicket(ticket); - param.setClientTunnelUrl(console_url); - param.setClientTunnelSession(console_host_session); + ConsoleProxyClientParam param = new ConsoleProxyClientParam(); + param.setClientHostAddress(host); + param.setClientHostPort(port); + param.setClientHostPassword(sid); + param.setClientTag(tag); + param.setTicket(ticket); + param.setClientTunnelUrl(console_url); + param.setClientTunnelSession(console_host_session); - ConsoleProxyClient viewer = ConsoleProxy.getVncViewer(param); + ConsoleProxyClient viewer = ConsoleProxy.getVncViewer(param); - if (key == 0) { - Image scaledImage = viewer.getClientScaledImage(width, height); - BufferedImage bufferedImage = new BufferedImage(width, height, - BufferedImage.TYPE_3BYTE_BGR); - Graphics2D bufImageGraphics = bufferedImage.createGraphics(); - bufImageGraphics.drawImage(scaledImage, 0, 0, null); - ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); - javax.imageio.ImageIO.write(bufferedImage, "jpg", bos); - byte[] bs = bos.toByteArray(); - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "image/jpeg"); - hds.set("Cache-Control", "no-cache"); - hds.set("Cache-Control", "no-store"); - t.sendResponseHeaders(200, bs.length); - OutputStream os = t.getResponseBody(); - os.write(bs); - os.close(); - } else { - AjaxFIFOImageCache imageCache = viewer.getAjaxImageCache(); - byte[] img = imageCache.getImage(key); - - if(img != null) { - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "image/jpeg"); - t.sendResponseHeaders(200, img.length); - - OutputStream os = t.getResponseBody(); - try { - os.write(img, 0, img.length); - } finally { - os.close(); - } - } else { - if(s_logger.isInfoEnabled()) - s_logger.info("Image has already been swept out, key: " + key); - t.sendResponseHeaders(404, -1); - } - } - } -} + if (key == 0) { + Image scaledImage = viewer.getClientScaledImage(width, height); + BufferedImage bufferedImage = new BufferedImage(width, height, + BufferedImage.TYPE_3BYTE_BGR); + Graphics2D bufImageGraphics = bufferedImage.createGraphics(); + bufImageGraphics.drawImage(scaledImage, 0, 0, null); + ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); + javax.imageio.ImageIO.write(bufferedImage, "jpg", bos); + byte[] bs = bos.toByteArray(); + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "image/jpeg"); + hds.set("Cache-Control", "no-cache"); + hds.set("Cache-Control", "no-store"); + t.sendResponseHeaders(200, bs.length); + OutputStream os = t.getResponseBody(); + os.write(bs); + os.close(); + } else { + AjaxFIFOImageCache imageCache = viewer.getAjaxImageCache(); + byte[] img = imageCache.getImage(key); + + if(img != null) { + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "image/jpeg"); + t.sendResponseHeaders(200, img.length); + + OutputStream os = t.getResponseBody(); + try { + os.write(img, 0, img.length); + } finally { + os.close(); + } + } else { + if(s_logger.isInfoEnabled()) + s_logger.info("Image has already been swept out, key: " + key); + t.sendResponseHeaders(404, -1); + } + } + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java index d9563b94d97..26ee9b33155 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyAuthenticationResult.java @@ -14,68 +14,68 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -// duplicated class -public class ConsoleProxyAuthenticationResult { - private boolean success; - private boolean isReauthentication; - private String host; - private int port; - private String tunnelUrl; - private String tunnelSession; - - public ConsoleProxyAuthenticationResult() { - success = false; - isReauthentication = false; - port = 0; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - - public boolean isReauthentication() { - return isReauthentication; - } - - public void setReauthentication(boolean isReauthentication) { - this.isReauthentication = isReauthentication; - } - - public String getHost() { - return host; - } - - public void setHost(String host) { - this.host = host; - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getTunnelUrl() { - return tunnelUrl; - } - - public void setTunnelUrl(String tunnelUrl) { - this.tunnelUrl = tunnelUrl; - } - - public String getTunnelSession() { - return tunnelSession; - } - - public void setTunnelSession(String tunnelSession) { - this.tunnelSession = tunnelSession; - } -} +package com.cloud.consoleproxy; + +// duplicated class +public class ConsoleProxyAuthenticationResult { + private boolean success; + private boolean isReauthentication; + private String host; + private int port; + private String tunnelUrl; + private String tunnelSession; + + public ConsoleProxyAuthenticationResult() { + success = false; + isReauthentication = false; + port = 0; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public boolean isReauthentication() { + return isReauthentication; + } + + public void setReauthentication(boolean isReauthentication) { + this.isReauthentication = isReauthentication; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public String getTunnelUrl() { + return tunnelUrl; + } + + public void setTunnelUrl(String tunnelUrl) { + this.tunnelUrl = tunnelUrl; + } + + public String getTunnelSession() { + return tunnelSession; + } + + public void setTunnelSession(String tunnelSession) { + this.tunnelSession = tunnelSession; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java index 2706184a72e..c9ad8ab82fa 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyBaseServerFactoryImpl.java @@ -14,8 +14,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - +package com.cloud.consoleproxy; + import java.io.IOException; import java.net.InetSocketAddress; @@ -23,26 +23,26 @@ import javax.net.ssl.SSLServerSocket; import com.cloud.consoleproxy.util.Logger; import com.sun.net.httpserver.HttpServer; - -public class ConsoleProxyBaseServerFactoryImpl implements ConsoleProxyServerFactory { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyBaseServerFactoryImpl.class); - - @Override - public void init(byte[] ksBits, String ksPassword) { - } - - @Override - public HttpServer createHttpServerInstance(int port) throws IOException { - if(s_logger.isInfoEnabled()) - s_logger.info("create HTTP server instance at port: " + port); - return HttpServer.create(new InetSocketAddress(port), 5); - } - - @Override - public SSLServerSocket createSSLServerSocket(int port) throws IOException { - if(s_logger.isInfoEnabled()) - s_logger.info("SSL server socket is not supported in ConsoleProxyBaseServerFactoryImpl"); - - return null; - } -} + +public class ConsoleProxyBaseServerFactoryImpl implements ConsoleProxyServerFactory { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyBaseServerFactoryImpl.class); + + @Override + public void init(byte[] ksBits, String ksPassword) { + } + + @Override + public HttpServer createHttpServerInstance(int port) throws IOException { + if(s_logger.isInfoEnabled()) + s_logger.info("create HTTP server instance at port: " + port); + return HttpServer.create(new InetSocketAddress(port), 5); + } + + @Override + public SSLServerSocket createSSLServerSocket(int port) throws IOException { + if(s_logger.isInfoEnabled()) + s_logger.info("SSL server socket is not supported in ConsoleProxyBaseServerFactoryImpl"); + + return null; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyClientListener.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyClientListener.java index 89097d84af7..43a0bab8bed 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyClientListener.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyClientListener.java @@ -14,12 +14,12 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -public interface ConsoleProxyClientListener { - void onFramebufferSizeChange(int w, int h); - void onFramebufferUpdate(int x, int y, int w, int h); - - void onClientConnected(); - void onClientClose(); -} +package com.cloud.consoleproxy; + +public interface ConsoleProxyClientListener { + void onFramebufferSizeChange(int w, int h); + void onFramebufferUpdate(int x, int y, int w, int h); + + void onClientConnected(); + void onClientClose(); +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java index 5471dea148f..408eb0419d7 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyCmdHandler.java @@ -14,57 +14,57 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; - +package com.cloud.consoleproxy; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; + import com.cloud.consoleproxy.util.Logger; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -public class ConsoleProxyCmdHandler implements HttpHandler { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyCmdHandler.class); - - public void handle(HttpExchange t) throws IOException { - try { - Thread.currentThread().setName("Cmd Thread " + - Thread.currentThread().getId() + " " + t.getRemoteAddress()); - s_logger.info("CmdHandler " + t.getRequestURI()); - doHandle(t); - } catch (Exception e) { - s_logger.error(e.toString(), e); - String response = "Not found"; - t.sendResponseHeaders(404, response.length()); - OutputStream os = t.getResponseBody(); - os.write(response.getBytes()); - os.close(); - } catch(OutOfMemoryError e) { - s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); - System.exit(1); - } catch (Throwable e) { - s_logger.error(e.toString(), e); - } finally { - t.close(); - } - } - - public void doHandle(HttpExchange t) throws Exception { - String path = t.getRequestURI().getPath(); - int i = path.indexOf("/", 1); - String cmd = path.substring(i + 1); - s_logger.info("Get CMD request for " + cmd); - if (cmd.equals("getstatus")) { - ConsoleProxyClientStatsCollector statsCollector = ConsoleProxy.getStatsCollector(); - - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "text/plain"); - t.sendResponseHeaders(200, 0); - OutputStreamWriter os = new OutputStreamWriter(t.getResponseBody()); - statsCollector.getStatsReport(os); - os.close(); - } - } -} +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class ConsoleProxyCmdHandler implements HttpHandler { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyCmdHandler.class); + + public void handle(HttpExchange t) throws IOException { + try { + Thread.currentThread().setName("Cmd Thread " + + Thread.currentThread().getId() + " " + t.getRemoteAddress()); + s_logger.info("CmdHandler " + t.getRequestURI()); + doHandle(t); + } catch (Exception e) { + s_logger.error(e.toString(), e); + String response = "Not found"; + t.sendResponseHeaders(404, response.length()); + OutputStream os = t.getResponseBody(); + os.write(response.getBytes()); + os.close(); + } catch(OutOfMemoryError e) { + s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); + System.exit(1); + } catch (Throwable e) { + s_logger.error(e.toString(), e); + } finally { + t.close(); + } + } + + public void doHandle(HttpExchange t) throws Exception { + String path = t.getRequestURI().getPath(); + int i = path.indexOf("/", 1); + String cmd = path.substring(i + 1); + s_logger.info("Get CMD request for " + cmd); + if (cmd.equals("getstatus")) { + ConsoleProxyClientStatsCollector statsCollector = ConsoleProxy.getStatsCollector(); + + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "text/plain"); + t.sendResponseHeaders(200, 0); + OutputStreamWriter os = new OutputStreamWriter(t.getResponseBody()); + statsCollector.getStatsReport(os); + os.close(); + } + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java index cf2027b86ec..7756d01cd7f 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java @@ -14,61 +14,61 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -import java.util.HashMap; -import java.util.Map; - -import com.cloud.consoleproxy.util.Logger; - -public class ConsoleProxyHttpHandlerHelper { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyHttpHandlerHelper.class); - - public static Map getQueryMap(String query) { - String[] params = query.split("&"); - Map map = new HashMap(); - for (String param : params) { - String[] paramTokens = param.split("="); - if(paramTokens != null && paramTokens.length == 2) { - String name = param.split("=")[0]; - String value = param.split("=")[1]; - map.put(name, value); - } else if (paramTokens.length == 3) { - // very ugly, added for Xen tunneling url - String name = paramTokens[0]; - String value = paramTokens[1] + "=" + paramTokens[2]; - map.put(name, value); - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("Invalid paramemter in URL found. param: " + param); - } - } - - // This is a ugly solution for now. We will do encryption/decryption translation - // here to make it transparent to rest of the code. - if(map.get("token") != null) { - ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor( - ConsoleProxy.getEncryptorPassword()); - - ConsoleProxyClientParam param = encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token")); - if(param != null) { - if(param.getClientHostAddress() != null) - map.put("host", param.getClientHostAddress()); - if(param.getClientHostPort() != 0) - map.put("port", String.valueOf(param.getClientHostPort())); - if(param.getClientTag() != null) - map.put("tag", param.getClientTag()); - if(param.getClientHostPassword() != null) - map.put("sid", param.getClientHostPassword()); - if(param.getClientTunnelUrl() != null) - map.put("consoleurl", param.getClientTunnelUrl()); - if(param.getClientTunnelSession() != null) - map.put("sessionref", param.getClientTunnelSession()); - if(param.getTicket() != null) - map.put("ticket", param.getTicket()); - } - } - - return map; - } -} +package com.cloud.consoleproxy; + +import java.util.HashMap; +import java.util.Map; + +import com.cloud.consoleproxy.util.Logger; + +public class ConsoleProxyHttpHandlerHelper { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyHttpHandlerHelper.class); + + public static Map getQueryMap(String query) { + String[] params = query.split("&"); + Map map = new HashMap(); + for (String param : params) { + String[] paramTokens = param.split("="); + if(paramTokens != null && paramTokens.length == 2) { + String name = param.split("=")[0]; + String value = param.split("=")[1]; + map.put(name, value); + } else if (paramTokens.length == 3) { + // very ugly, added for Xen tunneling url + String name = paramTokens[0]; + String value = paramTokens[1] + "=" + paramTokens[2]; + map.put(name, value); + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("Invalid paramemter in URL found. param: " + param); + } + } + + // This is a ugly solution for now. We will do encryption/decryption translation + // here to make it transparent to rest of the code. + if(map.get("token") != null) { + ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor( + ConsoleProxy.getEncryptorPassword()); + + ConsoleProxyClientParam param = encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token")); + if(param != null) { + if(param.getClientHostAddress() != null) + map.put("host", param.getClientHostAddress()); + if(param.getClientHostPort() != 0) + map.put("port", String.valueOf(param.getClientHostPort())); + if(param.getClientTag() != null) + map.put("tag", param.getClientTag()); + if(param.getClientHostPassword() != null) + map.put("sid", param.getClientHostPassword()); + if(param.getClientTunnelUrl() != null) + map.put("consoleurl", param.getClientTunnelUrl()); + if(param.getClientTunnelSession() != null) + map.put("sessionref", param.getClientTunnelSession()); + if(param.getTicket() != null) + map.put("ticket", param.getTicket()); + } + } + + return map; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java index 701ad7a277d..ff66de3bcc4 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyLoggerFactory.java @@ -14,76 +14,76 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; +package com.cloud.consoleproxy; import com.cloud.consoleproxy.util.Logger; import com.cloud.consoleproxy.util.LoggerFactory; - -public class ConsoleProxyLoggerFactory implements LoggerFactory { - public ConsoleProxyLoggerFactory() { - } - - public Logger getLogger(Class clazz) { - return new Log4jLogger(org.apache.log4j.Logger.getLogger(clazz)); - } - - public static class Log4jLogger extends Logger { - private org.apache.log4j.Logger logger; - - public Log4jLogger(org.apache.log4j.Logger logger) { - this.logger = logger; - } - - public boolean isTraceEnabled() { - return logger.isTraceEnabled(); - } - - public boolean isDebugEnabled() { - return logger.isDebugEnabled(); - } - - public boolean isInfoEnabled() { - return logger.isInfoEnabled(); - } - - public void trace(Object message) { - logger.trace(message); - } - - public void trace(Object message, Throwable exception) { - logger.trace(message, exception); - } - - public void info(Object message) { - logger.info(message); - } - - public void info(Object message, Throwable exception) { - logger.info(message, exception); - } - - public void debug(Object message) { - logger.debug(message); - } - - public void debug(Object message, Throwable exception) { - logger.debug(message, exception); - } - - public void warn(Object message) { - logger.warn(message); - } - - public void warn(Object message, Throwable exception) { - logger.warn(message, exception); - } - - public void error(Object message) { - logger.error(message); - } - - public void error(Object message, Throwable exception) { - logger.error(message, exception); - } - } -} + +public class ConsoleProxyLoggerFactory implements LoggerFactory { + public ConsoleProxyLoggerFactory() { + } + + public Logger getLogger(Class clazz) { + return new Log4jLogger(org.apache.log4j.Logger.getLogger(clazz)); + } + + public static class Log4jLogger extends Logger { + private org.apache.log4j.Logger logger; + + public Log4jLogger(org.apache.log4j.Logger logger) { + this.logger = logger; + } + + public boolean isTraceEnabled() { + return logger.isTraceEnabled(); + } + + public boolean isDebugEnabled() { + return logger.isDebugEnabled(); + } + + public boolean isInfoEnabled() { + return logger.isInfoEnabled(); + } + + public void trace(Object message) { + logger.trace(message); + } + + public void trace(Object message, Throwable exception) { + logger.trace(message, exception); + } + + public void info(Object message) { + logger.info(message); + } + + public void info(Object message, Throwable exception) { + logger.info(message, exception); + } + + public void debug(Object message) { + logger.debug(message); + } + + public void debug(Object message, Throwable exception) { + logger.debug(message, exception); + } + + public void warn(Object message) { + logger.warn(message); + } + + public void warn(Object message, Throwable exception) { + logger.warn(message, exception); + } + + public void error(Object message) { + logger.error(message); + } + + public void error(Object message, Throwable exception) { + logger.error(message, exception); + } + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java index be5df6efa59..030b2f452eb 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java @@ -34,120 +34,120 @@ import com.cloud.consoleproxy.util.Logger; // itself and the shell script will re-launch console proxy // public class ConsoleProxyMonitor { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyMonitor.class); - - private String[] _argv; - private Map _argMap = new HashMap(); - - private volatile Process _process; - private boolean _quit = false; - - public ConsoleProxyMonitor(String[] argv) { - _argv = argv; - - for(String arg : _argv) { - String[] tokens = arg.split("="); - if(tokens.length == 2) { - s_logger.info("Add argument " + tokens[0] + "=" + tokens[1] + " to the argument map"); + private static final Logger s_logger = Logger.getLogger(ConsoleProxyMonitor.class); + + private String[] _argv; + private Map _argMap = new HashMap(); + + private volatile Process _process; + private boolean _quit = false; + + public ConsoleProxyMonitor(String[] argv) { + _argv = argv; + + for(String arg : _argv) { + String[] tokens = arg.split("="); + if(tokens.length == 2) { + s_logger.info("Add argument " + tokens[0] + "=" + tokens[1] + " to the argument map"); - _argMap.put(tokens[0].trim(), tokens[1].trim()); - } else { - s_logger.warn("unrecognized argument, skip adding it to argument map"); - } - } - } - - private void run() { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override - public void run() { - _quit = true; - onShutdown(); - } - }); - - while(!_quit) { - String cmdLine = getLaunchCommandLine(); - - s_logger.info("Launch console proxy process with command line: " + cmdLine); - - try { - _process = Runtime.getRuntime().exec(cmdLine); - } catch (IOException e) { - s_logger.error("Unexpected exception ", e); - System.exit(1); - } - - boolean waitSucceeded = false; - int exitCode = 0; - while(!waitSucceeded) { - try { - exitCode = _process.waitFor(); - waitSucceeded = true; - - if(s_logger.isInfoEnabled()) - s_logger.info("Console proxy process exits with code: " + exitCode); - } catch (InterruptedException e) { - if(s_logger.isInfoEnabled()) - s_logger.info("InterruptedException while waiting for termination of console proxy, will retry"); - } - } - } - } - - private String getLaunchCommandLine() { - StringBuffer sb = new StringBuffer("java "); - String jvmOptions = _argMap.get("jvmoptions"); - - if(jvmOptions != null) - sb.append(jvmOptions); - - for(Map.Entry entry : _argMap.entrySet()) { - if(!"jvmoptions".equalsIgnoreCase(entry.getKey())) - sb.append(" ").append(entry.getKey()).append("=").append(entry.getValue()); - } - - return sb.toString(); - } - - private void onShutdown() { - if(_process != null) { - if(s_logger.isInfoEnabled()) - s_logger.info("Console proxy monitor shuts dwon, terminate console proxy process"); - _process.destroy(); - } - } + _argMap.put(tokens[0].trim(), tokens[1].trim()); + } else { + s_logger.warn("unrecognized argument, skip adding it to argument map"); + } + } + } + + private void run() { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + _quit = true; + onShutdown(); + } + }); + + while(!_quit) { + String cmdLine = getLaunchCommandLine(); + + s_logger.info("Launch console proxy process with command line: " + cmdLine); + + try { + _process = Runtime.getRuntime().exec(cmdLine); + } catch (IOException e) { + s_logger.error("Unexpected exception ", e); + System.exit(1); + } + + boolean waitSucceeded = false; + int exitCode = 0; + while(!waitSucceeded) { + try { + exitCode = _process.waitFor(); + waitSucceeded = true; + + if(s_logger.isInfoEnabled()) + s_logger.info("Console proxy process exits with code: " + exitCode); + } catch (InterruptedException e) { + if(s_logger.isInfoEnabled()) + s_logger.info("InterruptedException while waiting for termination of console proxy, will retry"); + } + } + } + } + + private String getLaunchCommandLine() { + StringBuffer sb = new StringBuffer("java "); + String jvmOptions = _argMap.get("jvmoptions"); + + if(jvmOptions != null) + sb.append(jvmOptions); + + for(Map.Entry entry : _argMap.entrySet()) { + if(!"jvmoptions".equalsIgnoreCase(entry.getKey())) + sb.append(" ").append(entry.getKey()).append("=").append(entry.getValue()); + } + + return sb.toString(); + } + + private void onShutdown() { + if(_process != null) { + if(s_logger.isInfoEnabled()) + s_logger.info("Console proxy monitor shuts dwon, terminate console proxy process"); + _process.destroy(); + } + } - private static void configLog4j() { - URL configUrl = System.class.getResource("/conf/log4j-cloud.xml"); - if(configUrl == null) - configUrl = ClassLoader.getSystemResource("log4j-cloud.xml"); - - if(configUrl == null) - configUrl = ClassLoader.getSystemResource("conf/log4j-cloud.xml"); - - if(configUrl != null) { - try { - System.out.println("Configure log4j using " + configUrl.toURI().toString()); - } catch (URISyntaxException e1) { - e1.printStackTrace(); - } + private static void configLog4j() { + URL configUrl = System.class.getResource("/conf/log4j-cloud.xml"); + if(configUrl == null) + configUrl = ClassLoader.getSystemResource("log4j-cloud.xml"); + + if(configUrl == null) + configUrl = ClassLoader.getSystemResource("conf/log4j-cloud.xml"); + + if(configUrl != null) { + try { + System.out.println("Configure log4j using " + configUrl.toURI().toString()); + } catch (URISyntaxException e1) { + e1.printStackTrace(); + } - try { - File file = new File(configUrl.toURI()); - - System.out.println("Log4j configuration from : " + file.getAbsolutePath()); - DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); - } catch (URISyntaxException e) { - System.out.println("Unable to convert log4j configuration Url to URI"); - } - } else { - System.out.println("Configure log4j with default properties"); - } - } - - public static void main(String[] argv) { - configLog4j(); - (new ConsoleProxyMonitor(argv)).run(); - } + try { + File file = new File(configUrl.toURI()); + + System.out.println("Log4j configuration from : " + file.getAbsolutePath()); + DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000); + } catch (URISyntaxException e) { + System.out.println("Unable to convert log4j configuration Url to URI"); + } + } else { + System.out.println("Configure log4j with default properties"); + } + } + + public static void main(String[] argv) { + configLog4j(); + (new ConsoleProxyMonitor(argv)).run(); + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java index f9dc21e1575..7d160472e8a 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyResourceHandler.java @@ -14,168 +14,168 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - +package com.cloud.consoleproxy; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + import com.cloud.consoleproxy.util.Logger; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -public class ConsoleProxyResourceHandler implements HttpHandler { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyResourceHandler.class); - - static Map s_mimeTypes; - static { - s_mimeTypes = new HashMap(); - s_mimeTypes.put("jar", "application/java-archive"); - s_mimeTypes.put("js", "text/javascript"); - s_mimeTypes.put("css", "text/css"); - s_mimeTypes.put("jpg", "image/jpeg"); - s_mimeTypes.put("html", "text/html"); - s_mimeTypes.put("htm", "text/html"); - s_mimeTypes.put("log", "text/plain"); - } - - static Map s_validResourceFolders; - static { - s_validResourceFolders = new HashMap(); - s_validResourceFolders.put("applet", ""); - s_validResourceFolders.put("logs", ""); - s_validResourceFolders.put("images", ""); - s_validResourceFolders.put("js", ""); - s_validResourceFolders.put("css", ""); - s_validResourceFolders.put("html", ""); - } - - public ConsoleProxyResourceHandler() { - } - - public void handle(HttpExchange t) throws IOException { - try { - if(s_logger.isDebugEnabled()) - s_logger.debug("Resource Handler " + t.getRequestURI()); - - long startTick = System.currentTimeMillis(); - - doHandle(t); - - if(s_logger.isDebugEnabled()) - s_logger.debug(t.getRequestURI() + " Process time " + (System.currentTimeMillis() - startTick) + " ms"); - } catch (IOException e) { - throw e; - } catch(Throwable e) { - s_logger.error("Unexpected exception, ", e); - t.sendResponseHeaders(500, -1); // server error - } finally { - t.close(); - } - } - - @SuppressWarnings("deprecation") - private void doHandle(HttpExchange t) throws Exception { - String path = t.getRequestURI().getPath(); - - if(s_logger.isInfoEnabled()) - s_logger.info("Get resource request for " + path); - - int i = path.indexOf("/", 1); - String filepath = path.substring(i + 1); - i = path.lastIndexOf("."); - String extension = (i == -1) ? "" : path.substring(i + 1); - String contentType = getContentType(extension); - - if(!validatePath(filepath)) { - if(s_logger.isInfoEnabled()) - s_logger.info("Resource access is forbidden, uri: " + path); - - t.sendResponseHeaders(403, -1); // forbidden - return; - } - - File f = new File ("./" + filepath); - if(f.exists()) { - long lastModified = f.lastModified(); - String ifModifiedSince = t.getRequestHeaders().getFirst("If-Modified-Since"); - if (ifModifiedSince != null) { - long d = Date.parse(ifModifiedSince); - if (d + 1000 >= lastModified) { - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", contentType); - t.sendResponseHeaders(304, -1); - - if(s_logger.isInfoEnabled()) - s_logger.info("Sent 304 file has not been " + - "modified since " + ifModifiedSince); - return; - } - } - - long length = f.length(); - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", contentType); - hds.set("Last-Modified", new Date(lastModified).toGMTString()); - t.sendResponseHeaders(200, length); - responseFileContent(t, f); - - if(s_logger.isInfoEnabled()) - s_logger.info("Sent file " + path + " with content type " + contentType); - } else { - if(s_logger.isInfoEnabled()) - s_logger.info("file does not exist" + path); - t.sendResponseHeaders(404, -1); - } - } - - private static String getContentType(String extension) { - String key = extension.toLowerCase(); - if(s_mimeTypes.containsKey(key)) { - return s_mimeTypes.get(key); - } - return "application/octet-stream"; - } - - private static void responseFileContent(HttpExchange t, File f) throws Exception { - OutputStream os = t.getResponseBody(); - FileInputStream fis = new FileInputStream(f); - while (true) { - byte[] b = new byte[8192]; - int n = fis.read(b); - if (n < 0) { - break; - } - os.write(b, 0, n); - } - fis.close(); - os.close(); - } - - private static boolean validatePath(String path) { - int i = path.indexOf("/"); - if(i == -1) { - if(s_logger.isInfoEnabled()) - s_logger.info("Invalid resource path: can not start at resource root"); - return false; - } - - if(path.contains("..")) { - if(s_logger.isInfoEnabled()) - s_logger.info("Invalid resource path: contains relative up-level navigation"); - - return false; - } - - return isValidResourceFolder(path.substring(0, i)); - } - - private static boolean isValidResourceFolder(String name) { - return s_validResourceFolders.containsKey(name); - } -} +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; + +public class ConsoleProxyResourceHandler implements HttpHandler { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyResourceHandler.class); + + static Map s_mimeTypes; + static { + s_mimeTypes = new HashMap(); + s_mimeTypes.put("jar", "application/java-archive"); + s_mimeTypes.put("js", "text/javascript"); + s_mimeTypes.put("css", "text/css"); + s_mimeTypes.put("jpg", "image/jpeg"); + s_mimeTypes.put("html", "text/html"); + s_mimeTypes.put("htm", "text/html"); + s_mimeTypes.put("log", "text/plain"); + } + + static Map s_validResourceFolders; + static { + s_validResourceFolders = new HashMap(); + s_validResourceFolders.put("applet", ""); + s_validResourceFolders.put("logs", ""); + s_validResourceFolders.put("images", ""); + s_validResourceFolders.put("js", ""); + s_validResourceFolders.put("css", ""); + s_validResourceFolders.put("html", ""); + } + + public ConsoleProxyResourceHandler() { + } + + public void handle(HttpExchange t) throws IOException { + try { + if(s_logger.isDebugEnabled()) + s_logger.debug("Resource Handler " + t.getRequestURI()); + + long startTick = System.currentTimeMillis(); + + doHandle(t); + + if(s_logger.isDebugEnabled()) + s_logger.debug(t.getRequestURI() + " Process time " + (System.currentTimeMillis() - startTick) + " ms"); + } catch (IOException e) { + throw e; + } catch(Throwable e) { + s_logger.error("Unexpected exception, ", e); + t.sendResponseHeaders(500, -1); // server error + } finally { + t.close(); + } + } + + @SuppressWarnings("deprecation") + private void doHandle(HttpExchange t) throws Exception { + String path = t.getRequestURI().getPath(); + + if(s_logger.isInfoEnabled()) + s_logger.info("Get resource request for " + path); + + int i = path.indexOf("/", 1); + String filepath = path.substring(i + 1); + i = path.lastIndexOf("."); + String extension = (i == -1) ? "" : path.substring(i + 1); + String contentType = getContentType(extension); + + if(!validatePath(filepath)) { + if(s_logger.isInfoEnabled()) + s_logger.info("Resource access is forbidden, uri: " + path); + + t.sendResponseHeaders(403, -1); // forbidden + return; + } + + File f = new File ("./" + filepath); + if(f.exists()) { + long lastModified = f.lastModified(); + String ifModifiedSince = t.getRequestHeaders().getFirst("If-Modified-Since"); + if (ifModifiedSince != null) { + long d = Date.parse(ifModifiedSince); + if (d + 1000 >= lastModified) { + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", contentType); + t.sendResponseHeaders(304, -1); + + if(s_logger.isInfoEnabled()) + s_logger.info("Sent 304 file has not been " + + "modified since " + ifModifiedSince); + return; + } + } + + long length = f.length(); + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", contentType); + hds.set("Last-Modified", new Date(lastModified).toGMTString()); + t.sendResponseHeaders(200, length); + responseFileContent(t, f); + + if(s_logger.isInfoEnabled()) + s_logger.info("Sent file " + path + " with content type " + contentType); + } else { + if(s_logger.isInfoEnabled()) + s_logger.info("file does not exist" + path); + t.sendResponseHeaders(404, -1); + } + } + + private static String getContentType(String extension) { + String key = extension.toLowerCase(); + if(s_mimeTypes.containsKey(key)) { + return s_mimeTypes.get(key); + } + return "application/octet-stream"; + } + + private static void responseFileContent(HttpExchange t, File f) throws Exception { + OutputStream os = t.getResponseBody(); + FileInputStream fis = new FileInputStream(f); + while (true) { + byte[] b = new byte[8192]; + int n = fis.read(b); + if (n < 0) { + break; + } + os.write(b, 0, n); + } + fis.close(); + os.close(); + } + + private static boolean validatePath(String path) { + int i = path.indexOf("/"); + if(i == -1) { + if(s_logger.isInfoEnabled()) + s_logger.info("Invalid resource path: can not start at resource root"); + return false; + } + + if(path.contains("..")) { + if(s_logger.isInfoEnabled()) + s_logger.info("Invalid resource path: contains relative up-level navigation"); + + return false; + } + + return isValidResourceFolder(path.substring(0, i)); + } + + private static boolean isValidResourceFolder(String name) { + return s_validResourceFolders.containsKey(name); + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java index 42d069f9331..ee0ee13fa92 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxySecureServerFactoryImpl.java @@ -14,8 +14,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - +package com.cloud.consoleproxy; + import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; @@ -35,111 +35,111 @@ import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsParameters; import com.sun.net.httpserver.HttpsServer; - -public class ConsoleProxySecureServerFactoryImpl implements ConsoleProxyServerFactory { - private static final Logger s_logger = Logger.getLogger(ConsoleProxySecureServerFactoryImpl.class); - - private SSLContext sslContext = null; - - public ConsoleProxySecureServerFactoryImpl() { - } - - @Override - public void init(byte[] ksBits, String ksPassword) { - s_logger.info("Start initializing SSL"); - if(ksBits == null) { - try { - s_logger.info("Initializing SSL from built-in default certificate"); - - char[] passphrase = "vmops.com".toCharArray(); - KeyStore ks = KeyStore.getInstance("JKS"); - - ks.load(new FileInputStream("certs/realhostip.keystore"), passphrase); - // ks.load(ConsoleProxy.class.getResourceAsStream("/realhostip.keystore"), passphrase); - - s_logger.info("SSL certificate loaded"); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, passphrase); - s_logger.info("Key manager factory is initialized"); +public class ConsoleProxySecureServerFactoryImpl implements ConsoleProxyServerFactory { + private static final Logger s_logger = Logger.getLogger(ConsoleProxySecureServerFactoryImpl.class); + + private SSLContext sslContext = null; + + public ConsoleProxySecureServerFactoryImpl() { + } + + @Override + public void init(byte[] ksBits, String ksPassword) { + s_logger.info("Start initializing SSL"); - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ks); - s_logger.info("Trust manager factory is initialized"); + if(ksBits == null) { + try { + s_logger.info("Initializing SSL from built-in default certificate"); + + char[] passphrase = "vmops.com".toCharArray(); + KeyStore ks = KeyStore.getInstance("JKS"); + + ks.load(new FileInputStream("certs/realhostip.keystore"), passphrase); + // ks.load(ConsoleProxy.class.getResourceAsStream("/realhostip.keystore"), passphrase); + + s_logger.info("SSL certificate loaded"); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + s_logger.info("Key manager factory is initialized"); - sslContext = SSLContext.getInstance("TLS"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - s_logger.info("SSL context is initialized"); - } catch (Exception ioe) { - s_logger.error(ioe.toString(), ioe); - } - - } else { - char[] passphrase = ksPassword != null ? ksPassword.toCharArray() : null; - try { - s_logger.info("Initializing SSL from passed-in certificate"); - - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(new ByteArrayInputStream(ksBits), passphrase); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, passphrase); - s_logger.info("Key manager factory is initialized"); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(ks); - s_logger.info("Trust manager factory is initialized"); - - sslContext = SSLContext.getInstance("TLS"); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - s_logger.info("SSL context is initialized"); - } catch(Exception e) { - s_logger.error("Unable to init factory due to exception ", e); - } - } - - } - - public HttpServer createHttpServerInstance(int port) throws IOException { - try { - HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 5); - server.setHttpsConfigurator (new HttpsConfigurator(sslContext) { - @Override - public void configure (HttpsParameters params) { - - // get the remote address if needed - InetSocketAddress remote = params.getClientAddress(); - SSLContext c = getSSLContext(); - - // get the default parameters - SSLParameters sslparams = c.getDefaultSSLParameters(); - - params.setSSLParameters(sslparams); - // statement above could throw IAE if any params invalid. - // eg. if app has a UI and parameters supplied by a user. - } - }); - - s_logger.info("create HTTPS server instance on port: " + port); - return server; - } catch (Exception ioe) { - s_logger.error(ioe.toString(), ioe); - } - return null; - } - - public SSLServerSocket createSSLServerSocket(int port) throws IOException { - try { - SSLServerSocket srvSock = null; - SSLServerSocketFactory ssf = sslContext.getServerSocketFactory(); - srvSock = (SSLServerSocket) ssf.createServerSocket(port); - - s_logger.info("create SSL server socket on port: " + port); - return srvSock; - } catch (Exception ioe) { - s_logger.error(ioe.toString(), ioe); - } - return null; - } -} + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ks); + s_logger.info("Trust manager factory is initialized"); + + sslContext = SSLContext.getInstance("TLS"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + s_logger.info("SSL context is initialized"); + } catch (Exception ioe) { + s_logger.error(ioe.toString(), ioe); + } + + } else { + char[] passphrase = ksPassword != null ? ksPassword.toCharArray() : null; + try { + s_logger.info("Initializing SSL from passed-in certificate"); + + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(new ByteArrayInputStream(ksBits), passphrase); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, passphrase); + s_logger.info("Key manager factory is initialized"); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ks); + s_logger.info("Trust manager factory is initialized"); + + sslContext = SSLContext.getInstance("TLS"); + sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + s_logger.info("SSL context is initialized"); + } catch(Exception e) { + s_logger.error("Unable to init factory due to exception ", e); + } + } + + } + + public HttpServer createHttpServerInstance(int port) throws IOException { + try { + HttpsServer server = HttpsServer.create(new InetSocketAddress(port), 5); + server.setHttpsConfigurator (new HttpsConfigurator(sslContext) { + @Override + public void configure (HttpsParameters params) { + + // get the remote address if needed + InetSocketAddress remote = params.getClientAddress(); + SSLContext c = getSSLContext(); + + // get the default parameters + SSLParameters sslparams = c.getDefaultSSLParameters(); + + params.setSSLParameters(sslparams); + // statement above could throw IAE if any params invalid. + // eg. if app has a UI and parameters supplied by a user. + } + }); + + s_logger.info("create HTTPS server instance on port: " + port); + return server; + } catch (Exception ioe) { + s_logger.error(ioe.toString(), ioe); + } + return null; + } + + public SSLServerSocket createSSLServerSocket(int port) throws IOException { + try { + SSLServerSocket srvSock = null; + SSLServerSocketFactory ssf = sslContext.getServerSocketFactory(); + srvSock = (SSLServerSocket) ssf.createServerSocket(port); + + s_logger.info("create SSL server socket on port: " + port); + return srvSock; + } catch (Exception ioe) { + s_logger.error(ioe.toString(), ioe); + } + return null; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyServerFactory.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyServerFactory.java index 9d65c00d096..7e0e5c77bf4 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyServerFactory.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyServerFactory.java @@ -14,16 +14,16 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - +package com.cloud.consoleproxy; + import java.io.IOException; import javax.net.ssl.SSLServerSocket; import com.sun.net.httpserver.HttpServer; - + public interface ConsoleProxyServerFactory { - void init(byte[] ksBits, String ksPassword); - HttpServer createHttpServerInstance(int port) throws IOException; - SSLServerSocket createSSLServerSocket(int port) throws IOException; -} + void init(byte[] ksBits, String ksPassword); + HttpServer createHttpServerInstance(int port) throws IOException; + SSLServerSocket createSSLServerSocket(int port) throws IOException; +} diff --git a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java index 82d45b77e74..6d34d3b9162 100644 --- a/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java +++ b/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyThumbnailHandler.java @@ -14,199 +14,199 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -import java.awt.Color; -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - +package com.cloud.consoleproxy; + +import java.awt.Color; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + import com.cloud.consoleproxy.util.Logger; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -public class ConsoleProxyThumbnailHandler implements HttpHandler { - private static final Logger s_logger = Logger.getLogger(ConsoleProxyThumbnailHandler.class); - - public ConsoleProxyThumbnailHandler() { - } - - public void handle(HttpExchange t) throws IOException { - try { - Thread.currentThread().setName("JPG Thread " + - Thread.currentThread().getId() + " " + t.getRemoteAddress()); - - if(s_logger.isDebugEnabled()) - s_logger.debug("ScreenHandler " + t.getRequestURI()); - - long startTick = System.currentTimeMillis(); - doHandle(t); - - if(s_logger.isDebugEnabled()) - s_logger.debug(t.getRequestURI() + "Process time " + (System.currentTimeMillis() - startTick) + " ms"); - } catch (IllegalArgumentException e) { - String response = "Bad query string"; - s_logger.error(response + ", request URI : " + t.getRequestURI()); - t.sendResponseHeaders(200, response.length()); - OutputStream os = t.getResponseBody(); - os.write(response.getBytes()); - os.close(); - } catch(OutOfMemoryError e) { - s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); - System.exit(1); - } catch (Throwable e) { - s_logger.error("Unexpected exception while handing thumbnail request, ", e); - - String queries = t.getRequestURI().getQuery(); - Map queryMap = getQueryMap(queries); - int width = 0; - int height = 0; - String ws = queryMap.get("w"); - String hs = queryMap.get("h"); - try { - width = Integer.parseInt(ws); - height = Integer.parseInt(hs); - } catch (NumberFormatException ex) { - } - width = Math.min(width, 800); - height = Math.min(height, 600); - - BufferedImage img = generateTextImage(width, height, "Cannot Connect"); - ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); - javax.imageio.ImageIO.write(img, "jpg", bos); - byte[] bs = bos.toByteArray(); - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "image/jpeg"); - hds.set("Cache-Control", "no-cache"); - hds.set("Cache-Control", "no-store"); - t.sendResponseHeaders(200, bs.length); - OutputStream os = t.getResponseBody(); - os.write(bs); - os.close(); - s_logger.error("Cannot get console, sent error JPG response for " + t.getRequestURI()); - return; - } finally { - t.close(); - } - } - - private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException { - String queries = t.getRequestURI().getQuery(); - Map queryMap = getQueryMap(queries); - int width = 0; - int height = 0; - int port = 0; - String ws = queryMap.get("w"); - String hs = queryMap.get("h"); - String host = queryMap.get("host"); - String portStr = queryMap.get("port"); - String sid = queryMap.get("sid"); - String tag = queryMap.get("tag"); - String ticket = queryMap.get("ticket"); - String console_url = queryMap.get("consoleurl"); - String console_host_session = queryMap.get("sessionref"); +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; - if(tag == null) - tag = ""; - - if (ws == null || hs == null || host == null || portStr == null || sid == null ) { - throw new IllegalArgumentException(); - } - try { - width = Integer.parseInt(ws); - height = Integer.parseInt(hs); - port = Integer.parseInt(portStr); - } catch (NumberFormatException e) { - throw new IllegalArgumentException(e); - } +public class ConsoleProxyThumbnailHandler implements HttpHandler { + private static final Logger s_logger = Logger.getLogger(ConsoleProxyThumbnailHandler.class); + + public ConsoleProxyThumbnailHandler() { + } - ConsoleProxyClientParam param = new ConsoleProxyClientParam(); - param.setClientHostAddress(host); - param.setClientHostPort(port); - param.setClientHostPassword(sid); - param.setClientTag(tag); - param.setTicket(ticket); - param.setClientTunnelUrl(console_url); - param.setClientTunnelSession(console_host_session); - - ConsoleProxyClient viewer = ConsoleProxy.getVncViewer(param); - - if (!viewer.isHostConnected()) { - // use generated image instead of static - BufferedImage img = generateTextImage(width, height, "Connecting"); - ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); - javax.imageio.ImageIO.write(img, "jpg", bos); - byte[] bs = bos.toByteArray(); - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "image/jpeg"); - hds.set("Cache-Control", "no-cache"); - hds.set("Cache-Control", "no-store"); - t.sendResponseHeaders(200, bs.length); - OutputStream os = t.getResponseBody(); - os.write(bs); - os.close(); - - if(s_logger.isInfoEnabled()) - s_logger.info("Console not ready, sent dummy JPG response"); - return; - } - - { - Image scaledImage = viewer.getClientScaledImage(width, height); - BufferedImage bufferedImage = new BufferedImage(width, height, - BufferedImage.TYPE_3BYTE_BGR); - Graphics2D bufImageGraphics = bufferedImage.createGraphics(); - bufImageGraphics.drawImage(scaledImage, 0, 0, null); - ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); - javax.imageio.ImageIO.write(bufferedImage, "jpg", bos); - byte[] bs = bos.toByteArray(); - Headers hds = t.getResponseHeaders(); - hds.set("Content-Type", "image/jpeg"); - hds.set("Cache-Control", "no-cache"); - hds.set("Cache-Control", "no-store"); - t.sendResponseHeaders(200, bs.length); - OutputStream os = t.getResponseBody(); - os.write(bs); - os.close(); - } - } - - public static BufferedImage generateTextImage(int w, int h, String text) { - BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); - Graphics2D g = img.createGraphics(); - g.setColor(Color.BLACK); - g.fillRect(0, 0, w, h); - g.setColor(Color.WHITE); - try { - g.setFont(new Font(null, Font.PLAIN, 12)); - FontMetrics fm = g.getFontMetrics(); - int textWidth = fm.stringWidth(text); - int startx = (w-textWidth) / 2; - if(startx < 0) - startx = 0; - g.drawString(text, startx, h/2); - } catch (Throwable e) { - s_logger.warn("Problem in generating text to thumnail image, return blank image"); - } - return img; - } - - public static Map getQueryMap(String query) { - String[] params = query.split("&"); - Map map = new HashMap(); - for (String param : params) { - String name = param.split("=")[0]; - String value = param.split("=")[1]; - map.put(name, value); - } - return map; - } -} + public void handle(HttpExchange t) throws IOException { + try { + Thread.currentThread().setName("JPG Thread " + + Thread.currentThread().getId() + " " + t.getRemoteAddress()); + + if(s_logger.isDebugEnabled()) + s_logger.debug("ScreenHandler " + t.getRequestURI()); + + long startTick = System.currentTimeMillis(); + doHandle(t); + + if(s_logger.isDebugEnabled()) + s_logger.debug(t.getRequestURI() + "Process time " + (System.currentTimeMillis() - startTick) + " ms"); + } catch (IllegalArgumentException e) { + String response = "Bad query string"; + s_logger.error(response + ", request URI : " + t.getRequestURI()); + t.sendResponseHeaders(200, response.length()); + OutputStream os = t.getResponseBody(); + os.write(response.getBytes()); + os.close(); + } catch(OutOfMemoryError e) { + s_logger.error("Unrecoverable OutOfMemory Error, exit and let it be re-launched"); + System.exit(1); + } catch (Throwable e) { + s_logger.error("Unexpected exception while handing thumbnail request, ", e); + + String queries = t.getRequestURI().getQuery(); + Map queryMap = getQueryMap(queries); + int width = 0; + int height = 0; + String ws = queryMap.get("w"); + String hs = queryMap.get("h"); + try { + width = Integer.parseInt(ws); + height = Integer.parseInt(hs); + } catch (NumberFormatException ex) { + } + width = Math.min(width, 800); + height = Math.min(height, 600); + + BufferedImage img = generateTextImage(width, height, "Cannot Connect"); + ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); + javax.imageio.ImageIO.write(img, "jpg", bos); + byte[] bs = bos.toByteArray(); + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "image/jpeg"); + hds.set("Cache-Control", "no-cache"); + hds.set("Cache-Control", "no-store"); + t.sendResponseHeaders(200, bs.length); + OutputStream os = t.getResponseBody(); + os.write(bs); + os.close(); + s_logger.error("Cannot get console, sent error JPG response for " + t.getRequestURI()); + return; + } finally { + t.close(); + } + } + + private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException { + String queries = t.getRequestURI().getQuery(); + Map queryMap = getQueryMap(queries); + int width = 0; + int height = 0; + int port = 0; + String ws = queryMap.get("w"); + String hs = queryMap.get("h"); + String host = queryMap.get("host"); + String portStr = queryMap.get("port"); + String sid = queryMap.get("sid"); + String tag = queryMap.get("tag"); + String ticket = queryMap.get("ticket"); + String console_url = queryMap.get("consoleurl"); + String console_host_session = queryMap.get("sessionref"); + + if(tag == null) + tag = ""; + + if (ws == null || hs == null || host == null || portStr == null || sid == null ) { + throw new IllegalArgumentException(); + } + try { + width = Integer.parseInt(ws); + height = Integer.parseInt(hs); + port = Integer.parseInt(portStr); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(e); + } + + ConsoleProxyClientParam param = new ConsoleProxyClientParam(); + param.setClientHostAddress(host); + param.setClientHostPort(port); + param.setClientHostPassword(sid); + param.setClientTag(tag); + param.setTicket(ticket); + param.setClientTunnelUrl(console_url); + param.setClientTunnelSession(console_host_session); + + ConsoleProxyClient viewer = ConsoleProxy.getVncViewer(param); + + if (!viewer.isHostConnected()) { + // use generated image instead of static + BufferedImage img = generateTextImage(width, height, "Connecting"); + ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); + javax.imageio.ImageIO.write(img, "jpg", bos); + byte[] bs = bos.toByteArray(); + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "image/jpeg"); + hds.set("Cache-Control", "no-cache"); + hds.set("Cache-Control", "no-store"); + t.sendResponseHeaders(200, bs.length); + OutputStream os = t.getResponseBody(); + os.write(bs); + os.close(); + + if(s_logger.isInfoEnabled()) + s_logger.info("Console not ready, sent dummy JPG response"); + return; + } + + { + Image scaledImage = viewer.getClientScaledImage(width, height); + BufferedImage bufferedImage = new BufferedImage(width, height, + BufferedImage.TYPE_3BYTE_BGR); + Graphics2D bufImageGraphics = bufferedImage.createGraphics(); + bufImageGraphics.drawImage(scaledImage, 0, 0, null); + ByteArrayOutputStream bos = new ByteArrayOutputStream(8196); + javax.imageio.ImageIO.write(bufferedImage, "jpg", bos); + byte[] bs = bos.toByteArray(); + Headers hds = t.getResponseHeaders(); + hds.set("Content-Type", "image/jpeg"); + hds.set("Cache-Control", "no-cache"); + hds.set("Cache-Control", "no-store"); + t.sendResponseHeaders(200, bs.length); + OutputStream os = t.getResponseBody(); + os.write(bs); + os.close(); + } + } + + public static BufferedImage generateTextImage(int w, int h, String text) { + BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = img.createGraphics(); + g.setColor(Color.BLACK); + g.fillRect(0, 0, w, h); + g.setColor(Color.WHITE); + try { + g.setFont(new Font(null, Font.PLAIN, 12)); + FontMetrics fm = g.getFontMetrics(); + int textWidth = fm.stringWidth(text); + int startx = (w-textWidth) / 2; + if(startx < 0) + startx = 0; + g.drawString(text, startx, h/2); + } catch (Throwable e) { + s_logger.warn("Problem in generating text to thumnail image, return blank image"); + } + return img; + } + + public static Map getQueryMap(String query) { + String[] params = query.split("&"); + Map map = new HashMap(); + for (String param : params) { + String name = param.split("=")[0]; + String value = param.split("=")[1]; + map.put(name, value); + } + return map; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/InputEventType.java b/console-proxy/src/com/cloud/consoleproxy/InputEventType.java index b0bf8ebc381..4a5aff16bcf 100644 --- a/console-proxy/src/com/cloud/consoleproxy/InputEventType.java +++ b/console-proxy/src/com/cloud/consoleproxy/InputEventType.java @@ -14,45 +14,45 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy; - -public enum InputEventType { - MOUSE_MOVE(1), - MOUSE_DOWN(2), - MOUSE_UP(3), - KEY_PRESS(4), - KEY_DOWN(5), - KEY_UP(6), - MOUSE_DBLCLICK(8); - - int eventCode; - private InputEventType(int eventCode) { - this.eventCode = eventCode; - } - - public int getEventCode() { - return eventCode; - } - - public static InputEventType fromEventCode(int eventCode) { - switch(eventCode) { - case 1 : - return MOUSE_MOVE; - case 2 : - return MOUSE_DOWN; - case 3 : - return MOUSE_UP; - case 4 : - return KEY_PRESS; - case 5 : - return KEY_DOWN; - case 6 : - return KEY_UP; - case 8 : - return MOUSE_DBLCLICK; - default : - break; - } - throw new IllegalArgumentException("Unsupport event code: " + eventCode); - } -} +package com.cloud.consoleproxy; + +public enum InputEventType { + MOUSE_MOVE(1), + MOUSE_DOWN(2), + MOUSE_UP(3), + KEY_PRESS(4), + KEY_DOWN(5), + KEY_UP(6), + MOUSE_DBLCLICK(8); + + int eventCode; + private InputEventType(int eventCode) { + this.eventCode = eventCode; + } + + public int getEventCode() { + return eventCode; + } + + public static InputEventType fromEventCode(int eventCode) { + switch(eventCode) { + case 1 : + return MOUSE_MOVE; + case 2 : + return MOUSE_DOWN; + case 3 : + return MOUSE_UP; + case 4 : + return KEY_PRESS; + case 5 : + return KEY_DOWN; + case 6 : + return KEY_UP; + case 8 : + return MOUSE_DBLCLICK; + default : + break; + } + throw new IllegalArgumentException("Unsupport event code: " + eventCode); + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/ITileScanListener.java b/console-proxy/src/com/cloud/consoleproxy/util/ITileScanListener.java index 547b13cd60a..2ff82d7242f 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/ITileScanListener.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/ITileScanListener.java @@ -14,12 +14,12 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.awt.Rectangle; -import java.util.List; - -public interface ITileScanListener { - boolean onTileChange(Rectangle rowMergedRect, int row, int col); - void onRegionChange(List regionList); -} +package com.cloud.consoleproxy.util; + +import java.awt.Rectangle; +import java.util.List; + +public interface ITileScanListener { + boolean onTileChange(Rectangle rowMergedRect, int row, int col); + void onRegionChange(List regionList); +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/ImageHelper.java b/console-proxy/src/com/cloud/consoleproxy/util/ImageHelper.java index 42fb59e48a7..bb7373e78b2 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/ImageHelper.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/ImageHelper.java @@ -14,19 +14,19 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.awt.image.BufferedImage; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -public class ImageHelper { - public static byte[] jpegFromImage(BufferedImage image) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(128000); - javax.imageio.ImageIO.write(image, "jpg", bos); - - byte[] jpegBits = bos.toByteArray(); - bos.close(); - return jpegBits; - } -} +package com.cloud.consoleproxy.util; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +public class ImageHelper { + public static byte[] jpegFromImage(BufferedImage image) throws IOException { + ByteArrayOutputStream bos = new ByteArrayOutputStream(128000); + javax.imageio.ImageIO.write(image, "jpg", bos); + + byte[] jpegBits = bos.toByteArray(); + bos.close(); + return jpegBits; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/Logger.java b/console-proxy/src/com/cloud/consoleproxy/util/Logger.java index 2392a98751b..f4357bd4bc4 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/Logger.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/Logger.java @@ -14,210 +14,210 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -// logger facility for dynamic switch between console logger used in Applet and log4j based logger -public class Logger { - private static LoggerFactory factory = null; - - public static final int LEVEL_TRACE = 1; - public static final int LEVEL_DEBUG = 2; - public static final int LEVEL_INFO = 3; - public static final int LEVEL_WARN = 4; - public static final int LEVEL_ERROR = 5; - - private Class clazz; - private Logger logger; - - private static int level = LEVEL_INFO; - - public static Logger getLogger(Class clazz) { - return new Logger(clazz); - } - - public static void setFactory(LoggerFactory f) { - factory = f; - } - - public static void setLevel(int l) { - level = l; - } - - public Logger(Class clazz) { - this.clazz = clazz; - } - - protected Logger() { - } - - public boolean isTraceEnabled() { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - return logger.isTraceEnabled(); - } - return level <= LEVEL_TRACE; - } - - public boolean isDebugEnabled() { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - return logger.isDebugEnabled(); - } - return level <= LEVEL_DEBUG; - } - - public boolean isInfoEnabled() { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - return logger.isInfoEnabled(); - } - return level <= LEVEL_INFO; - } - - public void trace(Object message) { - - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.trace(message); - } else { - if(level <= LEVEL_TRACE) - System.out.println(message); - } - } - - public void trace(Object message, Throwable exception) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.trace(message, exception); - } else { - if(level <= LEVEL_TRACE) { - System.out.println(message); - if (exception != null) { - exception.printStackTrace(System.out); - } - } - } - } - - public void info(Object message) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.info(message); - } else { - if(level <= LEVEL_INFO) - System.out.println(message); - } - } - - public void info(Object message, Throwable exception) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.info(message, exception); - } else { - if(level <= LEVEL_INFO) { - System.out.println(message); - if (exception != null) { - exception.printStackTrace(System.out); - } - } - } - } - - public void debug(Object message) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.debug(message); - } else { - if(level <= LEVEL_DEBUG) - System.out.println(message); - } - } - - public void debug(Object message, Throwable exception) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.debug(message, exception); - } else { - if(level <= LEVEL_DEBUG) { - System.out.println(message); - if (exception != null) { - exception.printStackTrace(System.out); - } - } - } - } - - public void warn(Object message) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.warn(message); - } else { - if(level <= LEVEL_WARN) - System.out.println(message); - } - } - - public void warn(Object message, Throwable exception) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.warn(message, exception); - } else { - if(level <= LEVEL_WARN) { - System.out.println(message); - if (exception != null) { - exception.printStackTrace(System.out); - } - } - } - } - - public void error(Object message) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.error(message); - } else { - if(level <= LEVEL_ERROR) - System.out.println(message); - } - } - - public void error(Object message, Throwable exception) { - if(factory != null) { - if(logger == null) - logger = factory.getLogger(clazz); - - logger.error(message, exception); - } else { - if(level <= LEVEL_ERROR) { - System.out.println(message); - if (exception != null) { - exception.printStackTrace(System.out); - } - } - } - } -} +package com.cloud.consoleproxy.util; + +// logger facility for dynamic switch between console logger used in Applet and log4j based logger +public class Logger { + private static LoggerFactory factory = null; + + public static final int LEVEL_TRACE = 1; + public static final int LEVEL_DEBUG = 2; + public static final int LEVEL_INFO = 3; + public static final int LEVEL_WARN = 4; + public static final int LEVEL_ERROR = 5; + + private Class clazz; + private Logger logger; + + private static int level = LEVEL_INFO; + + public static Logger getLogger(Class clazz) { + return new Logger(clazz); + } + + public static void setFactory(LoggerFactory f) { + factory = f; + } + + public static void setLevel(int l) { + level = l; + } + + public Logger(Class clazz) { + this.clazz = clazz; + } + + protected Logger() { + } + + public boolean isTraceEnabled() { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + return logger.isTraceEnabled(); + } + return level <= LEVEL_TRACE; + } + + public boolean isDebugEnabled() { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + return logger.isDebugEnabled(); + } + return level <= LEVEL_DEBUG; + } + + public boolean isInfoEnabled() { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + return logger.isInfoEnabled(); + } + return level <= LEVEL_INFO; + } + + public void trace(Object message) { + + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.trace(message); + } else { + if(level <= LEVEL_TRACE) + System.out.println(message); + } + } + + public void trace(Object message, Throwable exception) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.trace(message, exception); + } else { + if(level <= LEVEL_TRACE) { + System.out.println(message); + if (exception != null) { + exception.printStackTrace(System.out); + } + } + } + } + + public void info(Object message) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.info(message); + } else { + if(level <= LEVEL_INFO) + System.out.println(message); + } + } + + public void info(Object message, Throwable exception) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.info(message, exception); + } else { + if(level <= LEVEL_INFO) { + System.out.println(message); + if (exception != null) { + exception.printStackTrace(System.out); + } + } + } + } + + public void debug(Object message) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.debug(message); + } else { + if(level <= LEVEL_DEBUG) + System.out.println(message); + } + } + + public void debug(Object message, Throwable exception) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.debug(message, exception); + } else { + if(level <= LEVEL_DEBUG) { + System.out.println(message); + if (exception != null) { + exception.printStackTrace(System.out); + } + } + } + } + + public void warn(Object message) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.warn(message); + } else { + if(level <= LEVEL_WARN) + System.out.println(message); + } + } + + public void warn(Object message, Throwable exception) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.warn(message, exception); + } else { + if(level <= LEVEL_WARN) { + System.out.println(message); + if (exception != null) { + exception.printStackTrace(System.out); + } + } + } + } + + public void error(Object message) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.error(message); + } else { + if(level <= LEVEL_ERROR) + System.out.println(message); + } + } + + public void error(Object message, Throwable exception) { + if(factory != null) { + if(logger == null) + logger = factory.getLogger(clazz); + + logger.error(message, exception); + } else { + if(level <= LEVEL_ERROR) { + System.out.println(message); + if (exception != null) { + exception.printStackTrace(System.out); + } + } + } + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/LoggerFactory.java b/console-proxy/src/com/cloud/consoleproxy/util/LoggerFactory.java index fa0d3cfcb31..121411adf16 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/LoggerFactory.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/LoggerFactory.java @@ -14,8 +14,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -public interface LoggerFactory { - Logger getLogger(Class clazz); -} +package com.cloud.consoleproxy.util; + +public interface LoggerFactory { + Logger getLogger(Class clazz); +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/RawHTTP.java b/console-proxy/src/com/cloud/consoleproxy/util/RawHTTP.java index eeba34532de..c77b5511270 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/RawHTTP.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/RawHTTP.java @@ -14,236 +14,236 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.SocketFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.X509TrustManager; - -// -// This file is originally from XenConsole with modifications -// - -/** - * Send an HTTP CONNECT or PUT request to a XenAPI host with a Session ID, - * return the connected socket and the Task ID. Used for tunnelling VNC - * connections and import/export operations. - */ -public final class RawHTTP { - private static final Logger s_logger = Logger.getLogger(RawHTTP.class); - - private static final Pattern END_PATTERN = Pattern.compile("^\r\n$"); - private static final Pattern HEADER_PATTERN = Pattern - .compile("^([A-Z_a-z0-9-]+):\\s*(.*)\r\n$"); - private static final Pattern HTTP_PATTERN = Pattern - .compile("^HTTP/\\d+\\.\\d+ (\\d*) (.*)\r\n$"); - - /** - * @uml.property name="command" - */ - private final String command; - /** - * @uml.property name="host" - */ - private final String host; - /** - * @uml.property name="port" - */ - private final int port; - /** - * @uml.property name="path" - */ - private final String path; - /** - * @uml.property name="session" - */ - private final String session; - /** - * @uml.property name="useSSL" - */ - private final boolean useSSL; - - /** - * @uml.property name="responseHeaders" - * @uml.associationEnd qualifier="group:java.lang.String java.lang.String" - */ - private final Map responseHeaders = new HashMap(); - - /** - * @uml.property name="ic" - */ - private InputStream ic; - /** - * @uml.property name="oc" - */ - private OutputStream oc; - /** - * @uml.property name="s" - */ - private Socket s; - - public InputStream getInputStream() { - return ic; - } - - public OutputStream getOutputStream() { - return oc; - } - - public Socket getSocket() { - return s; - } - - public RawHTTP(String command, String host, int port, String path, - String session, boolean useSSL) { - this.command = command; - this.host = host; - this.port = port; - this.path = path; - this.session = session; - this.useSSL = useSSL; - } - - private static final TrustManager[] trustAllCerts = new TrustManager[] { - new X509TrustManager() { - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - public void checkClientTrusted(X509Certificate[] certs, String authType) { - } - - public void checkServerTrusted(X509Certificate[] certs, String authType) { - } - } - }; - - private Socket _getSocket() throws IOException { - if (useSSL) { - SSLContext context = getClientSSLContext(); - if(context == null) - throw new IOException("Unable to setup SSL context"); - - SSLSocket ssl = null; - try { - context.init(null, trustAllCerts, new SecureRandom()); - SocketFactory factory = context.getSocketFactory(); - ssl = (SSLSocket) factory.createSocket(host, port); - /* ssl.setSSLParameters(context.getDefaultSSLParameters()); */ - } catch (IOException e) { - s_logger.error("IOException: " + e.getMessage(), e); - throw e; - } catch (KeyManagementException e) { - s_logger.error("KeyManagementException: " + e.getMessage(), e); - } - return ssl; - } else { - return new Socket(host, port); - } - } - - public Socket connect() throws IOException { - String[] headers = makeHeaders(); - s = _getSocket(); - try { - oc = s.getOutputStream(); - for (String header : headers) { - oc.write(header.getBytes()); - oc.write("\r\n".getBytes()); - } - oc.flush(); - ic = s.getInputStream(); - while (true) { - String line = readline(ic); - - Matcher m = END_PATTERN.matcher(line); - if (m.matches()) { - return s; - } - - m = HEADER_PATTERN.matcher(line); - if (m.matches()) { - responseHeaders.put(m.group(1), m.group(2)); - continue; - } - - m = HTTP_PATTERN.matcher(line); - if (m.matches()) { - String status_code = m.group(1); - String reason_phrase = m.group(2); - if (!"200".equals(status_code)) { - throw new IOException("HTTP status " + status_code - + " " + reason_phrase); - } - } else { - throw new IOException("Unknown HTTP line " + line); - } - } - } catch (IOException exn) { - s.close(); - throw exn; - } catch (RuntimeException exn) { - s.close(); - throw exn; - } - } - - public Map getResponseHeaders() { - return responseHeaders; - } - - private String[] makeHeaders() { - String[] headers = { String.format("%s %s HTTP/1.0", command, path), - String.format("Host: %s", host), - String.format("Cookie: session_id=%s", session), "" }; - return headers; - } - - private static String readline(InputStream ic) throws IOException { - String result = ""; - while (true) { - try { - int c = ic.read(); - - if (c == -1) { - return result; - } - result = result + (char) c; - if (c == 0x0a /* LF */) { - return result; - } - } catch (IOException e) { - ic.close(); - throw e; - } - } - } - - private SSLContext getClientSSLContext() { - SSLContext sslContext = null; - try { - sslContext = SSLContext.getInstance("SSL", "SunJSSE"); - } catch (NoSuchAlgorithmException e) { - s_logger.error("Unexpected exception ", e); - } catch (NoSuchProviderException e) { - s_logger.error("Unexpected exception ", e); - } - return sslContext; - } -} +package com.cloud.consoleproxy.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +// +// This file is originally from XenConsole with modifications +// + +/** + * Send an HTTP CONNECT or PUT request to a XenAPI host with a Session ID, + * return the connected socket and the Task ID. Used for tunnelling VNC + * connections and import/export operations. + */ +public final class RawHTTP { + private static final Logger s_logger = Logger.getLogger(RawHTTP.class); + + private static final Pattern END_PATTERN = Pattern.compile("^\r\n$"); + private static final Pattern HEADER_PATTERN = Pattern + .compile("^([A-Z_a-z0-9-]+):\\s*(.*)\r\n$"); + private static final Pattern HTTP_PATTERN = Pattern + .compile("^HTTP/\\d+\\.\\d+ (\\d*) (.*)\r\n$"); + + /** + * @uml.property name="command" + */ + private final String command; + /** + * @uml.property name="host" + */ + private final String host; + /** + * @uml.property name="port" + */ + private final int port; + /** + * @uml.property name="path" + */ + private final String path; + /** + * @uml.property name="session" + */ + private final String session; + /** + * @uml.property name="useSSL" + */ + private final boolean useSSL; + + /** + * @uml.property name="responseHeaders" + * @uml.associationEnd qualifier="group:java.lang.String java.lang.String" + */ + private final Map responseHeaders = new HashMap(); + + /** + * @uml.property name="ic" + */ + private InputStream ic; + /** + * @uml.property name="oc" + */ + private OutputStream oc; + /** + * @uml.property name="s" + */ + private Socket s; + + public InputStream getInputStream() { + return ic; + } + + public OutputStream getOutputStream() { + return oc; + } + + public Socket getSocket() { + return s; + } + + public RawHTTP(String command, String host, int port, String path, + String session, boolean useSSL) { + this.command = command; + this.host = host; + this.port = port; + this.path = path; + this.session = session; + this.useSSL = useSSL; + } + + private static final TrustManager[] trustAllCerts = new TrustManager[] { + new X509TrustManager() { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + } + }; + + private Socket _getSocket() throws IOException { + if (useSSL) { + SSLContext context = getClientSSLContext(); + if(context == null) + throw new IOException("Unable to setup SSL context"); + + SSLSocket ssl = null; + try { + context.init(null, trustAllCerts, new SecureRandom()); + SocketFactory factory = context.getSocketFactory(); + ssl = (SSLSocket) factory.createSocket(host, port); + /* ssl.setSSLParameters(context.getDefaultSSLParameters()); */ + } catch (IOException e) { + s_logger.error("IOException: " + e.getMessage(), e); + throw e; + } catch (KeyManagementException e) { + s_logger.error("KeyManagementException: " + e.getMessage(), e); + } + return ssl; + } else { + return new Socket(host, port); + } + } + + public Socket connect() throws IOException { + String[] headers = makeHeaders(); + s = _getSocket(); + try { + oc = s.getOutputStream(); + for (String header : headers) { + oc.write(header.getBytes()); + oc.write("\r\n".getBytes()); + } + oc.flush(); + ic = s.getInputStream(); + while (true) { + String line = readline(ic); + + Matcher m = END_PATTERN.matcher(line); + if (m.matches()) { + return s; + } + + m = HEADER_PATTERN.matcher(line); + if (m.matches()) { + responseHeaders.put(m.group(1), m.group(2)); + continue; + } + + m = HTTP_PATTERN.matcher(line); + if (m.matches()) { + String status_code = m.group(1); + String reason_phrase = m.group(2); + if (!"200".equals(status_code)) { + throw new IOException("HTTP status " + status_code + + " " + reason_phrase); + } + } else { + throw new IOException("Unknown HTTP line " + line); + } + } + } catch (IOException exn) { + s.close(); + throw exn; + } catch (RuntimeException exn) { + s.close(); + throw exn; + } + } + + public Map getResponseHeaders() { + return responseHeaders; + } + + private String[] makeHeaders() { + String[] headers = { String.format("%s %s HTTP/1.0", command, path), + String.format("Host: %s", host), + String.format("Cookie: session_id=%s", session), "" }; + return headers; + } + + private static String readline(InputStream ic) throws IOException { + String result = ""; + while (true) { + try { + int c = ic.read(); + + if (c == -1) { + return result; + } + result = result + (char) c; + if (c == 0x0a /* LF */) { + return result; + } + } catch (IOException e) { + ic.close(); + throw e; + } + } + } + + private SSLContext getClientSSLContext() { + SSLContext sslContext = null; + try { + sslContext = SSLContext.getInstance("SSL", "SunJSSE"); + } catch (NoSuchAlgorithmException e) { + s_logger.error("Unexpected exception ", e); + } catch (NoSuchProviderException e) { + s_logger.error("Unexpected exception ", e); + } + return sslContext; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/Region.java b/console-proxy/src/com/cloud/consoleproxy/util/Region.java index a5860f361b5..a5d1751d63b 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/Region.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/Region.java @@ -14,77 +14,77 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.List; - -public class Region { - private Rectangle bound; - private List rectList; - - public Region() { - bound = new Rectangle(0, 0, 0, 0); - rectList = new ArrayList(); - } - - public Region(Rectangle rect) { - bound = new Rectangle(rect.x, rect.y, rect.width, rect.height); - rectList = new ArrayList(); - rectList.add(rect); - } - - public Rectangle getBound() { - return bound; - } - - public void clearBound() { - assert(rectList.size() == 0); - bound.x = bound.y = bound.width = bound.height = 0; - } - - public List getRectangles() { - return rectList; - } - - public boolean add(Rectangle rect) { - if(bound.isEmpty()) { - assert(rectList.size() == 0); - bound.x = rect.x; - bound.y = rect.y; - bound.width = rect.width; - bound.height = rect.height; - - rectList.add(rect); - return true; - } - - Rectangle rcInflated = new Rectangle(rect.x - 1, rect.y- 1, rect.width + 2, rect.height + 2); - if(!bound.intersects(rcInflated)) - return false; - - for(Rectangle r : rectList) { - if(r.intersects(rcInflated)) { - if(!r.contains(rect)) { - enlargeBound(rect); - rectList.add(rect); - return true; - } - } - } - return false; - } - - private void enlargeBound(Rectangle rect) { - int boundLeft = Math.min(bound.x, rect.x); - int boundTop = Math.min(bound.y, rect.y); - int boundRight = Math.max(bound.x + bound.width, rect.x + rect.width); - int boundBottom = Math.max(bound.y + bound.height, rect.y + rect.height); - - bound.x = boundLeft; - bound.y = boundTop; - bound.width = boundRight - boundLeft; - bound.height = boundBottom - boundTop; - } -} +package com.cloud.consoleproxy.util; + +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +public class Region { + private Rectangle bound; + private List rectList; + + public Region() { + bound = new Rectangle(0, 0, 0, 0); + rectList = new ArrayList(); + } + + public Region(Rectangle rect) { + bound = new Rectangle(rect.x, rect.y, rect.width, rect.height); + rectList = new ArrayList(); + rectList.add(rect); + } + + public Rectangle getBound() { + return bound; + } + + public void clearBound() { + assert(rectList.size() == 0); + bound.x = bound.y = bound.width = bound.height = 0; + } + + public List getRectangles() { + return rectList; + } + + public boolean add(Rectangle rect) { + if(bound.isEmpty()) { + assert(rectList.size() == 0); + bound.x = rect.x; + bound.y = rect.y; + bound.width = rect.width; + bound.height = rect.height; + + rectList.add(rect); + return true; + } + + Rectangle rcInflated = new Rectangle(rect.x - 1, rect.y- 1, rect.width + 2, rect.height + 2); + if(!bound.intersects(rcInflated)) + return false; + + for(Rectangle r : rectList) { + if(r.intersects(rcInflated)) { + if(!r.contains(rect)) { + enlargeBound(rect); + rectList.add(rect); + return true; + } + } + } + return false; + } + + private void enlargeBound(Rectangle rect) { + int boundLeft = Math.min(bound.x, rect.x); + int boundTop = Math.min(bound.y, rect.y); + int boundRight = Math.max(bound.x + bound.width, rect.x + rect.width); + int boundBottom = Math.max(bound.y + bound.height, rect.y + rect.height); + + bound.x = boundLeft; + bound.y = boundTop; + bound.width = boundRight - boundLeft; + bound.height = boundBottom - boundTop; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/RegionClassifier.java b/console-proxy/src/com/cloud/consoleproxy/util/RegionClassifier.java index c4d9b82eb4e..9faa04ea9eb 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/RegionClassifier.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/RegionClassifier.java @@ -14,45 +14,45 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.List; - -public class RegionClassifier { - private List regionList; - - public RegionClassifier() { - regionList = new ArrayList(); - } - - public void add(Rectangle rect) { - boolean newRegion = true; - Rectangle rcInflated = new Rectangle(rect.x - 1, rect.y - 1, rect.width + 2, rect.height + 2); - for(Region region : regionList) { - if(region.getBound().intersects(rcInflated)) { - newRegion = false; - break; - } - } - - if(newRegion) { - regionList.add(new Region(rect)); - } else { - for(Region region : regionList) { - if(region.add(rect)) - return; - } - regionList.add(new Region(rect)); - } - } - - public List getRegionList() { - return regionList; - } - - public void clear() { - regionList.clear(); - } -} +package com.cloud.consoleproxy.util; + +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +public class RegionClassifier { + private List regionList; + + public RegionClassifier() { + regionList = new ArrayList(); + } + + public void add(Rectangle rect) { + boolean newRegion = true; + Rectangle rcInflated = new Rectangle(rect.x - 1, rect.y - 1, rect.width + 2, rect.height + 2); + for(Region region : regionList) { + if(region.getBound().intersects(rcInflated)) { + newRegion = false; + break; + } + } + + if(newRegion) { + regionList.add(new Region(rect)); + } else { + for(Region region : regionList) { + if(region.add(rect)) + return; + } + regionList.add(new Region(rect)); + } + } + + public List getRegionList() { + return regionList; + } + + public void clear() { + regionList.clear(); + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/TileInfo.java b/console-proxy/src/com/cloud/consoleproxy/util/TileInfo.java index 728f07a700d..933a55a55b0 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/TileInfo.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/TileInfo.java @@ -14,42 +14,42 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.awt.Rectangle; - -public class TileInfo { - private int row; - private int col; - private Rectangle tileRect; - - public TileInfo(int row, int col, Rectangle tileRect) { - this.row = row; - this.col = col; - this.tileRect = tileRect; - } - - public int getRow() { - return row; - } - - public void setRow(int row) { - this.row = row; - } - - public int getCol() { - return col; - } - - public void setCol(int col) { - this.col = col; - } - - public Rectangle getTileRect() { - return tileRect; - } - - public void setTileRect(Rectangle tileRect) { - this.tileRect = tileRect; - } -} +package com.cloud.consoleproxy.util; + +import java.awt.Rectangle; + +public class TileInfo { + private int row; + private int col; + private Rectangle tileRect; + + public TileInfo(int row, int col, Rectangle tileRect) { + this.row = row; + this.col = col; + this.tileRect = tileRect; + } + + public int getRow() { + return row; + } + + public void setRow(int row) { + this.row = row; + } + + public int getCol() { + return col; + } + + public void setCol(int col) { + this.col = col; + } + + public Rectangle getTileRect() { + return tileRect; + } + + public void setTileRect(Rectangle tileRect) { + this.tileRect = tileRect; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/util/TileTracker.java b/console-proxy/src/com/cloud/consoleproxy/util/TileTracker.java index 350eebf26a2..b3facb2f88f 100644 --- a/console-proxy/src/com/cloud/consoleproxy/util/TileTracker.java +++ b/console-proxy/src/com/cloud/consoleproxy/util/TileTracker.java @@ -14,256 +14,256 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.util; - -import java.awt.Rectangle; -import java.util.ArrayList; -import java.util.List; - -public class TileTracker { - - // 2 dimension tile status snapshot, a true value means the corresponding tile has been invalidated - private boolean[][] snapshot; - - private int tileWidth = 0; - private int tileHeight = 0; - private int trackWidth = 0; - private int trackHeight = 0; - - public TileTracker() { - } - - public int getTileWidth() { - return tileWidth; - } - - public void setTileWidth(int tileWidth) { - this.tileWidth = tileWidth; - } - - public int getTileHeight() { - return tileHeight; - } - - public void setTileHeight(int tileHeight) { - this.tileHeight = tileHeight; - } - - public int getTrackWidth() { - return trackWidth; - } - - public void setTrackWidth(int trackWidth) { - this.trackWidth = trackWidth; - } - - public int getTrackHeight() { - return trackHeight; - } - - public void setTrackHeight(int trackHeight) { - this.trackHeight = trackHeight; - } - - public void initTracking(int tileWidth, int tileHeight, int trackWidth, int trackHeight) { - assert(tileWidth > 0); - assert(tileHeight > 0); - assert(trackWidth > 0); - assert(trackHeight > 0); - assert(tileWidth <= trackWidth); - assert(tileHeight <= trackHeight); - - this.tileWidth = tileWidth; - this.tileHeight = tileHeight; - this.trackWidth = trackWidth; - this.trackHeight = trackHeight; - - int cols = getTileCols(); - int rows = getTileRows(); - snapshot = new boolean[rows][cols]; - for(int i = 0; i < rows; i++) - for(int j = 0; j < cols; j++) - snapshot[i][j] = false; - } - - public synchronized void resize(int trackWidth, int trackHeight) { - assert(tileWidth > 0); - assert(tileHeight > 0); - assert(trackWidth > 0); - assert(trackHeight > 0); - - this.trackWidth = trackWidth; - this.trackHeight = trackHeight; - - int cols = getTileCols(); - int rows = getTileRows(); - snapshot = new boolean[rows][cols]; - for(int i = 0; i < rows; i++) - for(int j = 0; j < cols; j++) - snapshot[i][j] = true; - } - - public void invalidate(Rectangle rect) { - setTileFlag(rect, true); - } - - public void validate(Rectangle rect) { - setTileFlag(rect, false); - } - - public List scan(boolean init) { - List l = new ArrayList(); - - synchronized(this) { - for(int i = 0; i < getTileRows(); i++) { - for(int j = 0; j < getTileCols(); j++) { - if(init || snapshot[i][j]) { - Rectangle rect = new Rectangle(); - rect.y = i*tileHeight; - rect.x = j*tileWidth; - rect.width = Math.min(trackWidth - rect.x, tileWidth); - rect.height = Math.min(trackHeight - rect.y, tileHeight); - - l.add(new TileInfo(i, j, rect)); - snapshot[i][j] = false; - } - } - } - - return l; - } - } - - public boolean hasFullCoverage() { - synchronized(this) { - for(int i = 0; i < getTileRows(); i++) { - for(int j = 0; j < getTileCols(); j++) { - if(!snapshot[i][j]) - return false; - } - } - } - return true; - } - - - - public void initCoverageTest() { - synchronized(this) { - for(int i = 0; i < getTileRows(); i++) { - for(int j = 0; j < getTileCols(); j++) { - snapshot[i][j] = false; - } - } - } - } - - // listener will be called while holding the object lock, use it - // with care to avoid deadlock condition being formed - public synchronized void scan(int nStartRow, int nStartCol, ITileScanListener listener) { - assert(listener != null); - - int cols = getTileCols(); - int rows = getTileRows(); - - nStartRow = nStartRow % rows; - nStartCol = nStartCol % cols; - - int nPos = nStartRow*cols + nStartCol; - int nUnits = rows*cols; - int nStartPos = nPos; - int nRow; - int nCol; - do { - nRow = nPos / cols; - nCol = nPos % cols; - - if(snapshot[nRow][nCol]) { - int nEndCol = nCol; - for(; nEndCol < cols && snapshot[nRow][nEndCol]; nEndCol++) { - snapshot[nRow][nEndCol] = false; - } - - Rectangle rect = new Rectangle(); - rect.y = nRow*tileHeight; - rect.height = tileHeight; - rect.x = nCol*tileWidth; - rect.width = (nEndCol - nCol)*tileWidth; - - if(!listener.onTileChange(rect, nRow, nEndCol)) - break; - } - - nPos = (nPos + 1) % nUnits; - } while(nPos != nStartPos); - } - - public void capture(ITileScanListener listener) { - assert(listener != null); - - int cols = getTileCols(); - int rows = getTileRows(); - - RegionClassifier classifier = new RegionClassifier(); - int left, top, right, bottom; - - synchronized(this) { - for(int i = 0; i < rows; i++) { - top = i*tileHeight; - bottom = Math.min(top + tileHeight, trackHeight); - for(int j = 0; j < cols; j++) { - left = j*tileWidth; - right = Math.min(left + tileWidth, trackWidth); - - if(snapshot[i][j]) { - snapshot[i][j] = false; - classifier.add(new Rectangle(left, top, right - left, bottom - top)); - } - } - } - } - listener.onRegionChange(classifier.getRegionList()); - } - - private synchronized void setTileFlag(Rectangle rect, boolean flag) { - int nStartTileRow; - int nStartTileCol; - int nEndTileRow; - int nEndTileCol; - - int cols = getTileCols(); - int rows = getTileRows(); - - if(rect != null) { - nStartTileRow = Math.min(getTileYPos(rect.y), rows - 1); - nStartTileCol = Math.min(getTileXPos(rect.x), cols - 1); - nEndTileRow = Math.min(getTileYPos(rect.y + rect.height - 1), rows -1); - nEndTileCol = Math.min(getTileXPos(rect.x + rect.width - 1), cols -1); - } else { - nStartTileRow = 0; - nStartTileCol = 0; - nEndTileRow = rows - 1; - nEndTileCol = cols - 1; - } - - for(int i = nStartTileRow; i <= nEndTileRow; i++) - for(int j = nStartTileCol; j <= nEndTileCol; j++) - snapshot[i][j] = flag; - } - - private int getTileRows() { - return (trackHeight + tileHeight - 1) / tileHeight; - } - - private int getTileCols() { - return (trackWidth + tileWidth - 1) / tileWidth; - } - - private int getTileXPos(int x) { - return x / tileWidth; - } - - public int getTileYPos(int y) { - return y / tileHeight; - } -} +package com.cloud.consoleproxy.util; + +import java.awt.Rectangle; +import java.util.ArrayList; +import java.util.List; + +public class TileTracker { + + // 2 dimension tile status snapshot, a true value means the corresponding tile has been invalidated + private boolean[][] snapshot; + + private int tileWidth = 0; + private int tileHeight = 0; + private int trackWidth = 0; + private int trackHeight = 0; + + public TileTracker() { + } + + public int getTileWidth() { + return tileWidth; + } + + public void setTileWidth(int tileWidth) { + this.tileWidth = tileWidth; + } + + public int getTileHeight() { + return tileHeight; + } + + public void setTileHeight(int tileHeight) { + this.tileHeight = tileHeight; + } + + public int getTrackWidth() { + return trackWidth; + } + + public void setTrackWidth(int trackWidth) { + this.trackWidth = trackWidth; + } + + public int getTrackHeight() { + return trackHeight; + } + + public void setTrackHeight(int trackHeight) { + this.trackHeight = trackHeight; + } + + public void initTracking(int tileWidth, int tileHeight, int trackWidth, int trackHeight) { + assert(tileWidth > 0); + assert(tileHeight > 0); + assert(trackWidth > 0); + assert(trackHeight > 0); + assert(tileWidth <= trackWidth); + assert(tileHeight <= trackHeight); + + this.tileWidth = tileWidth; + this.tileHeight = tileHeight; + this.trackWidth = trackWidth; + this.trackHeight = trackHeight; + + int cols = getTileCols(); + int rows = getTileRows(); + snapshot = new boolean[rows][cols]; + for(int i = 0; i < rows; i++) + for(int j = 0; j < cols; j++) + snapshot[i][j] = false; + } + + public synchronized void resize(int trackWidth, int trackHeight) { + assert(tileWidth > 0); + assert(tileHeight > 0); + assert(trackWidth > 0); + assert(trackHeight > 0); + + this.trackWidth = trackWidth; + this.trackHeight = trackHeight; + + int cols = getTileCols(); + int rows = getTileRows(); + snapshot = new boolean[rows][cols]; + for(int i = 0; i < rows; i++) + for(int j = 0; j < cols; j++) + snapshot[i][j] = true; + } + + public void invalidate(Rectangle rect) { + setTileFlag(rect, true); + } + + public void validate(Rectangle rect) { + setTileFlag(rect, false); + } + + public List scan(boolean init) { + List l = new ArrayList(); + + synchronized(this) { + for(int i = 0; i < getTileRows(); i++) { + for(int j = 0; j < getTileCols(); j++) { + if(init || snapshot[i][j]) { + Rectangle rect = new Rectangle(); + rect.y = i*tileHeight; + rect.x = j*tileWidth; + rect.width = Math.min(trackWidth - rect.x, tileWidth); + rect.height = Math.min(trackHeight - rect.y, tileHeight); + + l.add(new TileInfo(i, j, rect)); + snapshot[i][j] = false; + } + } + } + + return l; + } + } + + public boolean hasFullCoverage() { + synchronized(this) { + for(int i = 0; i < getTileRows(); i++) { + for(int j = 0; j < getTileCols(); j++) { + if(!snapshot[i][j]) + return false; + } + } + } + return true; + } + + + + public void initCoverageTest() { + synchronized(this) { + for(int i = 0; i < getTileRows(); i++) { + for(int j = 0; j < getTileCols(); j++) { + snapshot[i][j] = false; + } + } + } + } + + // listener will be called while holding the object lock, use it + // with care to avoid deadlock condition being formed + public synchronized void scan(int nStartRow, int nStartCol, ITileScanListener listener) { + assert(listener != null); + + int cols = getTileCols(); + int rows = getTileRows(); + + nStartRow = nStartRow % rows; + nStartCol = nStartCol % cols; + + int nPos = nStartRow*cols + nStartCol; + int nUnits = rows*cols; + int nStartPos = nPos; + int nRow; + int nCol; + do { + nRow = nPos / cols; + nCol = nPos % cols; + + if(snapshot[nRow][nCol]) { + int nEndCol = nCol; + for(; nEndCol < cols && snapshot[nRow][nEndCol]; nEndCol++) { + snapshot[nRow][nEndCol] = false; + } + + Rectangle rect = new Rectangle(); + rect.y = nRow*tileHeight; + rect.height = tileHeight; + rect.x = nCol*tileWidth; + rect.width = (nEndCol - nCol)*tileWidth; + + if(!listener.onTileChange(rect, nRow, nEndCol)) + break; + } + + nPos = (nPos + 1) % nUnits; + } while(nPos != nStartPos); + } + + public void capture(ITileScanListener listener) { + assert(listener != null); + + int cols = getTileCols(); + int rows = getTileRows(); + + RegionClassifier classifier = new RegionClassifier(); + int left, top, right, bottom; + + synchronized(this) { + for(int i = 0; i < rows; i++) { + top = i*tileHeight; + bottom = Math.min(top + tileHeight, trackHeight); + for(int j = 0; j < cols; j++) { + left = j*tileWidth; + right = Math.min(left + tileWidth, trackWidth); + + if(snapshot[i][j]) { + snapshot[i][j] = false; + classifier.add(new Rectangle(left, top, right - left, bottom - top)); + } + } + } + } + listener.onRegionChange(classifier.getRegionList()); + } + + private synchronized void setTileFlag(Rectangle rect, boolean flag) { + int nStartTileRow; + int nStartTileCol; + int nEndTileRow; + int nEndTileCol; + + int cols = getTileCols(); + int rows = getTileRows(); + + if(rect != null) { + nStartTileRow = Math.min(getTileYPos(rect.y), rows - 1); + nStartTileCol = Math.min(getTileXPos(rect.x), cols - 1); + nEndTileRow = Math.min(getTileYPos(rect.y + rect.height - 1), rows -1); + nEndTileCol = Math.min(getTileXPos(rect.x + rect.width - 1), cols -1); + } else { + nStartTileRow = 0; + nStartTileCol = 0; + nEndTileRow = rows - 1; + nEndTileCol = cols - 1; + } + + for(int i = nStartTileRow; i <= nEndTileRow; i++) + for(int j = nStartTileCol; j <= nEndTileCol; j++) + snapshot[i][j] = flag; + } + + private int getTileRows() { + return (trackHeight + tileHeight - 1) / tileHeight; + } + + private int getTileCols() { + return (trackWidth + tileWidth - 1) / tileWidth; + } + + private int getTileXPos(int x) { + return x / tileWidth; + } + + public int getTileYPos(int y) { + return y / tileHeight; + } +} diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java b/console-proxy/src/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java index a92131fc98d..f2fb4bb6b69 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/BufferedImageCanvas.java @@ -30,125 +30,121 @@ import com.cloud.consoleproxy.util.ImageHelper; import com.cloud.consoleproxy.util.TileInfo; /** - * A BuffereImageCanvas component represents frame buffer image on the - * screen. It also notifies its subscribers when screen is repainted. + * A BuffereImageCanvas component represents frame buffer image on + * the screen. It also notifies its subscribers when screen is repainted. */ public class BufferedImageCanvas extends Canvas implements FrameBufferCanvas { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - // Offline screen buffer - private BufferedImage offlineImage; - - // Cached Graphics2D object for offline screen buffer - private Graphics2D graphics; + // Offline screen buffer + private BufferedImage offlineImage; - private PaintNotificationListener listener; + // Cached Graphics2D object for offline screen buffer + private Graphics2D graphics; - public BufferedImageCanvas(PaintNotificationListener listener, int width, int height) { - super(); - this.listener = listener; + private PaintNotificationListener listener; - setBackground(Color.black); - - setFocusable(true); + public BufferedImageCanvas(PaintNotificationListener listener, int width, int height) { + super(); + this.listener = listener; - // Don't intercept TAB key - setFocusTraversalKeysEnabled(false); + setBackground(Color.black); - setCanvasSize(width, height); - } + setFocusable(true); - public void setCanvasSize(int width, int height) { - this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); - graphics = offlineImage.createGraphics(); + // Don't intercept TAB key + setFocusTraversalKeysEnabled(false); - setSize(offlineImage.getWidth(), offlineImage.getHeight()); - } - - @Override - public void update(Graphics g) { - // Call paint() directly, without clearing screen first - paint(g); - } - - @Override - public void paint(Graphics g) { - // Only part of image, requested with repaint(Rectangle), will be - // painted on screen. - synchronized(offlineImage) { - g.drawImage(offlineImage, 0, 0, this); + setCanvasSize(width, height); } - // Notify server that update is painted on screen - listener.imagePaintedOnScreen(); - } - public BufferedImage getOfflineImage() { - return offlineImage; - } + public void setCanvasSize(int width, int height) { + this.offlineImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + graphics = offlineImage.createGraphics(); - public Graphics2D getOfflineGraphics() { - return graphics; - } - - public void copyTile(Graphics2D g, int x, int y, Rectangle rc) { - synchronized(offlineImage) { - g.drawImage(offlineImage, x, y, x + rc.width, y + rc.height, - rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); - } - } - - @Override - public Image getFrameBufferScaledImage(int width, int height) { - if(offlineImage != null) - return offlineImage.getScaledInstance(width, height, Image.SCALE_DEFAULT); - return null; - } - - @Override - public byte[] getFrameBufferJpeg() { - int width = 800; - int height = 600; - - width = offlineImage.getWidth(); - height = offlineImage.getHeight(); - - BufferedImage bufferedImage = new BufferedImage(width, height, - BufferedImage.TYPE_3BYTE_BGR); - Graphics2D g = bufferedImage.createGraphics(); - synchronized(offlineImage) { - g.drawImage(offlineImage, 0, 0, width, height, 0, 0, width, height, null); - } - - byte[] imgBits = null; - try { - imgBits = ImageHelper.jpegFromImage(bufferedImage); - } catch (IOException e) { - } - return imgBits; - } - - @Override - public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight) { - int width = Math.max(tileWidth, tileWidth*tileList.size()); - BufferedImage bufferedImage = new BufferedImage(width, tileHeight, - BufferedImage.TYPE_3BYTE_BGR); - Graphics2D g = bufferedImage.createGraphics(); - - synchronized(offlineImage) { - int i = 0; - for(TileInfo tile : tileList) { - Rectangle rc = tile.getTileRect(); - g.drawImage(offlineImage, i*tileWidth, 0, i*tileWidth + rc.width, rc.height, - rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); - i++; - } - } - - byte[] imgBits = null; - try { - imgBits = ImageHelper.jpegFromImage(bufferedImage); - } catch (IOException e) { - } - return imgBits; - } + setSize(offlineImage.getWidth(), offlineImage.getHeight()); + } + + @Override + public void update(Graphics g) { + // Call paint() directly, without clearing screen first + paint(g); + } + + @Override + public void paint(Graphics g) { + // Only part of image, requested with repaint(Rectangle), will be + // painted on screen. + synchronized (offlineImage) { + g.drawImage(offlineImage, 0, 0, this); + } + // Notify server that update is painted on screen + listener.imagePaintedOnScreen(); + } + + public BufferedImage getOfflineImage() { + return offlineImage; + } + + public Graphics2D getOfflineGraphics() { + return graphics; + } + + public void copyTile(Graphics2D g, int x, int y, Rectangle rc) { + synchronized (offlineImage) { + g.drawImage(offlineImage, x, y, x + rc.width, y + rc.height, rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); + } + } + + @Override + public Image getFrameBufferScaledImage(int width, int height) { + if (offlineImage != null) + return offlineImage.getScaledInstance(width, height, Image.SCALE_DEFAULT); + return null; + } + + @Override + public byte[] getFrameBufferJpeg() { + int width = 800; + int height = 600; + + width = offlineImage.getWidth(); + height = offlineImage.getHeight(); + + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + synchronized (offlineImage) { + g.drawImage(offlineImage, 0, 0, width, height, 0, 0, width, height, null); + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + return imgBits; + } + + @Override + public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight) { + int width = Math.max(tileWidth, tileWidth * tileList.size()); + BufferedImage bufferedImage = new BufferedImage(width, tileHeight, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + + synchronized (offlineImage) { + int i = 0; + for (TileInfo tile : tileList) { + Rectangle rc = tile.getTileRect(); + g.drawImage(offlineImage, i * tileWidth, 0, i * tileWidth + rc.width, rc.height, rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); + i++; + } + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + return imgBits; + } } \ No newline at end of file diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java b/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java index 3b72f442a06..dcf11461360 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferCanvas.java @@ -14,15 +14,17 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.consoleproxy.vnc; - -import java.awt.Image; -import java.util.List; - -import com.cloud.consoleproxy.util.TileInfo; - -public interface FrameBufferCanvas { - Image getFrameBufferScaledImage(int width, int height); - public byte[] getFrameBufferJpeg(); - public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight); -} +package com.cloud.consoleproxy.vnc; + +import java.awt.Image; +import java.util.List; + +import com.cloud.consoleproxy.util.TileInfo; + +public interface FrameBufferCanvas { + Image getFrameBufferScaledImage(int width, int height); + + public byte[] getFrameBufferJpeg(); + + public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight); +} diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java b/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java index 8dbbe993b14..b8527c5261a 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/FrameBufferUpdateListener.java @@ -18,9 +18,9 @@ package com.cloud.consoleproxy.vnc; public interface FrameBufferUpdateListener { - /** - * Notify listener, that frame buffer update packet is received, so client is - * permitted (but not obligated) to ask server to send another update. - */ - void frameBufferPacketReceived(); + /** + * Notify listener, that frame buffer update packet is received, so client + * is permitted (but not obligated) to ask server to send another update. + */ + void frameBufferPacketReceived(); } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/PaintNotificationListener.java b/console-proxy/src/com/cloud/consoleproxy/vnc/PaintNotificationListener.java index e3bd4af17eb..aaefacb99f2 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/PaintNotificationListener.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/PaintNotificationListener.java @@ -18,10 +18,10 @@ package com.cloud.consoleproxy.vnc; public interface PaintNotificationListener { - /** - * Notify subscriber that screen is updated, so client can send another frame - * buffer update request to server. - */ - void imagePaintedOnScreen(); + /** + * Notify subscriber that screen is updated, so client can send another + * frame buffer update request to server. + */ + void imagePaintedOnScreen(); } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/RfbConstants.java b/console-proxy/src/com/cloud/consoleproxy/vnc/RfbConstants.java index 75499b862ac..18bf47ec1d4 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/RfbConstants.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/RfbConstants.java @@ -20,62 +20,63 @@ import java.nio.charset.Charset; public interface RfbConstants { - public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003."; -// public static final String VNC_PROTOCOL_VERSION_MINOR = "003"; - public static final String VNC_PROTOCOL_VERSION_MINOR = "003"; - public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR; + public static final String RFB_PROTOCOL_VERSION_MAJOR = "RFB 003."; + // public static final String VNC_PROTOCOL_VERSION_MINOR = "003"; + public static final String VNC_PROTOCOL_VERSION_MINOR = "003"; + public static final String RFB_PROTOCOL_VERSION = RFB_PROTOCOL_VERSION_MAJOR + VNC_PROTOCOL_VERSION_MINOR; - /** - * Server message types. - */ - final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3; + /** + * Server message types. + */ + final static int SERVER_FRAMEBUFFER_UPDATE = 0, SERVER_SET_COLOURMAP_ENTRIES = 1, SERVER_BELL = 2, SERVER_CUT_TEXT = 3; - /** - * Client message types. - */ - public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3, - CLIENT_KEYBOARD_EVENT = 4, CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6; + /** + * Client message types. + */ + public static final int CLIENT_SET_PIXEL_FORMAT = 0, CLIENT_FIX_COLOURMAP_ENTRIES = 1, CLIENT_SET_ENCODINGS = 2, CLIENT_FRAMEBUFFER_UPDATE_REQUEST = 3, CLIENT_KEYBOARD_EVENT = 4, + CLIENT_POINTER_EVENT = 5, CLIENT_CUT_TEXT = 6; - /** - * Server authorization type - */ - public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2; + /** + * Server authorization type + */ + public final static int CONNECTION_FAILED = 0, NO_AUTH = 1, VNC_AUTH = 2; - /** - * Server authorization reply. - */ - public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2; + /** + * Server authorization reply. + */ + public final static int VNC_AUTH_OK = 0, VNC_AUTH_FAILED = 1, VNC_AUTH_TOO_MANY = 2; - /** - * Encodings. - */ - public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16; + /** + * Encodings. + */ + public final static int ENCODING_RAW = 0, ENCODING_COPY_RECT = 1, ENCODING_RRE = 2, ENCODING_CO_RRE = 4, ENCODING_HEXTILE = 5, ENCODING_ZRLE = 16; - /** - * Pseudo-encodings. - */ - public final static int ENCODING_CURSOR = -239 /*0xFFFFFF11*/, ENCODING_DESKTOP_SIZE = -223 /*0xFFFFFF21*/; + /** + * Pseudo-encodings. + */ + public final static int ENCODING_CURSOR = -239 /* 0xFFFFFF11 */, ENCODING_DESKTOP_SIZE = -223 /* 0xFFFFFF21 */; - /** - * Encodings, which we support. - */ - public final static int[] SUPPORTED_ENCODINGS_ARRAY = { ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE }; + /** + * Encodings, which we support. + */ + public final static int[] SUPPORTED_ENCODINGS_ARRAY = { ENCODING_RAW, ENCODING_COPY_RECT, ENCODING_DESKTOP_SIZE }; - /** - * Frame buffer update request type: update of whole screen or partial update. - */ - public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1; + /** + * Frame buffer update request type: update of whole screen or partial + * update. + */ + public static final int FRAMEBUFFER_FULL_UPDATE_REQUEST = 0, FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST = 1; - public static final int KEY_UP = 0, KEY_DOWN = 1; + public static final int KEY_UP = 0, KEY_DOWN = 1; - public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1; + public static final int LITTLE_ENDIAN = 0, BIG_ENDIAN = 1; - public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1; + public static final int EXCLUSIVE_ACCESS = 0, SHARED_ACCESS = 1; - public static final int PALETTE = 0, TRUE_COLOR = 1; + public static final int PALETTE = 0, TRUE_COLOR = 1; - /** - * Default charset to use when communicating with server. - */ - public static final Charset CHARSET = Charset.availableCharsets().get("US-ASCII"); + /** + * Default charset to use when communicating with server. + */ + public static final Charset CHARSET = Charset.availableCharsets().get("US-ASCII"); } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/VncClient.java b/console-proxy/src/com/cloud/consoleproxy/vnc/VncClient.java index abc9ffaeced..194eec17414 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/VncClient.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/VncClient.java @@ -39,414 +39,413 @@ import com.cloud.consoleproxy.vnc.packet.client.KeyboardEventPacket; import com.cloud.consoleproxy.vnc.packet.client.MouseEventPacket; public class VncClient { - private static final Logger s_logger = Logger.getLogger(VncClient.class); + private static final Logger s_logger = Logger.getLogger(VncClient.class); - private Socket socket; - private DataInputStream is; - private DataOutputStream os; + private Socket socket; + private DataInputStream is; + private DataOutputStream os; - private VncScreenDescription screen = new VncScreenDescription(); + private VncScreenDescription screen = new VncScreenDescription(); - private VncClientPacketSender sender; - private VncServerPacketReceiver receiver; - - private boolean noUI = false; - private ConsoleProxyClientListener clientListener = null; + private VncClientPacketSender sender; + private VncServerPacketReceiver receiver; - public static void main(String args[]) { - if (args.length < 3) { - printHelpMessage(); - System.exit(1); + private boolean noUI = false; + private ConsoleProxyClientListener clientListener = null; + + public static void main(String args[]) { + if (args.length < 3) { + printHelpMessage(); + System.exit(1); + } + + String host = args[0]; + String port = args[1]; + String password = args[2]; + + try { + new VncClient(host, Integer.parseInt(port), password, false, null); + } catch (NumberFormatException e) { + s_logger.error("Incorrect VNC server port number: " + port + "."); + System.exit(1); + } catch (UnknownHostException e) { + s_logger.error("Incorrect VNC server host name: " + host + "."); + System.exit(1); + } catch (IOException e) { + s_logger.error("Cannot communicate with VNC server: " + e.getMessage()); + System.exit(1); + } catch (Throwable e) { + s_logger.error("An error happened: " + e.getMessage()); + System.exit(1); + } + System.exit(0); } - String host = args[0]; - String port = args[1]; - String password = args[2]; - - try { - new VncClient(host, Integer.parseInt(port), password, false, null); - } catch (NumberFormatException e) { - s_logger.error("Incorrect VNC server port number: " + port + "."); - System.exit(1); - } catch (UnknownHostException e) { - s_logger.error("Incorrect VNC server host name: " + host + "."); - System.exit(1); - } catch (IOException e) { - s_logger.error("Cannot communicate with VNC server: " + e.getMessage()); - System.exit(1); - } catch (Throwable e) { - s_logger.error("An error happened: " + e.getMessage()); - System.exit(1); - } - System.exit(0); - } - - private static void printHelpMessage() { - /* LOG */s_logger.info("Usage: HOST PORT PASSWORD."); - } - - public VncClient(ConsoleProxyClientListener clientListener) { - this.noUI = true; - this.clientListener = clientListener; - } - - public VncClient(String host, int port, String password, boolean noUI, ConsoleProxyClientListener clientListener) - throws UnknownHostException, IOException { - - this.noUI = noUI; - this.clientListener = clientListener; - connectTo(host, port, password); - } - - public void shutdown() { - if(sender != null) - sender.closeConnection(); - - if(receiver != null) - receiver.closeConnection(); - - if(is != null) { - try { - is.close(); - } catch (Throwable e) { - } - } - - if(os != null) { - try { - os.close(); - } catch (Throwable e) { - } - } - - if(socket != null) { - try { - socket.close(); - } catch (Throwable e) { - } - } - } - - public ConsoleProxyClientListener getClientListener() { - return clientListener; - } - - public void connectTo(String host, int port, String path, - String session, boolean useSSL, String sid) throws UnknownHostException, IOException { - if(port < 0) { - if(useSSL) - port = 443; - else - port = 80; - } - - RawHTTP tunnel = new RawHTTP("CONNECT", host, port, path, session, useSSL); - this.socket = tunnel.connect(); - doConnect(sid); - } - - public void connectTo(String host, int port, String password) throws UnknownHostException, IOException { - // Connect to server - s_logger.info("Connecting to VNC server " + host + ":" + port + "..."); - this.socket = new Socket(host, port); - doConnect(password); - } - - private void doConnect(String password) throws IOException { - is = new DataInputStream(socket.getInputStream()); - os = new DataOutputStream(socket.getOutputStream()); - - // Initialize connection - handshake(); - authenticate(password); - initialize(); - - s_logger.info("Connecting to VNC server succeeded, start session"); - - // Run client-to-server packet sender - sender = new VncClientPacketSender(os, screen, this); - - // Create buffered image canvas - BufferedImageCanvas canvas = new BufferedImageCanvas(sender, screen.getFramebufferWidth(), screen.getFramebufferHeight()); - - // Subscribe packet sender to various events - canvas.addMouseListener(sender); - canvas.addMouseMotionListener(sender); - canvas.addKeyListener(sender); - - Frame frame = null; - if(!noUI) - frame = createVncClientMainWindow(canvas, screen.getDesktopName()); - - new Thread(sender).start(); - - // Run server-to-client packet receiver - receiver = new VncServerPacketReceiver(is, canvas, screen, this, sender, clientListener); - try { - receiver.run(); - } finally { - if(frame != null) { - frame.setVisible(false); - frame.dispose(); - } - this.shutdown(); - } - } - - private Frame createVncClientMainWindow(BufferedImageCanvas canvas, String title) { - // Create AWT windows - final Frame frame = new Frame(title + " - VNCle"); - - // Use scrolling pane to support screens, which are larger than ours - ScrollPane scroller = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); - scroller.add(canvas); - scroller.setSize(screen.getFramebufferWidth(), screen.getFramebufferHeight()); - - frame.add(scroller); - frame.pack(); - frame.setVisible(true); - - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent evt) { - frame.setVisible(false); - shutdown(); - } - }); - - return frame; - } - - /** - * Handshake with VNC server. - */ - private void handshake() throws IOException { - - // Read protocol version - byte[] buf = new byte[12]; - is.readFully(buf); - String rfbProtocol = new String(buf); - - // Server should use RFB protocol 3.x - if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR)) { - s_logger.error("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\"."); - throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\"."); + private static void printHelpMessage() { + /* LOG */s_logger.info("Usage: HOST PORT PASSWORD."); } - // Send response: we support RFB 3.3 only - String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n"; - os.write(ourProtocolString.getBytes()); - os.flush(); - } - - /** - * VNC authentication. - */ - private void authenticate(String password) throws IOException { - // Read security type - int authType = is.readInt(); - - switch (authType) { - case RfbConstants.CONNECTION_FAILED: { - // Server forbids to connect. Read reason and throw exception - - int length = is.readInt(); - byte[] buf = new byte[length]; - is.readFully(buf); - String reason = new String(buf, RfbConstants.CHARSET); - - s_logger.error("Authentication to VNC server is failed. Reason: " + reason); - throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason); + public VncClient(ConsoleProxyClientListener clientListener) { + this.noUI = true; + this.clientListener = clientListener; } - case RfbConstants.NO_AUTH: { - // Client can connect without authorization. Nothing to do. - break; + public VncClient(String host, int port, String password, boolean noUI, ConsoleProxyClientListener clientListener) throws UnknownHostException, IOException { + + this.noUI = noUI; + this.clientListener = clientListener; + connectTo(host, port, password); } - case RfbConstants.VNC_AUTH: { - s_logger.info("VNC server requires password authentication"); - doVncAuth(password); - break; + public void shutdown() { + if (sender != null) + sender.closeConnection(); + + if (receiver != null) + receiver.closeConnection(); + + if (is != null) { + try { + is.close(); + } catch (Throwable e) { + } + } + + if (os != null) { + try { + os.close(); + } catch (Throwable e) { + } + } + + if (socket != null) { + try { + socket.close(); + } catch (Throwable e) { + } + } } - default: - s_logger.error("Unsupported VNC protocol authorization scheme, scheme code: " + authType + "."); - throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + "."); - } - } - - /** - * Encode client password and send it to server. - */ - private void doVncAuth(String password) throws IOException { - - // Read challenge - byte[] challenge = new byte[16]; - is.readFully(challenge); - - // Encode challenge with password - byte[] response; - try { - response = encodePassword(challenge, password); - } catch (Exception e) { - s_logger.error("Cannot encrypt client password to send to server: " + e.getMessage()); - throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage()); + public ConsoleProxyClientListener getClientListener() { + return clientListener; } - // Send encoded challenge - os.write(response); - os.flush(); + public void connectTo(String host, int port, String path, String session, boolean useSSL, String sid) throws UnknownHostException, IOException { + if (port < 0) { + if (useSSL) + port = 443; + else + port = 80; + } - // Read security result - int authResult = is.readInt(); - - switch (authResult) { - case RfbConstants.VNC_AUTH_OK: { - // Nothing to do - break; + RawHTTP tunnel = new RawHTTP("CONNECT", host, port, path, session, useSSL); + this.socket = tunnel.connect(); + doConnect(sid); } - case RfbConstants.VNC_AUTH_TOO_MANY: - s_logger.error("Connection to VNC server failed: too many wrong attempts."); - throw new RuntimeException("Connection to VNC server failed: too many wrong attempts."); - - case RfbConstants.VNC_AUTH_FAILED: - s_logger.error("Connection to VNC server failed: wrong password."); - throw new RuntimeException("Connection to VNC server failed: wrong password."); - - default: - s_logger.error("Connection to VNC server failed, reason code: " + authResult); - throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult); - } - } - - /** - * Encode password using DES encryption with given challenge. - * - * @param challenge - * a random set of bytes. - * @param password - * a password - * @return DES hash of password and challenge - */ - public byte[] encodePassword(byte[] challenge, String password) throws Exception { - // VNC password consist of up to eight ASCII characters. - byte[] key = { 0, 0, 0, 0, 0, 0, 0, 0 }; // Padding - byte[] passwordAsciiBytes = password.getBytes(RfbConstants.CHARSET); - System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8)); - - // Flip bytes (reverse bits) in key - for (int i = 0; i < key.length; i++) { - key[i] = flipByte(key[i]); + public void connectTo(String host, int port, String password) throws UnknownHostException, IOException { + // Connect to server + s_logger.info("Connecting to VNC server " + host + ":" + port + "..."); + this.socket = new Socket(host, port); + doConnect(password); } - KeySpec desKeySpec = new DESKeySpec(key); - SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); - SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec); - Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding"); - cipher.init(Cipher.ENCRYPT_MODE, secretKey); + private void doConnect(String password) throws IOException { + is = new DataInputStream(socket.getInputStream()); + os = new DataOutputStream(socket.getOutputStream()); - byte[] response = cipher.doFinal(challenge); - return response; - } + // Initialize connection + handshake(); + authenticate(password); + initialize(); - /** - * Reverse bits in byte, so least significant bit will be most significant - * bit. E.g. 01001100 will become 00110010. - * - * See also: http://www.vidarholen.net/contents/junk/vnc.html , - * http://bytecrafter .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html - * - * @param b - * a byte - * @return byte in reverse order - */ - private static byte flipByte(byte b) { - int b1_8 = (b & 0x1) << 7; - int b2_7 = (b & 0x2) << 5; - int b3_6 = (b & 0x4) << 3; - int b4_5 = (b & 0x8) << 1; - int b5_4 = (b & 0x10) >>> 1; - int b6_3 = (b & 0x20) >>> 3; - int b7_2 = (b & 0x40) >>> 5; - int b8_1 = (b & 0x80) >>> 7; - byte c = (byte) (b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1); - return c; - } + s_logger.info("Connecting to VNC server succeeded, start session"); - private void initialize() throws IOException { - // Send client initialization message - { - // Send shared flag - os.writeByte(RfbConstants.EXCLUSIVE_ACCESS); - os.flush(); + // Run client-to-server packet sender + sender = new VncClientPacketSender(os, screen, this); + + // Create buffered image canvas + BufferedImageCanvas canvas = new BufferedImageCanvas(sender, screen.getFramebufferWidth(), screen.getFramebufferHeight()); + + // Subscribe packet sender to various events + canvas.addMouseListener(sender); + canvas.addMouseMotionListener(sender); + canvas.addKeyListener(sender); + + Frame frame = null; + if (!noUI) + frame = createVncClientMainWindow(canvas, screen.getDesktopName()); + + new Thread(sender).start(); + + // Run server-to-client packet receiver + receiver = new VncServerPacketReceiver(is, canvas, screen, this, sender, clientListener); + try { + receiver.run(); + } finally { + if (frame != null) { + frame.setVisible(false); + frame.dispose(); + } + this.shutdown(); + } } - // Read server initialization message - { - // Read frame buffer size - int framebufferWidth = is.readUnsignedShort(); - int framebufferHeight = is.readUnsignedShort(); - screen.setFramebufferSize(framebufferWidth, framebufferHeight); - if(clientListener != null) - clientListener.onFramebufferSizeChange(framebufferWidth, framebufferHeight); + private Frame createVncClientMainWindow(BufferedImageCanvas canvas, String title) { + // Create AWT windows + final Frame frame = new Frame(title + " - VNCle"); + + // Use scrolling pane to support screens, which are larger than ours + ScrollPane scroller = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED); + scroller.add(canvas); + scroller.setSize(screen.getFramebufferWidth(), screen.getFramebufferHeight()); + + frame.add(scroller); + frame.pack(); + frame.setVisible(true); + + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent evt) { + frame.setVisible(false); + shutdown(); + } + }); + + return frame; } - // Read pixel format - { - int bitsPerPixel = is.readUnsignedByte(); - int depth = is.readUnsignedByte(); + /** + * Handshake with VNC server. + */ + private void handshake() throws IOException { - int bigEndianFlag = is.readUnsignedByte(); - int trueColorFlag = is.readUnsignedByte(); + // Read protocol version + byte[] buf = new byte[12]; + is.readFully(buf); + String rfbProtocol = new String(buf); - int redMax = is.readUnsignedShort(); - int greenMax = is.readUnsignedShort(); - int blueMax = is.readUnsignedShort(); + // Server should use RFB protocol 3.x + if (!rfbProtocol.contains(RfbConstants.RFB_PROTOCOL_VERSION_MAJOR)) { + s_logger.error("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\"."); + throw new RuntimeException("Cannot handshake with VNC server. Unsupported protocol version: \"" + rfbProtocol + "\"."); + } - int redShift = is.readUnsignedByte(); - int greenShift = is.readUnsignedByte(); - int blueShift = is.readUnsignedByte(); - - // Skip padding - is.skipBytes(3); - - screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag, trueColorFlag, redMax, greenMax, blueMax, redShift, greenShift, blueShift); + // Send response: we support RFB 3.3 only + String ourProtocolString = RfbConstants.RFB_PROTOCOL_VERSION + "\n"; + os.write(ourProtocolString.getBytes()); + os.flush(); } - // Read desktop name - { - int length = is.readInt(); - byte buf[] = new byte[length]; - is.readFully(buf); - String desktopName = new String(buf, RfbConstants.CHARSET); - screen.setDesktopName(desktopName); + /** + * VNC authentication. + */ + private void authenticate(String password) throws IOException { + // Read security type + int authType = is.readInt(); + + switch (authType) { + case RfbConstants.CONNECTION_FAILED: { + // Server forbids to connect. Read reason and throw exception + + int length = is.readInt(); + byte[] buf = new byte[length]; + is.readFully(buf); + String reason = new String(buf, RfbConstants.CHARSET); + + s_logger.error("Authentication to VNC server is failed. Reason: " + reason); + throw new RuntimeException("Authentication to VNC server is failed. Reason: " + reason); + } + + case RfbConstants.NO_AUTH: { + // Client can connect without authorization. Nothing to do. + break; + } + + case RfbConstants.VNC_AUTH: { + s_logger.info("VNC server requires password authentication"); + doVncAuth(password); + break; + } + + default: + s_logger.error("Unsupported VNC protocol authorization scheme, scheme code: " + authType + "."); + throw new RuntimeException("Unsupported VNC protocol authorization scheme, scheme code: " + authType + "."); + } + } + + /** + * Encode client password and send it to server. + */ + private void doVncAuth(String password) throws IOException { + + // Read challenge + byte[] challenge = new byte[16]; + is.readFully(challenge); + + // Encode challenge with password + byte[] response; + try { + response = encodePassword(challenge, password); + } catch (Exception e) { + s_logger.error("Cannot encrypt client password to send to server: " + e.getMessage()); + throw new RuntimeException("Cannot encrypt client password to send to server: " + e.getMessage()); + } + + // Send encoded challenge + os.write(response); + os.flush(); + + // Read security result + int authResult = is.readInt(); + + switch (authResult) { + case RfbConstants.VNC_AUTH_OK: { + // Nothing to do + break; + } + + case RfbConstants.VNC_AUTH_TOO_MANY: + s_logger.error("Connection to VNC server failed: too many wrong attempts."); + throw new RuntimeException("Connection to VNC server failed: too many wrong attempts."); + + case RfbConstants.VNC_AUTH_FAILED: + s_logger.error("Connection to VNC server failed: wrong password."); + throw new RuntimeException("Connection to VNC server failed: wrong password."); + + default: + s_logger.error("Connection to VNC server failed, reason code: " + authResult); + throw new RuntimeException("Connection to VNC server failed, reason code: " + authResult); + } + } + + /** + * Encode password using DES encryption with given challenge. + * + * @param challenge + * a random set of bytes. + * @param password + * a password + * @return DES hash of password and challenge + */ + public byte[] encodePassword(byte[] challenge, String password) throws Exception { + // VNC password consist of up to eight ASCII characters. + byte[] key = { 0, 0, 0, 0, 0, 0, 0, 0 }; // Padding + byte[] passwordAsciiBytes = password.getBytes(RfbConstants.CHARSET); + System.arraycopy(passwordAsciiBytes, 0, key, 0, Math.min(password.length(), 8)); + + // Flip bytes (reverse bits) in key + for (int i = 0; i < key.length; i++) { + key[i] = flipByte(key[i]); + } + + KeySpec desKeySpec = new DESKeySpec(key); + SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES"); + SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec); + Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + + byte[] response = cipher.doFinal(challenge); + return response; + } + + /** + * Reverse bits in byte, so least significant bit will be most significant + * bit. E.g. 01001100 will become 00110010. + * + * See also: http://www.vidarholen.net/contents/junk/vnc.html , + * http://bytecrafter + * .blogspot.com/2010/09/des-encryption-as-used-in-vnc.html + * + * @param b + * a byte + * @return byte in reverse order + */ + private static byte flipByte(byte b) { + int b1_8 = (b & 0x1) << 7; + int b2_7 = (b & 0x2) << 5; + int b3_6 = (b & 0x4) << 3; + int b4_5 = (b & 0x8) << 1; + int b5_4 = (b & 0x10) >>> 1; + int b6_3 = (b & 0x20) >>> 3; + int b7_2 = (b & 0x40) >>> 5; + int b8_1 = (b & 0x80) >>> 7; + byte c = (byte) (b1_8 | b2_7 | b3_6 | b4_5 | b5_4 | b6_3 | b7_2 | b8_1); + return c; + } + + private void initialize() throws IOException { + // Send client initialization message + { + // Send shared flag + os.writeByte(RfbConstants.EXCLUSIVE_ACCESS); + os.flush(); + } + + // Read server initialization message + { + // Read frame buffer size + int framebufferWidth = is.readUnsignedShort(); + int framebufferHeight = is.readUnsignedShort(); + screen.setFramebufferSize(framebufferWidth, framebufferHeight); + if (clientListener != null) + clientListener.onFramebufferSizeChange(framebufferWidth, framebufferHeight); + } + + // Read pixel format + { + int bitsPerPixel = is.readUnsignedByte(); + int depth = is.readUnsignedByte(); + + int bigEndianFlag = is.readUnsignedByte(); + int trueColorFlag = is.readUnsignedByte(); + + int redMax = is.readUnsignedShort(); + int greenMax = is.readUnsignedShort(); + int blueMax = is.readUnsignedShort(); + + int redShift = is.readUnsignedByte(); + int greenShift = is.readUnsignedByte(); + int blueShift = is.readUnsignedByte(); + + // Skip padding + is.skipBytes(3); + + screen.setPixelFormat(bitsPerPixel, depth, bigEndianFlag, trueColorFlag, redMax, greenMax, blueMax, redShift, greenShift, blueShift); + } + + // Read desktop name + { + int length = is.readInt(); + byte buf[] = new byte[length]; + is.readFully(buf); + String desktopName = new String(buf, RfbConstants.CHARSET); + screen.setDesktopName(desktopName); + } + } + + public FrameBufferCanvas getFrameBufferCanvas() { + if (receiver != null) + return receiver.getCanvas(); + + return null; + } + + public void requestUpdate(boolean fullUpdate) { + if (fullUpdate) + sender.requestFullScreenUpdate(); + else + sender.imagePaintedOnScreen(); + } + + public void sendClientKeyboardEvent(int event, int code, int modifiers) { + sender.sendClientPacket(new KeyboardEventPacket(event, code)); + } + + public void sendClientMouseEvent(int event, int x, int y, int code, int modifiers) { + sender.sendClientPacket(new MouseEventPacket(event, x, y)); + } + + public boolean isHostConnected() { + return receiver != null && receiver.isConnectionAlive(); } - } - - public FrameBufferCanvas getFrameBufferCanvas() { - if(receiver != null) - return receiver.getCanvas(); - - return null; - } - - public void requestUpdate(boolean fullUpdate) { - if(fullUpdate) - sender.requestFullScreenUpdate(); - else - sender.imagePaintedOnScreen(); - } - - public void sendClientKeyboardEvent(int event, int code, int modifiers) { - sender.sendClientPacket(new KeyboardEventPacket(event, code)); - } - - public void sendClientMouseEvent(int event, int x, int y, int code, int modifiers) { - sender.sendClientPacket(new MouseEventPacket(event, x, y)); - } - - public boolean isHostConnected() { - return receiver != null && receiver.isConnectionAlive(); - } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/VncClientPacketSender.java b/console-proxy/src/com/cloud/consoleproxy/vnc/VncClientPacketSender.java index cf15f885e5f..d27b76d3468 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/VncClientPacketSender.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/VncClientPacketSender.java @@ -35,226 +35,224 @@ import com.cloud.consoleproxy.vnc.packet.client.SetEncodingsPacket; import com.cloud.consoleproxy.vnc.packet.client.SetPixelFormatPacket; public class VncClientPacketSender implements Runnable, PaintNotificationListener, KeyListener, MouseListener, MouseMotionListener, FrameBufferUpdateListener { - private static final Logger s_logger = Logger.getLogger(VncClientPacketSender.class); + private static final Logger s_logger = Logger.getLogger(VncClientPacketSender.class); - // Queue for outgoing packets - private final BlockingQueue queue = new ArrayBlockingQueue(30); + // Queue for outgoing packets + private final BlockingQueue queue = new ArrayBlockingQueue(30); - private final DataOutputStream os; - private final VncScreenDescription screen; - private final VncClient vncConnection; + private final DataOutputStream os; + private final VncScreenDescription screen; + private final VncClient vncConnection; - private boolean connectionAlive = true; + private boolean connectionAlive = true; - // Don't send update request again until we receive next frame buffer update - private boolean updateRequestSent = false; + // Don't send update request again until we receive next frame buffer update + private boolean updateRequestSent = false; - public VncClientPacketSender(DataOutputStream os, VncScreenDescription screen, VncClient vncConnection) { - this.os = os; - this.screen = screen; - this.vncConnection = vncConnection; + public VncClientPacketSender(DataOutputStream os, VncScreenDescription screen, VncClient vncConnection) { + this.os = os; + this.screen = screen; + this.vncConnection = vncConnection; - sendSetPixelFormat(); - sendSetEncodings(); - requestFullScreenUpdate(); - } - - public void sendClientPacket(ClientPacket packet) { - queue.add(packet); - } + sendSetPixelFormat(); + sendSetEncodings(); + requestFullScreenUpdate(); + } - @Override - public void run() { - try { - while (connectionAlive) { - ClientPacket packet = queue.poll(1, TimeUnit.SECONDS); - if (packet != null) { - packet.write(os); - os.flush(); + public void sendClientPacket(ClientPacket packet) { + queue.add(packet); + } + + @Override + public void run() { + try { + while (connectionAlive) { + ClientPacket packet = queue.poll(1, TimeUnit.SECONDS); + if (packet != null) { + packet.write(os); + os.flush(); + } + } + } catch (Throwable e) { + s_logger.error("Unexpected exception: ", e); + if (connectionAlive) { + closeConnection(); + vncConnection.shutdown(); + } } - } - } catch (Throwable e) { - s_logger.error("Unexpected exception: ", e); - if (connectionAlive) { - closeConnection(); - vncConnection.shutdown(); - } - } - } - - private void sendSetEncodings() { - queue.add(new SetEncodingsPacket(RfbConstants.SUPPORTED_ENCODINGS_ARRAY)); - } - - private void sendSetPixelFormat() { - if (!screen.isRGB888_32_LE()) { - queue.add(new SetPixelFormatPacket(screen, 32, 24, RfbConstants.LITTLE_ENDIAN, RfbConstants.TRUE_COLOR, 255, 255, 255, 16, 8, 0)); - } - } - - public void closeConnection() { - connectionAlive = false; - } - - public void requestFullScreenUpdate() { - queue.add(new FramebufferUpdateRequestPacket(RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST, 0, 0, screen.getFramebufferWidth(), screen - .getFramebufferHeight())); - updateRequestSent = true; - } - - @Override - public void imagePaintedOnScreen() { - if (!updateRequestSent) { - queue.add(new FramebufferUpdateRequestPacket(RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST, 0, 0, screen.getFramebufferWidth(), screen - .getFramebufferHeight())); - updateRequestSent = true; - } - } - - @Override - public void frameBufferPacketReceived() { - updateRequestSent = false; - } - - @Override - public void mouseDragged(MouseEvent e) { - queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); - } - - @Override - public void mouseMoved(MouseEvent e) { - queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); - } - - @Override - public void mouseClicked(MouseEvent e) { - // Nothing to do - } - - @Override - public void mousePressed(MouseEvent e) { - queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); - } - - @Override - public void mouseReleased(MouseEvent e) { - queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); - } - - @Override - public void mouseEntered(MouseEvent e) { - // Nothing to do - } - - @Override - public void mouseExited(MouseEvent e) { - // Nothing to do - } - - /** - * Current state of buttons 1 to 8 are represented by bits 0 to 7 of - * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a - * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and - * right buttons on the mouse. On a wheel mouse, each step of the wheel - * upwards is represented by a press and release of button 4, and each step - * downwards is represented by a press and release of button 5. - * - * @param modifiers - * extended modifiers from AWT mouse event - * @return VNC mouse button mask - */ - public static int mapAwtModifiersToVncButtonMask(int modifiers) { - int mask = (((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0) - | (((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0); - return mask; - } - - @Override - public void keyTyped(KeyEvent e) { - // Do nothing - } - - @Override - public void keyPressed(KeyEvent e) { - ClientPacket request = new KeyboardEventPacket(RfbConstants.KEY_DOWN, mapAwtKeyToVncKey(e.getKeyCode())); - queue.add(request); - } - - @Override - public void keyReleased(KeyEvent e) { - ClientPacket request = new KeyboardEventPacket(RfbConstants.KEY_UP, mapAwtKeyToVncKey(e.getKeyCode())); - queue.add(request); - } - - private int mapAwtKeyToVncKey(int key) { - switch (key) { - case KeyEvent.VK_BACK_SPACE: - return 0xff08; - case KeyEvent.VK_TAB: - return 0xff09; - case KeyEvent.VK_ENTER: - return 0xff0d; - case KeyEvent.VK_ESCAPE: - return 0xff1b; - case KeyEvent.VK_INSERT: - return 0xff63; - case KeyEvent.VK_DELETE: - return 0xffff; - case KeyEvent.VK_HOME: - return 0xff50; - case KeyEvent.VK_END: - return 0xff57; - case KeyEvent.VK_PAGE_UP: - return 0xff55; - case KeyEvent.VK_PAGE_DOWN: - return 0xff56; - case KeyEvent.VK_LEFT: - return 0xff51; - case KeyEvent.VK_UP: - return 0xff52; - case KeyEvent.VK_RIGHT: - return 0xff53; - case KeyEvent.VK_DOWN: - return 0xff54; - case KeyEvent.VK_F1: - return 0xffbe; - case KeyEvent.VK_F2: - return 0xffbf; - case KeyEvent.VK_F3: - return 0xffc0; - case KeyEvent.VK_F4: - return 0xffc1; - case KeyEvent.VK_F5: - return 0xffc2; - case KeyEvent.VK_F6: - return 0xffc3; - case KeyEvent.VK_F7: - return 0xffc4; - case KeyEvent.VK_F8: - return 0xffc5; - case KeyEvent.VK_F9: - return 0xffc6; - case KeyEvent.VK_F10: - return 0xffc7; - case KeyEvent.VK_F11: - return 0xffc8; - case KeyEvent.VK_F12: - return 0xffc9; - case KeyEvent.VK_SHIFT: - return 0xffe1; - case KeyEvent.VK_CONTROL: - return 0xffe3; - case KeyEvent.VK_META: - return 0xffe7; - case KeyEvent.VK_ALT: - return 0xffe9; - case KeyEvent.VK_ALT_GRAPH: - return 0xffea; - case KeyEvent.VK_BACK_QUOTE: - return 0x0060; } - return key; - } + private void sendSetEncodings() { + queue.add(new SetEncodingsPacket(RfbConstants.SUPPORTED_ENCODINGS_ARRAY)); + } + + private void sendSetPixelFormat() { + if (!screen.isRGB888_32_LE()) { + queue.add(new SetPixelFormatPacket(screen, 32, 24, RfbConstants.LITTLE_ENDIAN, RfbConstants.TRUE_COLOR, 255, 255, 255, 16, 8, 0)); + } + } + + public void closeConnection() { + connectionAlive = false; + } + + public void requestFullScreenUpdate() { + queue.add(new FramebufferUpdateRequestPacket(RfbConstants.FRAMEBUFFER_FULL_UPDATE_REQUEST, 0, 0, screen.getFramebufferWidth(), screen.getFramebufferHeight())); + updateRequestSent = true; + } + + @Override + public void imagePaintedOnScreen() { + if (!updateRequestSent) { + queue.add(new FramebufferUpdateRequestPacket(RfbConstants.FRAMEBUFFER_INCREMENTAL_UPDATE_REQUEST, 0, 0, screen.getFramebufferWidth(), screen.getFramebufferHeight())); + updateRequestSent = true; + } + } + + @Override + public void frameBufferPacketReceived() { + updateRequestSent = false; + } + + @Override + public void mouseDragged(MouseEvent e) { + queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); + } + + @Override + public void mouseMoved(MouseEvent e) { + queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); + } + + @Override + public void mouseClicked(MouseEvent e) { + // Nothing to do + } + + @Override + public void mousePressed(MouseEvent e) { + queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); + } + + @Override + public void mouseReleased(MouseEvent e) { + queue.add(new MouseEventPacket(mapAwtModifiersToVncButtonMask(e.getModifiersEx()), e.getX(), e.getY())); + } + + @Override + public void mouseEntered(MouseEvent e) { + // Nothing to do + } + + @Override + public void mouseExited(MouseEvent e) { + // Nothing to do + } + + /** + * Current state of buttons 1 to 8 are represented by bits 0 to 7 of + * button-mask respectively, 0 meaning up, 1 meaning down (pressed). On a + * conventional mouse, buttons 1, 2 and 3 correspond to the left, middle and + * right buttons on the mouse. On a wheel mouse, each step of the wheel + * upwards is represented by a press and release of button 4, and each step + * downwards is represented by a press and release of button 5. + * + * @param modifiers + * extended modifiers from AWT mouse event + * @return VNC mouse button mask + */ + public static int mapAwtModifiersToVncButtonMask(int modifiers) { + int mask = (((modifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0) ? 0x1 : 0) | (((modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0) ? 0x2 : 0) + | (((modifiers & MouseEvent.BUTTON3_DOWN_MASK) != 0) ? 0x4 : 0); + return mask; + } + + @Override + public void keyTyped(KeyEvent e) { + // Do nothing + } + + @Override + public void keyPressed(KeyEvent e) { + ClientPacket request = new KeyboardEventPacket(RfbConstants.KEY_DOWN, mapAwtKeyToVncKey(e.getKeyCode())); + queue.add(request); + } + + @Override + public void keyReleased(KeyEvent e) { + ClientPacket request = new KeyboardEventPacket(RfbConstants.KEY_UP, mapAwtKeyToVncKey(e.getKeyCode())); + queue.add(request); + } + + private int mapAwtKeyToVncKey(int key) { + switch (key) { + case KeyEvent.VK_BACK_SPACE: + return 0xff08; + case KeyEvent.VK_TAB: + return 0xff09; + case KeyEvent.VK_ENTER: + return 0xff0d; + case KeyEvent.VK_ESCAPE: + return 0xff1b; + case KeyEvent.VK_INSERT: + return 0xff63; + case KeyEvent.VK_DELETE: + return 0xffff; + case KeyEvent.VK_HOME: + return 0xff50; + case KeyEvent.VK_END: + return 0xff57; + case KeyEvent.VK_PAGE_UP: + return 0xff55; + case KeyEvent.VK_PAGE_DOWN: + return 0xff56; + case KeyEvent.VK_LEFT: + return 0xff51; + case KeyEvent.VK_UP: + return 0xff52; + case KeyEvent.VK_RIGHT: + return 0xff53; + case KeyEvent.VK_DOWN: + return 0xff54; + case KeyEvent.VK_F1: + return 0xffbe; + case KeyEvent.VK_F2: + return 0xffbf; + case KeyEvent.VK_F3: + return 0xffc0; + case KeyEvent.VK_F4: + return 0xffc1; + case KeyEvent.VK_F5: + return 0xffc2; + case KeyEvent.VK_F6: + return 0xffc3; + case KeyEvent.VK_F7: + return 0xffc4; + case KeyEvent.VK_F8: + return 0xffc5; + case KeyEvent.VK_F9: + return 0xffc6; + case KeyEvent.VK_F10: + return 0xffc7; + case KeyEvent.VK_F11: + return 0xffc8; + case KeyEvent.VK_F12: + return 0xffc9; + case KeyEvent.VK_SHIFT: + return 0xffe1; + case KeyEvent.VK_CONTROL: + return 0xffe3; + case KeyEvent.VK_META: + return 0xffe7; + case KeyEvent.VK_ALT: + return 0xffe9; + case KeyEvent.VK_ALT_GRAPH: + return 0xffea; + case KeyEvent.VK_BACK_QUOTE: + return 0x0060; + } + + return key; + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/VncScreenDescription.java b/console-proxy/src/com/cloud/consoleproxy/vnc/VncScreenDescription.java index c9e135ecd34..44b2a34769b 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/VncScreenDescription.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/VncScreenDescription.java @@ -21,70 +21,69 @@ package com.cloud.consoleproxy.vnc; */ public class VncScreenDescription { - // Frame buffer size - private int framebufferWidth = -1; - private int framebufferHeight = -1; + // Frame buffer size + private int framebufferWidth = -1; + private int framebufferHeight = -1; - // Desktop name - private String desktopName; + // Desktop name + private String desktopName; - // Bytes per pixel - private int bytesPerPixel; + // Bytes per pixel + private int bytesPerPixel; - // Indicates that screen uses format which we want to use: - // RGB 24bit packed into 32bit little-endian int. - private boolean rgb888_32_le = false; + // Indicates that screen uses format which we want to use: + // RGB 24bit packed into 32bit little-endian int. + private boolean rgb888_32_le = false; - public VncScreenDescription() { - } + public VncScreenDescription() { + } - /** - * Store information about server pixel format. - */ - public void setPixelFormat(int bitsPerPixel, int depth, int bigEndianFlag, int trueColorFlag, int redMax, int greenMax, int blueMax, int redShift, - int greenShift, int blueShift) { + /** + * Store information about server pixel format. + */ + public void setPixelFormat(int bitsPerPixel, int depth, int bigEndianFlag, int trueColorFlag, int redMax, int greenMax, int blueMax, int redShift, int greenShift, int blueShift) { - bytesPerPixel = (bitsPerPixel + 7) / 8; + bytesPerPixel = (bitsPerPixel + 7) / 8; - rgb888_32_le = (depth == 24 && bitsPerPixel == 32 && redShift == 16 && greenShift == 8 && blueShift == 0 && redMax == 255 && greenMax == 255 - && blueMax == 255 && bigEndianFlag == RfbConstants.LITTLE_ENDIAN && trueColorFlag == RfbConstants.TRUE_COLOR); - } + rgb888_32_le = (depth == 24 && bitsPerPixel == 32 && redShift == 16 && greenShift == 8 && blueShift == 0 && redMax == 255 && greenMax == 255 && blueMax == 255 + && bigEndianFlag == RfbConstants.LITTLE_ENDIAN && trueColorFlag == RfbConstants.TRUE_COLOR); + } - /** - * Store information about server screen size. - */ - public void setFramebufferSize(int framebufferWidth, int framebufferHeight) { - this.framebufferWidth = framebufferWidth; - this.framebufferHeight = framebufferHeight; - } + /** + * Store information about server screen size. + */ + public void setFramebufferSize(int framebufferWidth, int framebufferHeight) { + this.framebufferWidth = framebufferWidth; + this.framebufferHeight = framebufferHeight; + } - /** - * Store server desktop name. - */ - public void setDesktopName(String desktopName) { - this.desktopName = desktopName; - } + /** + * Store server desktop name. + */ + public void setDesktopName(String desktopName) { + this.desktopName = desktopName; + } - // Getters for variables, as usual + // Getters for variables, as usual - public String getDesktopName() { - return desktopName; - } + public String getDesktopName() { + return desktopName; + } - public int getBytesPerPixel() { - return bytesPerPixel; - } + public int getBytesPerPixel() { + return bytesPerPixel; + } - public int getFramebufferHeight() { - return framebufferHeight; - } + public int getFramebufferHeight() { + return framebufferHeight; + } - public int getFramebufferWidth() { - return framebufferWidth; - } + public int getFramebufferWidth() { + return framebufferWidth; + } - public boolean isRGB888_32_LE() { - return rgb888_32_le; - } + public boolean isRGB888_32_LE() { + return rgb888_32_le; + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java b/console-proxy/src/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java index 06a4f0332e3..57c8ff8efe2 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/VncServerPacketReceiver.java @@ -27,97 +27,97 @@ import com.cloud.consoleproxy.vnc.packet.server.FramebufferUpdatePacket; import com.cloud.consoleproxy.vnc.packet.server.ServerCutText; public class VncServerPacketReceiver implements Runnable { - private static final Logger s_logger = Logger.getLogger(VncServerPacketReceiver.class); + private static final Logger s_logger = Logger.getLogger(VncServerPacketReceiver.class); - private final VncScreenDescription screen; - private BufferedImageCanvas canvas; - private DataInputStream is; + private final VncScreenDescription screen; + private BufferedImageCanvas canvas; + private DataInputStream is; - private boolean connectionAlive = true; - private VncClient vncConnection; - private final FrameBufferUpdateListener fburListener; - private final ConsoleProxyClientListener clientListener; + private boolean connectionAlive = true; + private VncClient vncConnection; + private final FrameBufferUpdateListener fburListener; + private final ConsoleProxyClientListener clientListener; - public VncServerPacketReceiver(DataInputStream is, BufferedImageCanvas canvas, VncScreenDescription screen, VncClient vncConnection, - FrameBufferUpdateListener fburListener, ConsoleProxyClientListener clientListener) { - this.screen = screen; - this.canvas = canvas; - this.is = is; - this.vncConnection = vncConnection; - this.fburListener = fburListener; - this.clientListener = clientListener; - } - - public BufferedImageCanvas getCanvas() { - return canvas; - } - - @Override - public void run() { - try { - while (connectionAlive) { - - // Read server message type - int messageType = is.readUnsignedByte(); - - // Invoke packet handler by packet type. - switch (messageType) { - - case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: { - // Notify sender that frame buffer update is received, - // so it can send another frame buffer update request - fburListener.frameBufferPacketReceived(); - // Handle frame buffer update - new FramebufferUpdatePacket(canvas, screen, is, clientListener); - break; - } - - case RfbConstants.SERVER_BELL: { - serverBell(); - break; - } - - case RfbConstants.SERVER_CUT_TEXT: { - serverCutText(is); - break; - } - - default: - throw new RuntimeException("Unknown server packet type: " + messageType + "."); - } - } - } catch (Throwable e) { - s_logger.error("Unexpected exception: ", e); - if (connectionAlive) { - closeConnection(); - vncConnection.shutdown(); - } + public VncServerPacketReceiver(DataInputStream is, BufferedImageCanvas canvas, VncScreenDescription screen, VncClient vncConnection, FrameBufferUpdateListener fburListener, + ConsoleProxyClientListener clientListener) { + this.screen = screen; + this.canvas = canvas; + this.is = is; + this.vncConnection = vncConnection; + this.fburListener = fburListener; + this.clientListener = clientListener; } - } - public void closeConnection() { - connectionAlive = false; - } - - public boolean isConnectionAlive() { - return connectionAlive; - } + public BufferedImageCanvas getCanvas() { + return canvas; + } - /** - * Handle server bell packet. - */ - private void serverBell() { - Toolkit.getDefaultToolkit().beep(); - } + @Override + public void run() { + try { + while (connectionAlive) { - /** - * Handle packet with server clip-board. - */ - private void serverCutText(DataInputStream is) throws IOException { - ServerCutText clipboardContent = new ServerCutText(is); - StringSelection contents = new StringSelection(clipboardContent.getContent()); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null); - - s_logger.info("Server clipboard buffer: "+clipboardContent.getContent()); - } + // Read server message type + int messageType = is.readUnsignedByte(); + + // Invoke packet handler by packet type. + switch (messageType) { + + case RfbConstants.SERVER_FRAMEBUFFER_UPDATE: { + // Notify sender that frame buffer update is received, + // so it can send another frame buffer update request + fburListener.frameBufferPacketReceived(); + // Handle frame buffer update + new FramebufferUpdatePacket(canvas, screen, is, clientListener); + break; + } + + case RfbConstants.SERVER_BELL: { + serverBell(); + break; + } + + case RfbConstants.SERVER_CUT_TEXT: { + serverCutText(is); + break; + } + + default: + throw new RuntimeException("Unknown server packet type: " + messageType + "."); + } + } + } catch (Throwable e) { + s_logger.error("Unexpected exception: ", e); + if (connectionAlive) { + closeConnection(); + vncConnection.shutdown(); + } + } + } + + public void closeConnection() { + connectionAlive = false; + } + + public boolean isConnectionAlive() { + return connectionAlive; + } + + /** + * Handle server bell packet. + */ + private void serverBell() { + Toolkit.getDefaultToolkit().beep(); + } + + /** + * Handle packet with server clip-board. + */ + private void serverCutText(DataInputStream is) throws IOException { + ServerCutText clipboardContent = new ServerCutText(is); + StringSelection contents = new StringSelection(clipboardContent.getContent()); + Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, null); + + s_logger.info("Server clipboard buffer: " + clipboardContent.getContent()); + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java index 10e7c021cb1..873b8c0825e 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/ClientPacket.java @@ -21,6 +21,6 @@ import java.io.IOException; public interface ClientPacket { - void write(DataOutputStream os) throws IOException; + void write(DataOutputStream os) throws IOException; } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java index b5e87a88f57..d3a6e40e961 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/FramebufferUpdateRequestPacket.java @@ -28,27 +28,26 @@ import com.cloud.consoleproxy.vnc.RfbConstants; */ public class FramebufferUpdateRequestPacket implements ClientPacket { - private final int incremental; - private final int x, y, width, height; + private final int incremental; + private final int x, y, width, height; - public FramebufferUpdateRequestPacket(int incremental, int x, int y, int width, int height) { - this.incremental = incremental; - this.x = x; - this.y = y; - this.width = width; - this.height = height; - } + public FramebufferUpdateRequestPacket(int incremental, int x, int y, int width, int height) { + this.incremental = incremental; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + @Override + public void write(DataOutputStream os) throws IOException { + os.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST); - @Override - public void write(DataOutputStream os) throws IOException { - os.writeByte(RfbConstants.CLIENT_FRAMEBUFFER_UPDATE_REQUEST); - - os.writeByte(incremental); - os.writeShort(x); - os.writeShort(y); - os.writeShort(width); - os.writeShort(height); - } + os.writeByte(incremental); + os.writeShort(x); + os.writeShort(y); + os.writeShort(width); + os.writeShort(height); + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java index 335fee6b176..8efbab123a5 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/KeyboardEventPacket.java @@ -23,20 +23,20 @@ import com.cloud.consoleproxy.vnc.RfbConstants; public class KeyboardEventPacket implements ClientPacket { - private final int downFlag, key; - - public KeyboardEventPacket(int downFlag, int key) { - this.downFlag = downFlag; - this.key = key; - } + private final int downFlag, key; - @Override - public void write(DataOutputStream os) throws IOException { - os.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT); + public KeyboardEventPacket(int downFlag, int key) { + this.downFlag = downFlag; + this.key = key; + } - os.writeByte(downFlag); - os.writeShort(0); // padding - os.writeInt(key); - } + @Override + public void write(DataOutputStream os) throws IOException { + os.writeByte(RfbConstants.CLIENT_KEYBOARD_EVENT); + + os.writeByte(downFlag); + os.writeShort(0); // padding + os.writeInt(key); + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java index 4b799f6f2f7..b42191cbadc 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/MouseEventPacket.java @@ -23,21 +23,21 @@ import com.cloud.consoleproxy.vnc.RfbConstants; public class MouseEventPacket implements ClientPacket { - private final int buttonMask, x, y; + private final int buttonMask, x, y; - public MouseEventPacket(int buttonMask, int x, int y) { - this.buttonMask = buttonMask; - this.x = x; - this.y = y; - } + public MouseEventPacket(int buttonMask, int x, int y) { + this.buttonMask = buttonMask; + this.x = x; + this.y = y; + } - @Override - public void write(DataOutputStream os) throws IOException { - os.writeByte(RfbConstants.CLIENT_POINTER_EVENT); + @Override + public void write(DataOutputStream os) throws IOException { + os.writeByte(RfbConstants.CLIENT_POINTER_EVENT); - os.writeByte(buttonMask); - os.writeShort(x); - os.writeShort(y); - } + os.writeByte(buttonMask); + os.writeShort(x); + os.writeShort(y); + } } diff --git a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java index f34576f23f0..3d8cfcb09a6 100644 --- a/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java +++ b/console-proxy/src/com/cloud/consoleproxy/vnc/packet/client/SetEncodingsPacket.java @@ -23,26 +23,23 @@ import com.cloud.consoleproxy.vnc.RfbConstants; public class SetEncodingsPacket implements ClientPacket { - private final int[] encodings; + private final int[] encodings; - public SetEncodingsPacket(int[] encodings) - { - this.encodings = encodings; - } - - @Override - public void write(DataOutputStream os) throws IOException - { - os.writeByte(RfbConstants.CLIENT_SET_ENCODINGS); - - os.writeByte(0);//padding - - os.writeShort(encodings.length); - - for(int i=0;i -tileMap = [ ${tileSequence} ]; -<#if resized == true> - ajaxViewer.resize('main_panel', ${width}, ${height}, ${tileWidth}, ${tileHeight}); - -ajaxViewer.refresh('${imgUrl}', tileMap, false); - +<#-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +tileMap = [ ${tileSequence} ]; +<#if resized == true> + ajaxViewer.resize('main_panel', ${width}, ${height}, ${tileWidth}, ${tileHeight}); + +ajaxViewer.refresh('${imgUrl}', tileMap, false); + From dd41bedcb6e8e251cbd044781d88ee698b1129f1 Mon Sep 17 00:00:00 2001 From: "Edison.Su" Date: Fri, 7 Sep 2012 21:21:19 -0400 Subject: [PATCH 36/37] fix ant deploy-server --- build/developer.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build/developer.xml b/build/developer.xml index 947fa2e41c3..62f443373c2 100755 --- a/build/developer.xml +++ b/build/developer.xml @@ -182,12 +182,11 @@ - From 0ae1d58c190e01d8066e94f1e9fdc15f0468bdc3 Mon Sep 17 00:00:00 2001 From: Mice Xia Date: Sat, 8 Sep 2012 10:55:34 +0800 Subject: [PATCH 37/37] CLOUDSTACK-50 build-apidocs ClassNotFoundException: com.cloud.api.commands.DeleteCiscoNexusVSMCmd --- build/developer.xml | 14 +++----- client/tomcatconf/commands-ext.properties.in | 22 +------------ .../tomcatconf/netapp_commands.properties.in | 33 +++++++++++++++++++ 3 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 client/tomcatconf/netapp_commands.properties.in diff --git a/build/developer.xml b/build/developer.xml index 62f443373c2..69e4929bd72 100755 --- a/build/developer.xml +++ b/build/developer.xml @@ -398,21 +398,17 @@ - - - - - - - + + + - + - + diff --git a/client/tomcatconf/commands-ext.properties.in b/client/tomcatconf/commands-ext.properties.in index 7e009e6fe29..f172067ede9 100644 --- a/client/tomcatconf/commands-ext.properties.in +++ b/client/tomcatconf/commands-ext.properties.in @@ -20,15 +20,7 @@ generateUsageRecords=com.cloud.api.commands.GenerateUsageRecordsCmd;1 listUsageRecords=com.cloud.api.commands.GetUsageRecordsCmd;1 listUsageTypes=com.cloud.api.commands.ListUsageTypesCmd;1 -#### external firewall commands -addExternalFirewall=com.cloud.api.commands.AddExternalFirewallCmd;1 -deleteExternalFirewall=com.cloud.api.commands.DeleteExternalFirewallCmd;1 -listExternalFirewalls=com.cloud.api.commands.ListExternalFirewallsCmd;1 -#### external loadbalancer commands -addExternalLoadBalancer=com.cloud.api.commands.AddExternalLoadBalancerCmd;1 -deleteExternalLoadBalancer=com.cloud.api.commands.DeleteExternalLoadBalancerCmd;1 -listExternalLoadBalancers=com.cloud.api.commands.ListExternalLoadBalancersCmd;1 ### Network Devices commands addNetworkDevice=com.cloud.api.commands.AddNetworkDeviceCmd;1 @@ -40,16 +32,4 @@ addTrafficMonitor=com.cloud.api.commands.AddTrafficMonitorCmd;1 deleteTrafficMonitor=com.cloud.api.commands.DeleteTrafficMonitorCmd;1 listTrafficMonitors=com.cloud.api.commands.ListTrafficMonitorsCmd;1 -####Netapp integration commands -createVolumeOnFiler=com.cloud.api.commands.netapp.CreateVolumeOnFilerCmd;15 -destroyVolumeOnFiler=com.cloud.api.commands.netapp.DestroyVolumeOnFilerCmd;15 -listVolumesOnFiler=com.cloud.api.commands.netapp.ListVolumesOnFilerCmd;15 -createLunOnFiler=com.cloud.api.commands.netapp.CreateLunCmd;15 -destroyLunOnFiler=com.cloud.api.commands.netapp.DestroyLunCmd;15 -listLunsOnFiler=com.cloud.api.commands.netapp.ListLunsCmd;15 -associateLun=com.cloud.api.commands.netapp.AssociateLunCmd;15 -dissociateLun=com.cloud.api.commands.netapp.DissociateLunCmd;15 -createPool=com.cloud.api.commands.netapp.CreateVolumePoolCmd;15 -deletePool=com.cloud.api.commands.netapp.DeleteVolumePoolCmd;15 -modifyPool=com.cloud.api.commands.netapp.ModifyVolumePoolCmd;15 -listPools=com.cloud.api.commands.netapp.ListVolumePoolsCmd;15 + diff --git a/client/tomcatconf/netapp_commands.properties.in b/client/tomcatconf/netapp_commands.properties.in new file mode 100644 index 00000000000..21844035592 --- /dev/null +++ b/client/tomcatconf/netapp_commands.properties.in @@ -0,0 +1,33 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +### bitmap of permissions at the end of each classname, 1 = ADMIN, 2 = RESOURCE_DOMAIN_ADMIN, 4 = DOMAIN_ADMIN, 8 = USER +### Please standardize naming conventions to camel-case (even for acronyms). + +####Netapp integration commands +createVolumeOnFiler=com.cloud.api.commands.netapp.CreateVolumeOnFilerCmd;15 +destroyVolumeOnFiler=com.cloud.api.commands.netapp.DestroyVolumeOnFilerCmd;15 +listVolumesOnFiler=com.cloud.api.commands.netapp.ListVolumesOnFilerCmd;15 +createLunOnFiler=com.cloud.api.commands.netapp.CreateLunCmd;15 +destroyLunOnFiler=com.cloud.api.commands.netapp.DestroyLunCmd;15 +listLunsOnFiler=com.cloud.api.commands.netapp.ListLunsCmd;15 +associateLun=com.cloud.api.commands.netapp.AssociateLunCmd;15 +dissociateLun=com.cloud.api.commands.netapp.DissociateLunCmd;15 +createPool=com.cloud.api.commands.netapp.CreateVolumePoolCmd;15 +deletePool=com.cloud.api.commands.netapp.DeleteVolumePoolCmd;15 +modifyPool=com.cloud.api.commands.netapp.ModifyVolumePoolCmd;15 +listPools=com.cloud.api.commands.netapp.ListVolumePoolsCmd;15