`
sillycat
  • 浏览: 2539556 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

DevOps(4)Build RPM for CentOS

 
阅读更多

DevOps(4)Build RPM for CentOS

1. On CentOS

Install the RPM build ENV
>sudo yum install rpm-build
>sudo yum install gcc
>sudo yum install rpmdevtools
>sudo yum install rpmlint


2. On Ubuntu
>sudo apt-get install lintian
>sudo apt-get install fakeroot
>sudo apt-get install rpm


Error Message:
rpm:packageBin) java.io.IOException: Cannot run program "rpmbuild"

Solution:
Install the RPM build ENV
>sudo yum install rpm-build
>sudo yum install gcc
>sudo yum install rpmdevtools
>sudo yum install rpmlint

Error Message:
(localpoint-bridge-api-rpm/rpm:publish) java.io.IOException: destination file exists and overwrite == false

Solution:
I change the file 
>vi ~/.sbt/repositories 
[ivy] sbt.override.build.repos=true

But it does not work. I will check the artifactory side.

Error Message:
debian:genChanges) Cannot generate .changes file without a changelog

Solution:
Place a file changelog.txt in the project place will help.


Publish the RPM Build
>;project projectname; clean; project projectname-rpm; clean; rpm:publish

Package the PRM Build
>;project projectname; clean; project projectname-rpm; clean; rpm:packageBin

Package the Debian Build
>;project projectname; clean; project projectname-rpm; clean; debian:packageBin

3. Some Configuration in the Project Directory
I just do not plan to spend a lot of time on this right now. So I will just log the conf here.
build.properties
// 0.13.2 defaults to publishing ivy artifacts with overwrite = false, which we don't want to deal with yet
sbt.version=0.13.6

Build.scala
import sbt._
import Keys._
import com.typesafe.sbt.packager.Keys._
import scalariform.formatter.preferences._
import com.typesafe.sbt.SbtScalariform._
import spray.revolver.RevolverPlugin._

import org.sbtidea.SbtIdeaPlugin._


object ApplicationBuild extends Build {
  lazy val ourVersion = Process("git describe --match=[^(jenkins)].* --always --long").lines.head

  val akkaVersion = "2.2.0-RC1"

  val sprayVersion = "1.2-M8"

  val publishEnv = SettingKey[String]("publishEnv","artifact environment to publish to")

  override lazy val settings: Seq[Project.Setting[_]] =
    super.settings ++ Seq(
      scalaVersion := "2.10.3",
      version := ourVersion,
      organization  := "com.sillycat",
      resolvers := Seq(),
      externalResolvers := Seq(
        Resolver.defaultLocal,
        “sillycat Artifactory" at "http://repository.sillycat.com/artifactory/remote-repos"
      ),
      credentials += Credentials("Artifactory Realm", "repository.sillycat.com", "builder", “sillycat2011!"),
      publishTo := Some(“sillycat Artifactory Dev" at "http://repository.sillycat.com/artifactory/sillycat-dev/")
    )

  lazy val all = Project(id = "all",
    base = file(".")).
    aggregate(
      main,
      gerd,
      auth,
      util,
      localpointBridgeApi,
      migration,
      messageQueue,
      profilesSpark,
      localpointAuthCenter
    )

  /**
   Several projects have 2 ids, e.g. foo and foo-rpm
   The 1st is for ease of development, so that changes to guts are recognized without publishing.
   It depends on main, which will put guts on the classpath before libraryDependencies.
   The 2nd is specifically for building the rpm, and uses the same sourcetree as the project above.
   It doesnt use dependsOn; the guts jar is included from libraryDependencies,
   so guts must be published before the rpm can be built.
  */

  lazy val main = Project(id = "guts",
    base = file("guts")).
    dependsOn(util).
    settings(scalariformSettings ++ Revolver.settings ++ Seq(
      name := "guts",
      scalacOptions := Seq("-unchecked", "-deprecation", "-feature", "-encoding", "utf8"),
      publishEnv := "develop",
      libraryDependencies ++= Seq(
        // do not upgrade mysql connector, 5.1.27 broke hibernate
        "mysql" % "mysql-connector-java" % "5.1.26",
        "org.apache.cassandra" % "cassandra-all" % "1.2.8",
        "com.datastax.cassandra" % "cassandra-driver-core" % "1.0.3",
        //https://github.com/jorgeortiz85/scala-time
        "org.scalaj" % "scalaj-time_2.10.0-M7" % "0.6",
        "com.typesafe.slick" %% "slick" % "1.0.1",
        "com.typesafe.slick" %% "slick-testkit" % "1.0.1" % "test",
        "com.typesafe" % "config" % "1.0.0",
        "org.scalatest" % "scalatest_2.10" % "1.9.1",
        "io.spray" % "spray-json_2.10" % "1.2.3",
        "c3p0" % "c3p0" % "0.9.1.2",
        "com.typesafe" %% "scalalogging-slf4j" % "1.0.1",
        "com.esotericsoftware.kryo" % "kryo" % "2.21",
        "org.bouncycastle" % "bcprov-jdk16" % "1.46",
        "org.jasypt" % "jasypt" % "1.9.0",
        "com.google.guava" % "guava-parent" % "14.0.1",
        // this is needed for guava
        "com.google.code.findbugs" % "jsr305" % "2.0.1",
        "redis.clients" % "jedis" % "2.0.0",
        "org.apache.kafka" % "kafka_2.10" % "0.8.0",
        "org.msgpack" %% "msgpack-scala" % "0.6.8",
        "com.googlecode.flyway" % "flyway-core" % "2.2.1"
      ),
      fork := true,
      publishArtifact in Test := true,
      publishTo <<= publishEnv { (p: String) =>
        if(p == "master")
          Some(“sillycat Artifactory master" at "http://repository.sillycat.com/artifactory/sillycat-master")
        else if(p == "feature")
          Some(“sillycat Artifactory feature" at "http://repository.sillycat.com/artifactory/sillycat-feature")
        else if(p == "release")
          Some(“sillycat Artifactory release" at "http://repository.sillycat.com/artifactory/sillycat-release")
        else if(p == "maven")
          Some(Resolver.file("file",  new File(Path.userHome.absolutePath+"/.m2/repository")))
        else
          Some(“sillycat Artifactory dev" at "http://repository.sillycat.com/artifactory/sillycat-dev")
      }
    ): _*)

  lazy val auth = Project(id = "localpoint-auth",
    base = file("localpoint-auth")).
    dependsOn(main % "test->test;compile->compile").
    dependsOn(util).
    settings(scalariformSettings ++ Revolver.settings ++ Seq(
      name := "localpoint-auth",
      scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8"),
      libraryDependencies ++= Seq(
        "io.spray" % "spray-can" % sprayVersion,
        "io.spray" % "spray-routing" % sprayVersion,
        "io.spray" % "spray-testkit" % sprayVersion,
        "io.spray" % "spray-caching" % sprayVersion,
        "io.spray" % "spray-client" % sprayVersion,
        "com.typesafe.akka" %% "akka-actor" % akkaVersion,
        "com.typesafe.akka" %% "akka-testkit" % akkaVersion,
        "com.typesafe.akka" %% "akka-transactor" % akkaVersion
      ),
      fork := true
    ): _*)

  lazy val util = Project(id = "localpoint-auth-util",
    base = file("localpoint-auth-util")).
    settings(
      autoScalaLibrary := false,
      crossPaths := false
    )

  lazy val gerdSettings: Seq[Setting[_]] = scalariformSettings ++ Seq(
    name := "gerd",
    // gerd actually has more than one consumer, but this is the first one in the chain
    mainClass := Some("com.sillycat.gerd.EntryEventConsumer"),
    libraryDependencies ++= Seq(
      "log4j" % "log4j" % "1.2.17",
      "com.github.sgroschupf" % "zkclient" % "0.1",
      "com.yammer.metrics" % "metrics-core" % "2.2.0",
      "org.apache.kafka" % "kafka_2.10" % "0.8.0" intransitive()
    )
  )

  lazy val gerd = Project(id = "gerd",
    base = file("gerd")).
    dependsOn(main)

  lazy val gerdRpm = Project(id = "gerd-rpm",
    base = gerd.base).
    settings(gerdSettings ++ Packaging.settings ++ Packaging.server ++ Seq(
      target := file("gerd/target-rpm"),
      packageSummary := "Generalized Event Routing and Distribution (gerd)",
      packageDescription := "consumers that process device traffic events from kafka",
      publishTo := Packaging.rpmCalcPublishTo("gerd"),
      libraryDependencies += "com.sillycat" %% "guts" % ourVersion,
      ideaIgnoreModule := true,
      rpmPost := Some(Packaging.rpmCalcPostChown("gerd"))
    ): _*)

  lazy val localpointBridgeApiSettings: Seq[Setting[_]] =
    scalariformSettings ++ Revolver.settings ++
    Seq(
      name := "localpoint-bridge-api",
      mainClass := Some(“com.sillycat.localpoint.console.api.LocalpointBridgeAPIServer"),
      scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8"),
      libraryDependencies ++= Seq(
        "org.specs2" %% "specs2" % "1.13" % "test",
  "io.spray" % "spray-io" % sprayVersion,
  "io.spray" % "spray-can" % sprayVersion,
  "io.spray" % "spray-routing" % sprayVersion,
  "io.spray" % "spray-caching" % sprayVersion,
  "io.spray" % "spray-http" % sprayVersion,
  "io.spray" % "spray-testkit" % sprayVersion,
  "io.spray" % "spray-util" % sprayVersion,
  "io.spray" % "spray-client" % sprayVersion,
        "com.typesafe.akka" %% "akka-actor" % akkaVersion,
        "com.typesafe.akka" %% "akka-testkit" % akkaVersion,
        "com.typesafe.akka" %% "akka-transactor" % akkaVersion
      ),
      fork := true
    )

  lazy val localpointBridgeApi = {
    val dir = "localpoint-bridge-api"

    BuildInfo.write(dir,
      Process("git rev-parse HEAD").lines.head,
      Process("git rev-parse --abbrev-ref HEAD").lines.head,
      ourVersion)

    Project(id = "localpoint-bridge-api",
      base = file(dir)).
      dependsOn(auth).
      dependsOn(main % "test->test").
      dependsOn(messageQueue).
      settings(localpointBridgeApiSettings: _*)
  }

  lazy val localpointBridgeApiRpm = Project(id = "localpoint-bridge-api-rpm",
    base = localpointBridgeApi.base).
    settings(localpointBridgeApiSettings ++ Packaging.settings ++ Packaging.server ++ Seq(
      target := file("localpoint-bridge-api/target-rpm"),
      packageSummary := "localpoint bridge api",
      packageDescription := "localpoint bridge api for configuration of brand-specific settings",
      publishTo := Packaging.rpmCalcPublishTo("localpoint-bridge-api"),
      libraryDependencies ++= Seq(
        "com.sillycat" %% "localpoint-auth" % ourVersion,
        "com.sillycat" %% "message-queue" % ourVersion
      ),
      ideaIgnoreModule := true,
      rpmChangelogFile := Some("changelog.txt"),
      maintainer := "Carl <luohuazju@gmail.com>",
      rpmPost := Some(Packaging.rpmCalcPostChown("localpoint-bridge-api"))
    ): _*)

  lazy val migration = Project(id = "migration",
    base = file("migration")).
    dependsOn(main).
    settings(scalariformSettings ++ Seq(
      name := "migration",
      scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8")
    ): _*)

  lazy val messageQueueSettings: Seq[Setting[_]] = scalariformSettings ++ Seq(
    name := "message-queue",
    mainClass := Some("com.sillycat.messagequeue.Workers"),
    libraryDependencies ++= Seq(
      "com.rabbitmq" % "amqp-client" % "3.2.1",
      "net.jodah" % "lyra" % "0.3.2",
      "org.slf4j" % "slf4j-api" % "1.6.1",
      "com.sillycat" %% "push_notifications_api" % "0.1-0-g20d290d",
      "com.lmax" % "disruptor" % "3.2.0",
      "org.javolution" % "javolution-core-java" % "6.0.0"
    ),
    initialCommands in console := """
import com.sillycat.messagequeue.disruptor._
import com.sillycat.messagequeue.rabbitmq._
import com.sillycat.messagequeue.rabbitmq.CampaignPoller._
import com.sillycat.messagequeue.pushy._
import com.sillycat.messagequeue._
import com.sillycat.localpoint.model.DAL
import org.joda.time.{DateTimeZone, DateTime}""",
    initialCommands in consoleQuick := ""
  )

  lazy val messageQueue = Project(id = "message-queue",
    base = file("message-queue")).
    dependsOn(main).
    dependsOn(main % "test->test").
    settings(messageQueueSettings: _*)

  lazy val messageQueueRpm = Project(id = "message-queue-rpm",
    base = messageQueue.base).
    settings(messageQueueSettings ++ Packaging.settings ++ Packaging.server ++ Seq(
      target := file("message-queue/target-rpm"),
      packageSummary := "message queue processor",
      packageDescription := "worker that reads from message queue and sends push notifications",
      publishTo := Packaging.rpmCalcPublishTo("message-queue"),
      libraryDependencies += "com.sillycat" %% "guts" % ourVersion,
      ideaIgnoreModule := true,
      rpmPost := Some(Packaging.rpmCalcPostChown("message-queue"))
    ): _*)

  lazy val profilesSparkSettings: Seq[Setting[_]] = scalariformSettings ++ Seq(
    name := "profiles-spark",
    mainClass := Some("com.sillycat.localpoint.profile.ProfileUpdater"),
    libraryDependencies ++= Seq(
      "org.apache.spark" %% "spark-core" % "0.9.0-incubating",
      "org.hectorclient" % "hector-core" % "1.1-3",
      "org.apache.cassandra" % "cassandra-all" % "1.2.14"
    )
  )

  lazy val profilesSpark = Project(id = "profiles-spark",
    base = file("profiles-spark")).
    dependsOn(main).
    settings(profilesSparkSettings: _*)

  lazy val profilesSparkRpm = Project(id = "profiles-spark-rpm",
    base = profilesSpark.base).
    settings(profilesSparkSettings ++ Packaging.settings ++ Packaging.app ++ Seq(
      target := file("profiles-spark/target-rpm"),
      packageSummary := "profiles spark job",
      packageDescription := "spark job to update profiles in cassandra",
      publishTo := Packaging.rpmCalcPublishTo("profiles-spark"),
      rpmPost := Some("""
hn=`/bin/hostname | /bin/cut -d'.' -f1`
if [ $hn = "cassops" ]; then
  echo "10 0 * * * spark /usr/bin/profiles-spark" > /etc/cron.d/profiles-spark
fi
"""),
      rpmPostun := Some("""
rm -f /etc/cron.d/profiles-spark
"""),
      libraryDependencies += "com.sillycat" %% "guts" % ourVersion,
      ideaIgnoreModule := true
    ): _*)

  lazy val localpointAuthCenterSettings: Seq[Setting[_]] =
    scalariformSettings ++ Revolver.settings ++
    Seq(
      name := "localpoint-auth-center",
      mainClass := Some("com.sillycat.localpoint.authcenter.Boot"),
      scalacOptions := Seq("-unchecked", "-deprecation", "-encoding", "utf8"),
      fork := true
    )

  lazy val localpointAuthCenter = Project(id = "localpoint-auth-center",
    base = file("localpoint-auth-center")).
    dependsOn(main % "test->test;compile->compile").
    dependsOn(util).
    dependsOn(auth).
    settings(localpointAuthCenterSettings: _*)

  lazy val localpointAuthCenterRpm = Project(id = "localpoint-auth-center-rpm",
    base = localpointAuthCenter.base).
    settings(localpointAuthCenterSettings ++ Packaging.settings ++ Packaging.server ++ Seq(
      target := file("localpoint-auth-center/target-rpm"),
      packageSummary := "localpoint auth center",
      packageDescription := "server process for localpoint authentication requests",
      publishTo := Packaging.rpmCalcPublishTo("localpoint-auth-center"),
      libraryDependencies += "com.sillycat" %% "localpoint-auth" % ourVersion,
      ideaIgnoreModule := true,
      rpmPost := Some(Packaging.rpmCalcPostChown("localpoint-auth-center"))
    ): _*)

}

BuildInfo.scala
import sbt._
import java.io.PrintWriter

object BuildInfo {
  /*
   * Generate buld information to be used by the /bldinfo.txt route
   *
   * logo taken from http://www.network-science.de/ascii/ using the "slant" font.
   */
  def write(dir: String, gitHash: String, branch: String, version: String): Unit = {
    val logo = """
          BUILD-DATE : %s
       GIT REV-PARSE : %s
          GIT BRANCH : %s
             VERSION : %s
 """
    try {
      val buildDate = new java.util.Date().toString()
      val writer = new PrintWriter(new File(dir + "/src/main/resources/bldinfo.txt" ))
      writer.write(logo.format(buildDate, gitHash, branch, version))
      writer.close
    } catch {
      case e: Exception => {
        println("Nonfatal build exception thrown creating bldinfo.txt : " + e.getMessage())
        e.printStackTrace()
      }
    }
  }
}

Packaging.scala
import sbt._
import Keys._

object Packaging {
  import com.typesafe.sbt.packager.Keys._
  import com.typesafe.sbt.SbtNativePackager._

  def app = packageArchetype.java_application

  def server = packageArchetype.java_server

  def settings: Seq[Setting[_]] =
    packagerSettings ++
    deploymentSettings ++
    Seq(
      version in Rpm ~= { _.replace("-", "_") },
      rpmVendor in Rpm := “sillycat",
      rpmLicense in Rpm := Some("proprietary"),
      publishArtifact in (Compile, packageBin) := false,
      publishArtifact in (Rpm, packageBin) := true
    )

  /** calculate rpm publish location; default may add stuff like scala version that we dont want */
  def rpmCalcPublishTo(name: String) = Some(
    Resolver.url(“sillycat Artifactory Rpm",
      new URL("http://repository.sillycat.com/artifactory/rpm-repo/6/os/x86_64/Packages/%s/".format(name))
    )(Patterns("%s-[revision].[ext]".format(name))))

  /** because we're lazy about logging and just use a single file, on a reinstall make sure the log file is writeable by the user. */
  def rpmCalcPostChown(name: String) = s"""
chown ${name}:${name} /var/log/${name};
chown -f ${name}:${name} /var/log/${name}/*.log;
"""
}

plugins.sbt
resolvers := Seq()

externalResolvers ++= Seq(
  Resolver.defaultLocal,
  “sillycat Artifactory" at "http://repository.sillycat.com/artifactory/remote-repos"
)

credentials += Credentials("Artifactory Realm", "repository.sillycat.com", "builder", “sillycat2011!")

addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2")

addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")

addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")

addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.4")

//addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.0-RC2")

addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.8.0-M2")

It can build rpm and debian. I will try these later.

References:
http://www.scala-sbt.org/sbt-native-packager/installation.html
http://www.scala-sbt.org/sbt-native-packager/GettingStartedApplications/MyFirstProject.html
https://github.com/sbt/sbt-native-packager

https://github.com/sbt/sbt-native-packager/issues/103

https://github.com/sbt/sbt/issues/1156
http://www.scala-sbt.org/0.12.2/docs/Detailed-Topics/Launcher.html
http://www.scala-sbt.org/0.13/docs/Proxy-Repositories.html

分享到:
评论

相关推荐

    Python for DevOps.pdf

    This practical resource shows you how to use Python for everyday Linux systems administration tasks with today’s most useful DevOps tools, including Docker, Kubernetes, and Terraform.

    集成DevOps思想 基于Centos 7.X打造全方位Linux高级运维架构师 运维开发+自动化运维

    基于Centos 7.X打造全方位Linux高级运维架构师课程,28G百集内容,是一套非常强大的Linux运维课程,后篇还有云计算运维课程,它集成了DevOps思想,或者说叫DevOps方法。 Linux自动化运维课程包括了Linux基础运维...

    DevOps for Web Development.pdf

    DevOps for Web Development.pdf DevOps for Web Development.pdf DevOps for Web Development.pdf DevOps for Web Development.pdf

    DevOps_Roadmap_For_Security

    信息安全如何与devops结合:作者通过常年的devops、信息安全研究,指出了安全如何帮助devops更快的进行发布。

    DevOps_For_Dummies

    4. 敏捷恢复与持续改进:当SAN失败时,CIO并没有选择等待长时间的定制解决方案,而是迅速转向能够快速提供帮助的Tegile Systems。这显示了敏捷恢复的思想,即在出现故障时能够快速恢复服务,并从失败中学习,持续...

    DevOps for Networking epub

    DevOps for Networking 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请在美国亚马逊官网搜索此书

    DevOps.for.Web.Development.2016.10.pdf

    ### DevOps for Web Development #### 知识点一:DevOps 概念及核心原则 - **定义**:DevOps 是一种文化和实践方法,旨在通过自动化软件交付过程和基础设施变更来缩短系统变更从构建到生产的时间,同时保持高质量...

    ansible-for-devops.pdf

    Over the last few years, Ansible has rapidly become one of the most popular IT automation tools in the world. We’ve seen the open source community expand from the beginning of the project in early ...

    DevOps For Dummies.epub

    Develop faster with DevOps DevOps embraces a culture of unifying the ...DevOps For Dummies is essential reading for developers and operations professionals in the early stages of DevOps adoption.

    DevOps for Dummies.pdf

    This book takes a business-centric approach to DevOps. Today’s fast-moving world makes DevOps essential to all enterprises that must be agile and lean enough to respond rapidly to changes such as ...

    DevOps for Networking

    ### DevOps for Networking:深化理解与实践 #### 标题解析 标题“DevOps for Networking”直译为“面向网络的DevOps”,这表明本书旨在介绍如何将DevOps的文化、理念和技术应用于网络管理领域。传统的网络管理和...

    主会场-Toda-DevOps & TPS - For success your Business.zip

    【标题】"主会场-Toda-DevOps & TPS - For success your Business.zip" 提供的资料聚焦于DevOps和TPS(Toyota Production System)两大主题,它们都是现代企业成功的关键因素。DevOps是一种软件开发实践,旨在通过...

    DevOps for Web Development

    《DevOps for Web Development》这本书深入探讨了DevOps在Web开发中的应用,旨在帮助运维开发者提升工作效率和产品质量。DevOps是一种文化和实践,它强调开发人员和运维人员之间的协作,以缩短软件开发周期并提供更...

    azure-functions-devops-build:用于为Azure Functions项目设置和管理Azure DevOps构建的python库

    适用于Azure功能的Azure Devops Build Manager :construction: 该项目目前正在进行中。 请不要在生产中使用,因为我们希望随着时间的推移会有所发展。 :construction: 该项目提供了类AzureDevopsBuildManager和...

    ansible-for-devops, DevOps Ansible的Ansible示例.zip

    ansible-for-devops, DevOps Ansible的Ansible示例 用于DevOps示例的 Ansible 这个存储库包含了Ansible示例,为支持 Ansible的不同部分( 一本关于 Ansible的书),该书由。大多数示例都是完整的VM示例,它使用 ...

    devops for dummies

    devops入门讲解,方便大家在项目管理中学习和使用。 DevOps (a clipped compound of "development" and "operations") is a software development methodology that combines software development (Dev) with ...

Global site tag (gtag.js) - Google Analytics