Kuali Rice Development
  1. Kuali Rice Development
  2. KULRICE-2764

Deploy Rice standalone server to our test environments

    Details

    • Similar issues:
      KULRICE-13134Create Rice 2.5 environments for testing client/server deployments
      KULRICE-2815 Deploy CAS-enabled Rice standalone server to test environment
      KULRICE-2816Deploy Rice standalone server with Recipe sample app to test environments
      KULRICE-2932rice-config.xml for deployment of standalone server
      KULRICE-1475Deploy a test Rice Standalone application to a test environment
      KULRICE-5665Implement the ability to run rice sample app as a seperate application integrated with the Rice Standalone Server, put process in place to automatically deploy to a test environment using CI
      KULRICE-11774Create performance test environment: Standalone Server Oracle, Rice Sample App Client Oracle, KRAD Client Oracle
      KULRICE-11775Create performance test environment: Standalone Server MySQL, KRAD Client MySQL, Rice Sample App Client MySQL
      KULRICE-4656Maintenance/Transactional screen's images are being served from standalone rice server
      KULRICE-3157Deploy new kuali-cas server to test environments

      Description

      Here are the notes from our meeting today regarding this:

      • Update the build.xml in rice and add dist-external and dist-war
        • generated war file from dist-war will get automatically deployed to wsa131 via the j2ee_deploy_war script on wsa123
      • We need to update do-daily-updates.sh in kul-cfg-envs to add "kupdate" statements in our script so that we execute the daily update
        • Initially, let's start with just the STG environment and use the RICESTG database
        • part of the kupdate script should be able to create the RICESTG database using our nightly database export
        • so our first environments will use the STG database
      • Update /usr/local/rice/rice-config.xml to reflect configuration changes in rice 1.0, verify files in /usr/local/rice/stg/...
      • at any point during the day we can probably just run do-daily-updates.sh to test an initial deployment
        • IMPORTANT: no two projects can run their updates scripts at the same time
      • We also need to update (and move to KULRICE) the documentation at the following location:
        https://test.kuali.org/confluence/display/KULFOUND/Kuali+Rice+Test+Environments

        Issue Links

          Activity

          Hide
          Casey Boettcher (Inactive) added a comment - - edited

          Added "kupdate stg standard true true Oracle9i" to do-daily-updates.sh
          Copied dist-external and dist-war to ant file, sans init target for properties (presumably these are passed in when called by kant).
          Changed package name of Oracle9iPlatform in stg-rice-config.xml to point to correct class.

            • Do you really mean RICESTG for the DB schema? Are you sure you don't want to use RICE094STG? I don't think the former conforms to bash script naming conventions for schemas (though I think it can be worked around by passing an empty string for the second argument to kupdate)
          Show
          Casey Boettcher (Inactive) added a comment - - edited Added "kupdate stg standard true true Oracle9i" to do-daily-updates.sh Copied dist-external and dist-war to ant file, sans init target for properties (presumably these are passed in when called by kant). Changed package name of Oracle9iPlatform in stg-rice-config.xml to point to correct class. Do you really mean RICESTG for the DB schema? Are you sure you don't want to use RICE094STG? I don't think the former conforms to bash script naming conventions for schemas (though I think it can be worked around by passing an empty string for the second argument to kupdate)
          Hide
          Eric Westfall added a comment -

          When you say you copied dist-external and dist-war, what do you mean? Where did you copy them from? We probably need to write our own versions of those so that they build and package the Rice standalone war properly.

          As for the RICESTG db, yes I think that's the name we want since we will only have one particular version of Rice deployed to STG at a time. Is this going to cause issues with our deployment scripts?

          Show
          Eric Westfall added a comment - When you say you copied dist-external and dist-war, what do you mean? Where did you copy them from? We probably need to write our own versions of those so that they build and package the Rice standalone war properly. As for the RICESTG db, yes I think that's the name we want since we will only have one particular version of Rice deployed to STG at a time. Is this going to cause issues with our deployment scripts?
          Hide
          Casey Boettcher (Inactive) added a comment - - edited

          I'll modify the ant targets as necessary.

          The script breaks when the following occurs:

          In do-daily-updates.sh, kupdate is called (the shared-functions file having been sourced).
          kupdate generates a properties file called, appropriately, "generated-build.properties" by calling ksetprops
          kupdate then calls kcheckout and then...
          kupdate calls kant
          kant calls ant with a target of import, passing it the following argument: -Dgenerated.properties.file=/home/j2eemgr/kuali/generated-build.properties
          ant uses the default build file in kul-cfg-envs and executes the import target which then calls other ant targets:
          <target name="init-base-properties">
          <property file="$

          {generated.properties.file}

          " />
          <property file="$

          {application.working.directory}

          /build.properties" />
          <property file="$

          {working.directory}

          /build.properties" />
          <property file="$

          {application.deploy.directory}

          /build.properties" />
          <condition property="import.into.mysql">
          <equals arg1="$

          {datasource.ojb.platform}

          " arg2="MySQL" />
          </condition>
          </target>

          <!-- note: init-mysql-properties depends upon init-base-properties -->
          <target name="init-properties" depends="init-mysql-properties">
          <property file="$

          {oracle.impex.properties.file}

          " />
          <loadfile property="impex-build.properties" srcfile="$

          {impex.properties.file.template}

          "><filterchain><expandproperties /></filterchain></loadfile>
          <delete file="$

          {impex.properties.file}" />
          <echo message="${impex-build.properties}" file="${impex.properties.file}

          " />
          </target>

          <!-- note: create-mysql user depends upon init-properties -->
          <target name="import" depends="create-mysql-user">
          <ant antfile="$

          {impex.build.file}" target="empty-schema" inheritall="false" />
          <ant antfile="${impex.build.file}

          " target="import" inheritall="false" />
          <delete file="$

          {log.file}

          " />
          </target>

          So, at this point, I"m not really sure what the state of the environment is, or how many properties files have bee read. Let's just assume that generated-build.properties and impex-build.properties are in the mix.

          ant then invokes itself, only with the impex build file of the kul-cfg-dbs project and calls empty-schema....

          <target name="oracle-empty-schema" depends="inittasks">
          <adminsql sql="$

          {oracle.empty.schema.commands}

          " />
          </target>

          adminsql executes the following:
          "DECLARE temp NUMBER; BEGIN temp := kulcfgusr.kuluser_maint_pk.recreate_user( '<generated-user-name>' ); END;"

          Where <generated-user-name> is a string formed from the $DATABASE_APPLICATION_CODE variable in 0.9.4-settings file. Setting this to "rice" and not "rice094" (to make use of the existing RICESTG schema) is not feasible because the same generated user name is used to export data from the RICE094DBA schema (not "RICEDBA").

          Show
          Casey Boettcher (Inactive) added a comment - - edited I'll modify the ant targets as necessary. The script breaks when the following occurs: In do-daily-updates.sh, kupdate is called (the shared-functions file having been sourced). kupdate generates a properties file called, appropriately, "generated-build.properties" by calling ksetprops kupdate then calls kcheckout and then... kupdate calls kant kant calls ant with a target of import, passing it the following argument: -Dgenerated.properties.file=/home/j2eemgr/kuali/generated-build.properties ant uses the default build file in kul-cfg-envs and executes the import target which then calls other ant targets: <target name="init-base-properties"> <property file="$ {generated.properties.file} " /> <property file="$ {application.working.directory} /build.properties" /> <property file="$ {working.directory} /build.properties" /> <property file="$ {application.deploy.directory} /build.properties" /> <condition property="import.into.mysql"> <equals arg1="$ {datasource.ojb.platform} " arg2="MySQL" /> </condition> </target> <!-- note: init-mysql-properties depends upon init-base-properties --> <target name="init-properties" depends="init-mysql-properties"> <property file="$ {oracle.impex.properties.file} " /> <loadfile property="impex-build.properties" srcfile="$ {impex.properties.file.template} "><filterchain><expandproperties /></filterchain></loadfile> <delete file="$ {impex.properties.file}" /> <echo message="${impex-build.properties}" file="${impex.properties.file} " /> </target> <!-- note: create-mysql user depends upon init-properties --> <target name="import" depends="create-mysql-user"> <ant antfile="$ {impex.build.file}" target="empty-schema" inheritall="false" /> <ant antfile="${impex.build.file} " target="import" inheritall="false" /> <delete file="$ {log.file} " /> </target> So, at this point, I"m not really sure what the state of the environment is, or how many properties files have bee read. Let's just assume that generated-build.properties and impex-build.properties are in the mix. ant then invokes itself, only with the impex build file of the kul-cfg-dbs project and calls empty-schema.... <target name="oracle-empty-schema" depends="inittasks"> <adminsql sql="$ {oracle.empty.schema.commands} " /> </target> adminsql executes the following: "DECLARE temp NUMBER; BEGIN temp := kulcfgusr.kuluser_maint_pk.recreate_user( '<generated-user-name>' ); END;" Where <generated-user-name> is a string formed from the $DATABASE_APPLICATION_CODE variable in 0.9.4-settings file. Setting this to "rice" and not "rice094" (to make use of the existing RICESTG schema) is not feasible because the same generated user name is used to export data from the RICE094DBA schema (not "RICEDBA").
          Hide
          Casey Boettcher (Inactive) added a comment -

          If you'd like me to create a RICE094STG schema, I've got everything in place to do that, apart from the tablespace.

          The problem with creating a tablespace is that the package currently on the server seems to be at odds with all the other RICE users that have been created prior to this point. The following in the KULUSER_MAINT_PK package that is currently installed on the esdbk02 server (leading comment is not mine):

          – FOR NOW THIS NEEDS TO BE CHANGED TO TRUE FOR THE KUALI FOUNDATION DAILY UPDATE PROCESS
          UseUserNameForTablespace CONSTANT BOOLEAN := TRUE;
          <cut>
          – create user
          CreateUserDDL := 'CREATE USER '||UserID||' IDENTIFIED BY ';
          IF PasswordHash THEN
          CreateUserDDL := CreateUserDDL||'VALUES '''||UserPW||''' ';
          ELSE
          CreateUserDDL := CreateUserDDL||UserPW||' ';
          END IF;
          IF UseUserNameForTablespace THEN
          CreateUserDDL := CreateUserDDL||'DEFAULT TABLESPACE '||UserID;
          ELSE
          CreateUserDDL := CreateUserDDL||'DEFAULT TABLESPACE '||PrimaryTablespace;
          END IF;

          Maybe I'm reading the PL/SQL wrong, but this would seemingly create a RICE094STG tablespace. Were UseUserNameForTablespace 'FALSE', I wouldn't have to create a tablespace for the RICE094STG user – it would use a default. Note that all other Rice-related users (incl RICESTG) use a default tablespace of "KUALI_TABLES"

          Let me know how you'd like to proceed. If we use RICESTG, I think we'll have to alter something outside of Rice settings/scripting in kul-cfg-envs. If we use RICE094STG, then we would either need to create a tablespace for that user or alter the maintenance package on the server (note that the package body in the repo has the variable in question set to FALSE).

          Show
          Casey Boettcher (Inactive) added a comment - If you'd like me to create a RICE094STG schema, I've got everything in place to do that, apart from the tablespace. The problem with creating a tablespace is that the package currently on the server seems to be at odds with all the other RICE users that have been created prior to this point. The following in the KULUSER_MAINT_PK package that is currently installed on the esdbk02 server (leading comment is not mine): – FOR NOW THIS NEEDS TO BE CHANGED TO TRUE FOR THE KUALI FOUNDATION DAILY UPDATE PROCESS UseUserNameForTablespace CONSTANT BOOLEAN := TRUE; <cut> – create user CreateUserDDL := 'CREATE USER '||UserID||' IDENTIFIED BY '; IF PasswordHash THEN CreateUserDDL := CreateUserDDL||'VALUES '''||UserPW||''' '; ELSE CreateUserDDL := CreateUserDDL||UserPW||' '; END IF; IF UseUserNameForTablespace THEN CreateUserDDL := CreateUserDDL||'DEFAULT TABLESPACE '||UserID; ELSE CreateUserDDL := CreateUserDDL||'DEFAULT TABLESPACE '||PrimaryTablespace; END IF; Maybe I'm reading the PL/SQL wrong, but this would seemingly create a RICE094STG tablespace. Were UseUserNameForTablespace 'FALSE', I wouldn't have to create a tablespace for the RICE094STG user – it would use a default. Note that all other Rice-related users (incl RICESTG) use a default tablespace of "KUALI_TABLES" Let me know how you'd like to proceed. If we use RICESTG, I think we'll have to alter something outside of Rice settings/scripting in kul-cfg-envs. If we use RICE094STG, then we would either need to create a tablespace for that user or alter the maintenance package on the server (note that the package body in the repo has the variable in question set to FALSE).
          Hide
          Casey Boettcher (Inactive) added a comment -

          Decided to go with tablespace per schema. Have asked IU DBA team to advise on sane tablespace DDL and amount of space on esdbk02 machine.

          >The Database Administration (DBA) team has received your message (IM683228). Priority is currently being assigned.
          >
          >Please include the incident number in any follow up communications.
          >
          >Thank you for using our services.
          >
          >DBA TEAM
          >Indiana University

          Show
          Casey Boettcher (Inactive) added a comment - Decided to go with tablespace per schema. Have asked IU DBA team to advise on sane tablespace DDL and amount of space on esdbk02 machine. >The Database Administration (DBA) team has received your message (IM683228). Priority is currently being assigned. > >Please include the incident number in any follow up communications. > >Thank you for using our services. > >DBA TEAM >Indiana University
          Hide
          Casey Boettcher (Inactive) added a comment -

          Deploy failed last night with error:

                  • begin error log *****
                    <snip>
                    20090313.00.45.02: executing command: /usr/local/ant/bin/ant -Dgenerated.properties.file=/home/j2eemgr/kuali/generated-build.properties -f /home/j2eemgr/kuali/build.xml dist-war
                    Buildfile: /home/j2eemgr/kuali/build.xml

          init-base-properties:

          init-mysql-properties:

          init-properties:
          [delete] Deleting: /home/j2eemgr/impex-build.properties

          dist-ant:
          Trying to override old definition of task maven

          init:
          [echo] The Kuali Rice version is 0.9.4-SNAPSHOT
          [echo] [Dependency

          {groupId=org.springframework, artifactId=spring-aop, version=2.0.4, type=jar}

          , Dependency

          {groupId=org.springframework, artifactId=spring-beans, version=2.0.4, type=jar}

          , Dependency {groupId=org.springframework, <snip>
          [mkdir] Created dir: /opt/ears/stg/kr/rice/target/ant-build

          install-rice-jars:
          [java] [INFO] Scanning for projects...
          [java] [INFO] Reactor build order:
          [java] [INFO] Kuali Rice
          [java] [INFO] Kuali Rice API
          [java] [INFO] Kuali Rice Implementation
          [java] [INFO] Kuali Rice Web
          [java] [INFO] ksb
          [java] [INFO] kcb
          [java] [INFO] kns
          [java] [INFO] kim
          [java] [INFO] kew
          [java] [INFO] ken
          <snip>
          [java] [INFO] [compiler:compile]
          [java] [INFO] Compiling 215 source files to /opt/ears/stg/kr/rice/api/target/classes
          [java] [INFO] ------------------------------------------------------------------------
          [java] [ERROR] BUILD ERROR
          [java] [INFO] ------------------------------------------------------------------------
          [java] [INFO] Fatal error compiling

          [java] Embedded error: Error while executing the external compiler.
          [java] java.io.IOException: javac: not found
          [java] [INFO] ------------------------------------------------------------------------
          [java] [INFO] For more information, run Maven with the -e switch
          [java] [INFO] ------------------------------------------------------------------------
          [java] [INFO] Total time: 9 seconds
          [java] [INFO] Finished at: Fri Mar 13 00:45:17 EDT 2009
          [java] [INFO] Final Memory: 13M/69M
          [java] [INFO] ------------------------------------------------------------------------

          BUILD FAILED
          /home/j2eemgr/kuali/build.xml:50: The following error occurred while executing this line:
          /opt/ears/stg/kr/rice/build.xml:134: The following error occurred while executing this line:
          /opt/ears/stg/kr/rice/build.xml:293: Java returned: 1

                  • end error log *****

          This is part of the kupdate process initiated in do-daily-updates.sh. kupdate calls 'kant dist-war' which invokes the dist-war target in the build file of the kul-cfg-envs project.

          This target (dist-war) then invokes dist-ant in the same file. dist-ant calls "ant dist"; that is you have an ant process calling itself with a different build file, to wit, that of the rice project. In the error log output above, you'll see "Trying to override old definition of task maven". This string doesn't exist in a kuali project – it's ant reporting that it's attempting to overwrite an existing macro definition, one that's already defined in the kul-cfg-envs build file. What's the macro called?

          "maven"

          A long story shorter, "ant dist" depends upon dist-server, which depends on prepare-lib which calls install-rice-jars, which calls the maven macro.

          I'd like to set the maven.build flag to true and have the dist-war target in kul-cfg-envs invoke its own maven macro definition via dist-maven. This will have to wait, however, as KFS is running its weekly build today.

          Show
          Casey Boettcher (Inactive) added a comment - Deploy failed last night with error: begin error log ***** <snip> 20090313.00.45.02: executing command: /usr/local/ant/bin/ant -Dgenerated.properties.file=/home/j2eemgr/kuali/generated-build.properties -f /home/j2eemgr/kuali/build.xml dist-war Buildfile: /home/j2eemgr/kuali/build.xml init-base-properties: init-mysql-properties: init-properties: [delete] Deleting: /home/j2eemgr/impex-build.properties dist-ant: Trying to override old definition of task maven init: [echo] The Kuali Rice version is 0.9.4-SNAPSHOT [echo] [Dependency {groupId=org.springframework, artifactId=spring-aop, version=2.0.4, type=jar} , Dependency {groupId=org.springframework, artifactId=spring-beans, version=2.0.4, type=jar} , Dependency {groupId=org.springframework, <snip> [mkdir] Created dir: /opt/ears/stg/kr/rice/target/ant-build install-rice-jars: [java] [INFO] Scanning for projects... [java] [INFO] Reactor build order: [java] [INFO] Kuali Rice [java] [INFO] Kuali Rice API [java] [INFO] Kuali Rice Implementation [java] [INFO] Kuali Rice Web [java] [INFO] ksb [java] [INFO] kcb [java] [INFO] kns [java] [INFO] kim [java] [INFO] kew [java] [INFO] ken <snip> [java] [INFO] [compiler:compile] [java] [INFO] Compiling 215 source files to /opt/ears/stg/kr/rice/api/target/classes [java] [INFO] ------------------------------------------------------------------------ [java] [ERROR] BUILD ERROR [java] [INFO] ------------------------------------------------------------------------ [java] [INFO] Fatal error compiling [java] Embedded error: Error while executing the external compiler. [java] java.io.IOException: javac: not found [java] [INFO] ------------------------------------------------------------------------ [java] [INFO] For more information, run Maven with the -e switch [java] [INFO] ------------------------------------------------------------------------ [java] [INFO] Total time: 9 seconds [java] [INFO] Finished at: Fri Mar 13 00:45:17 EDT 2009 [java] [INFO] Final Memory: 13M/69M [java] [INFO] ------------------------------------------------------------------------ BUILD FAILED /home/j2eemgr/kuali/build.xml:50: The following error occurred while executing this line: /opt/ears/stg/kr/rice/build.xml:134: The following error occurred while executing this line: /opt/ears/stg/kr/rice/build.xml:293: Java returned: 1 end error log ***** This is part of the kupdate process initiated in do-daily-updates.sh. kupdate calls 'kant dist-war' which invokes the dist-war target in the build file of the kul-cfg-envs project. This target (dist-war) then invokes dist-ant in the same file. dist-ant calls "ant dist"; that is you have an ant process calling itself with a different build file, to wit, that of the rice project. In the error log output above, you'll see "Trying to override old definition of task maven". This string doesn't exist in a kuali project – it's ant reporting that it's attempting to overwrite an existing macro definition, one that's already defined in the kul-cfg-envs build file. What's the macro called? "maven" A long story shorter, "ant dist" depends upon dist-server, which depends on prepare-lib which calls install-rice-jars, which calls the maven macro. I'd like to set the maven.build flag to true and have the dist-war target in kul-cfg-envs invoke its own maven macro definition via dist-maven. This will have to wait, however, as KFS is running its weekly build today.
          Hide
          Casey Boettcher (Inactive) added a comment -

          Files related to KULRICE-2764

          Show
          Casey Boettcher (Inactive) added a comment - Files related to KULRICE-2764
          Hide
          Eric Westfall added a comment -

          Casey, that sounds like a good idea if we can get that to work. A couple of things we need to consider though:

          1) dist-server is currently overlaying files from web/src/main/config into the standalone war, this includes things like license acknowledgements and an updated index.html that doesn't include the sample application links. We'll need to try and figure out how to do something similar in maven
          2) dist-server is executing a replacement of "dev" with the environment code in web.xml in the WAR file. We will need to figure out how to do this as well so that the packaged web.xml has the correct environment code.

          Show
          Eric Westfall added a comment - Casey, that sounds like a good idea if we can get that to work. A couple of things we need to consider though: 1) dist-server is currently overlaying files from web/src/main/config into the standalone war, this includes things like license acknowledgements and an updated index.html that doesn't include the sample application links. We'll need to try and figure out how to do something similar in maven 2) dist-server is executing a replacement of "dev" with the environment code in web.xml in the WAR file. We will need to figure out how to do this as well so that the packaged web.xml has the correct environment code.
          Hide
          Casey Boettcher (Inactive) added a comment -

          More info on the problem reported in this comment: https://test.kuali.org/jira/browse/KULRICE-2764?focusedCommentId=119846#action_119846

          Both j2eemgr and tomcat users have javac on their paths, both on wsa123 and wsa131

          I've forced the PATH environment variable to include /usr/local/java/bin for the forked JVM created by the maven macro in rice's build.xml. I've also turned on debugging and included an echo task that will hopefully echo the true PATH used by the forked JVM, though, on reflection, the output might not accurately reflect its environment. Does a JVM inherit the environment from which it's spawned?

          Note that, even were I to want to set the maven.build flag (as I suggested at the end of the referenced comment) I could not have done so, because of the way this system of scripts is set up and because of the logic behind ant's if/unless target attributes. In order to have maven.build in the generated ant properties file, I would have to alter the ksetprops function to echo this into the generated file from the rice settings file. But this would occur for every project (KC, KFS and rice). That's not a problem, since I could set a default of "false" in the shared-properties file and a value of "true" in the Rice settings file. That would be superfluous code, however, because regardless of the value maven.build is set to, the dist-maven target would be run instead of dist-ant for every project. In ant, "if" and "unless" check for the existence of a property and disregard its value entirely.

          Show
          Casey Boettcher (Inactive) added a comment - More info on the problem reported in this comment: https://test.kuali.org/jira/browse/KULRICE-2764?focusedCommentId=119846#action_119846 Both j2eemgr and tomcat users have javac on their paths, both on wsa123 and wsa131 I've forced the PATH environment variable to include /usr/local/java/bin for the forked JVM created by the maven macro in rice's build.xml. I've also turned on debugging and included an echo task that will hopefully echo the true PATH used by the forked JVM, though, on reflection, the output might not accurately reflect its environment. Does a JVM inherit the environment from which it's spawned? Note that, even were I to want to set the maven.build flag (as I suggested at the end of the referenced comment) I could not have done so, because of the way this system of scripts is set up and because of the logic behind ant's if/unless target attributes. In order to have maven.build in the generated ant properties file, I would have to alter the ksetprops function to echo this into the generated file from the rice settings file. But this would occur for every project (KC, KFS and rice). That's not a problem, since I could set a default of "false" in the shared-properties file and a value of "true" in the Rice settings file. That would be superfluous code, however, because regardless of the value maven.build is set to, the dist-maven target would be run instead of dist-ant for every project. In ant, "if" and "unless" check for the existence of a property and disregard its value entirely.
          Hide
          Casey Boettcher (Inactive) added a comment -

          Potential further work would involve understanding why PATH had to be set explicitly in 'maven' macro in order to avoid javac FileNotFound error

          Show
          Casey Boettcher (Inactive) added a comment - Potential further work would involve understanding why PATH had to be set explicitly in 'maven' macro in order to avoid javac FileNotFound error
          Hide
          Eric Westfall added a comment -

          Bulk change of all Rice 1.0 issues to closed after public release.

          Show
          Eric Westfall added a comment - Bulk change of all Rice 1.0 issues to closed after public release.

            People

            • Assignee:
              Casey Boettcher (Inactive)
              Reporter:
              Eric Westfall
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Time Tracking

                Estimated:
                Original Estimate - 2 days, 4 hours
                2d 4h
                Remaining:
                Remaining Estimate - 2 days, 4 hours
                2d 4h
                Logged:
                Time Spent - Not Specified
                Not Specified

                  Structure Helper Panel