Skip to content

Commit

Permalink
#58: generate install scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
ypujante committed Jul 11, 2013
1 parent 6e60354 commit 83e7f3b
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ import org.linkedin.util.codec.HexaCodec
import org.linkedin.util.codec.OneWayCodec
import org.linkedin.util.codec.OneWayMessageDigestCodec
import org.linkedin.util.io.resource.Resource
import org.linkedin.util.reflect.ReflectUtils
import org.pongasoft.glu.provisioner.core.metamodel.AgentCliMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.AgentMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.CliMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.ConsoleCliMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.ConsoleMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.GluMetaModel
Expand Down Expand Up @@ -70,6 +72,105 @@ public class GluPackager
return packagedArtifacts
}

void generateInstallScripts(boolean generateInstallAllScript)
{
def installAllScript = []

[
(ZooKeeperMetaModel.class): "zookeepers",
(AgentMetaModel.class): "agents",
(ConsoleMetaModel.class): "consoles",
(AgentCliMetaModel.class): "agent-cli",
(ConsoleCliMetaModel.class): "console-cli",
].each { Class<? extends CliMetaModel> metaModelClass, String name ->

def installScript = []

installScript << ("#" * 20) + " [${name}] " + ("#" * 20)
buildInstallCommands(metaModelClass, installScript)
installScript << "#" * 20

generateInstallScript("install-${name}.sh", installScript)

installAllScript.addAll(installScript)
}

if(generateInstallAllScript)
generateInstallScript("install-all.sh", installAllScript)
}

protected Resource generateInstallScript(String name, def lines)
{
def content = """#!/bin/bash
if [ -z "\$SCP_CMD" ]; then
SCP_CMD="scp"
fi
if [ -z "\$SCP_OPTIONS" ]; then
SCP_OPTIONS="-r"
fi
if [ -z "\$SCP_USER" ]; then
SCP_USER=\$USER
fi
${lines.join('\n')}
"""
def installScript = shell.saveContent(outputFolder.createRelative("bin/${name}"), content)
shell.chmodPlusX(installScript)

log.info "Generated install script ${installScript.file.canonicalPath}"

return installScript
}

/**
* Build install commands
*/
protected <T extends CliMetaModel> void buildInstallCommands(Class<T> metaModelClass,
def installScript)
{
filter(packagedArtifacts, metaModelClass).each { T metaModel, PackagedArtifact pa ->
installScript << buildInstallCommand(metaModel, pa)
}
}

/**
* Build a single install command
*/
protected String buildInstallCommand(CliMetaModel cli, PackagedArtifact artifact)
{
if(artifact.host)
{
if(cli.install?.path)
{
"\$SCP_CMD \$SCP_OPTIONS \"${artifact.location.file.canonicalPath}\" \"\$SCP_USER@${artifact.host}:${cli.install.path}\""
}
else
{
"# manually install ${artifact.location.file.canonicalPath} on host ${artifact.host}"
}
}
else
{
"# manually install ${artifact.location.file.canonicalPath}"
}

}

/**
* Filter the map by class
*/
protected <T extends MetaModel> Map<T, PackagedArtifact> filter(Map<MetaModel, PackagedArtifact> artifacts,
Class<T> metaModelClass)
{
artifacts.findAll {k, v ->
ReflectUtils.isSubClassOrInterfaceOf(k.getClass(), metaModelClass)
} as Map<T, PackagedArtifact>
}

void packageAgents()
{
def checksums = [:]
Expand Down Expand Up @@ -203,8 +304,7 @@ public class GluPackager

packagedArtifacts.putAll(packager.createPackages())

if(!dryMode)
println "Generated agent-cli package ${packagedArtifacts[agentCliMetaModel].location}"
displayPackagedArtifact(agentCliMetaModel, "agent cli package")
}

protected void packageConsoleCli()
Expand All @@ -223,8 +323,7 @@ public class GluPackager

packagedArtifacts.putAll(packager.createPackages())

if(!dryMode)
println "Generated console-cli package ${packagedArtifacts[consoleCliMetaModel].location}"
displayPackagedArtifact(consoleCliMetaModel, "console cli package")
}

protected PackagerContext createPackagerContext()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,10 @@ import org.linkedin.groovy.util.log.JulToSLF4jBridge
import org.linkedin.util.clock.Timespan
import org.linkedin.util.io.resource.FileResource
import org.linkedin.util.io.resource.Resource
import org.linkedin.util.reflect.ReflectUtils
import org.linkedin.zookeeper.cli.commands.UploadCommand
import org.linkedin.zookeeper.client.ZKClient
import org.pongasoft.glu.provisioner.core.metamodel.AgentCliMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.AgentMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.CliMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.ConsoleCliMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.ConsoleMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.GluMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.MetaModel
import org.pongasoft.glu.provisioner.core.metamodel.ZooKeeperClusterMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.ZooKeeperMetaModel
import org.pongasoft.glu.provisioner.core.metamodel.impl.builder.GluMetaModelBuilder
import org.slf4j.Logger
import org.slf4j.LoggerFactory
Expand Down Expand Up @@ -273,83 +265,17 @@ setup.sh -Z <meta-model>+ // configure ZooKeeper clusters (step 3)
packager.packageConsoles()
if(Config.getOptionalBoolean(config, 'zookeeper-clusters-only', false))
packager.packageZooKeeperClusters()
}
else
{
Map<MetaModel, PackagedArtifact> packagedArtifacts = packager.packageAll()

log.info "All distributions generated successfully."

def installScript = []

[
ZooKeeperMetaModel,
AgentMetaModel,
ConsoleMetaModel,
AgentCliMetaModel,
ConsoleCliMetaModel,
].each { Class<? extends CliMetaModel> metaModelClass ->
installScript << ("#" * 20) + " [${metaModelClass.simpleName - 'MetaModel'}s] " + ("#" * 20)
buildInstallCommands(packagedArtifacts, metaModelClass, installScript)
installScript << "#" * 20
}

log.info """Install script ....
#!/bin/bash
SCP_OPTIONS="-R"
SCP_USER="${System.getProperty('user.name')}"

${installScript.join('\n')}
"""
}
}

/**
* Build install commands
*/
protected <T extends CliMetaModel> void buildInstallCommands(Map<MetaModel, PackagedArtifact> packagedArtifacts,
Class<T> metaModelClass,
def installScript)
{
filter(packagedArtifacts, metaModelClass).each { T metaModel, PackagedArtifact pa ->
installScript << buildInstallCommand(metaModel, pa)
}
}

/**
* Build a single install command
*/
protected String buildInstallCommand(CliMetaModel cli, PackagedArtifact artifact)
{
if(artifact.host)
{
if(cli.install?.path)
{
"scp \$SCP_OPTIONS \"${artifact.location.file.canonicalPath}\" \"\$SCP_USER@${artifact.host}:${cli.install.path}\""
}
else
{
"# manually install ${artifact.location.file.canonicalPath} on host ${artifact.host}"
}
packager.generateInstallScripts(false)
}
else
{
"# manually install ${artifact.location.file.canonicalPath}"
}
packager.packageAll()

}
packager.generateInstallScripts(true)

/**
* Filter the map by class
*/
protected <T extends MetaModel> Map<T, PackagedArtifact> filter(Map<MetaModel, PackagedArtifact> artifacts,
Class<T> metaModelClass)
{
artifacts.findAll {k, v ->
ReflectUtils.isSubClassOrInterfaceOf(k.getClass(), metaModelClass)
} as Map<T, PackagedArtifact>
log.info "All distributions generated successfully."
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public abstract class BasePackagerTest extends GroovyTestCase

public static final String GLU_VERSION = 'g.v.0'
public static final String ZOOKEEPER_VERSION = 'z.v.1'
public static final String JETTY_VERSION = "j.v.2"

public static final String DEFAULT_KEYS = """
keys: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ import org.pongasoft.glu.provisioner.core.metamodel.ConsoleMetaModel
* @author yan@pongasoft.com */
public class TestConsoleServerPackager extends BasePackagerTest
{
public static final String JETTY_VERSION = "j.v.2"

public void testTutorialModel()
{
ShellImpl.createTempShell { Shell shell ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2013 Yan Pujante
*
* Licensed 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 test.setup

import org.linkedin.glu.groovy.utils.shell.Shell
import org.linkedin.glu.groovy.utils.shell.ShellImpl
import org.pongasoft.glu.packaging.setup.ConsoleCliPackager
import org.pongasoft.glu.packaging.setup.GluPackager
import org.pongasoft.glu.packaging.setup.PackagedArtifact

import java.nio.file.Files

/**
* @author yan@pongasoft.com */
public class TestGluPackager extends BasePackagerTest
{
public void testInstallScripts()
{
ShellImpl.createTempShell { Shell shell ->

def packagesRoot = shell.mkdirs("/packages")

[
"org.linkedin.zookeeper-server-${ZOOKEEPER_VERSION}",
"org.linkedin.glu.agent-server-${GLU_VERSION}",
"org.linkedin.glu.console-server-${GLU_VERSION}",
"org.linkedin.glu.agent-cli-${GLU_VERSION}",
"org.linkedin.glu.console-cli-${GLU_VERSION}"
].each { String pkgName ->
def inputPackage = shell.mkdirs("/packages/${pkgName}")
shell.saveContent(inputPackage.createRelative('README.md'), "this is the readme")
}

// agent-server
shell.saveContent("/packages/org.linkedin.glu.agent-server-${GLU_VERSION}/version.txt",
GLU_VERSION)

// console-server
def jettyDistribution = "jetty-distribution-${JETTY_VERSION}"
shell.mkdirs("/packages/org.linkedin.glu.console-server-${GLU_VERSION}/${jettyDistribution}")

def packager = new GluPackager(shell: shell,
configsRoots: copyConfigs(shell.toResource('/configs')),
packagesRoot: packagesRoot,
outputFolder: shell.mkdirs('/out'),
keysRoot: keysRootResource,
gluMetaModel: testModel,
dryMode: false)

packager.packageAll()

packager.generateInstallScripts(true)

shell.ls('/out/bin').each { def r ->
assertTrue(Files.isExecutable(r.file.toPath()))
}

// make sure
def expectedResources =
[
"/install-agents.sh": FILE,
"/install-consoles.sh": FILE,
"/install-zookeepers.sh": FILE,
"/install-agent-cli.sh": FILE,
"/install-console-cli.sh": FILE,
"/install-all.sh": FILE,
]

checkPackageContent(expectedResources, shell.toResource('/out/bin'))
}
}
}

0 comments on commit 83e7f3b

Please sign in to comment.