Skip to content

Commit

Permalink
Merge branch 'bug_26023/technique_compilation_errors_doesn_t_seems_to…
Browse files Browse the repository at this point in the history
…_be_reloaded_when_the_technique_is_deleted_pr' into branches/rudder/8.2
  • Loading branch information
fanf committed Dec 17, 2024
2 parents 17ceaa2 + 3c5e04b commit e0616f1
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import com.normation.cfclerk.services.UpdateTechniqueLibrary
import com.normation.errors.*
import com.normation.errors.IOResult
import com.normation.eventlog.ModificationId
import com.normation.inventory.domain.Version
import com.normation.rudder.domain.logger.ApplicationLogger
import com.normation.rudder.domain.policies.DeleteDirectiveDiff
import com.normation.rudder.domain.policies.Directive
Expand Down Expand Up @@ -79,13 +80,14 @@ trait DeleteEditorTechnique {
}

class DeleteEditorTechniqueImpl(
archiver: TechniqueArchiver,
techLibUpdate: UpdateTechniqueLibrary,
readDirectives: RoDirectiveRepository,
writeDirectives: WoDirectiveRepository,
techniqueRepository: TechniqueRepository,
workflowLevelService: WorkflowLevelService,
baseConfigRepoPath: String // root of config repos
archiver: TechniqueArchiver,
techLibUpdate: UpdateTechniqueLibrary,
readDirectives: RoDirectiveRepository,
writeDirectives: WoDirectiveRepository,
techniqueRepository: TechniqueRepository,
workflowLevelService: WorkflowLevelService,
compilationStatusService: TechniqueCompilationStatusSyncService,
baseConfigRepoPath: String // root of config repos
) extends DeleteEditorTechnique {
// root of technique repository
val techniquesDir: File = File(baseConfigRepoPath) / "techniques"
Expand Down Expand Up @@ -237,6 +239,10 @@ class DeleteEditorTechniqueImpl(
case Some(technique) => removeTechnique(techniqueId, technique)
case None => removeInvalidTechnique(techniquesDir, techniqueId)
}

_ <- compilationStatusService.unsyncOne(
BundleName(techniqueName) -> new Version(techniqueVersion)
) // to delete the status of the technique
} yield ()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import com.normation.rudder.batch.UpdateCompilationStatus
import com.normation.rudder.domain.logger.StatusLoggerPure
import net.liftweb.common.SimpleActor
import zio.*
import zio.syntax.*

sealed trait CompilationResult
object CompilationResult {
Expand Down Expand Up @@ -100,10 +101,13 @@ trait TechniqueCompilationStatusSyncService {
*/
def syncOne(result: EditorTechniqueCompilationResult): IOResult[Unit]

/*
* The whole process that lookup for compilation status and update everything
def unsyncOne(id: (BundleName, Version)): IOResult[Unit]

/**
* The whole process that lookup for compilation status and update everything.
* @param results if none all results are looked up, if some only consider these ones
*/
def getUpdateAndSync(): IOResult[Unit]
def getUpdateAndSync(results: Option[List[EditorTechniqueCompilationResult]] = None): IOResult[Unit]
}

/**
Expand Down Expand Up @@ -158,36 +162,35 @@ class TechniqueCompilationErrorsActorSync(
errorBase: Ref[Map[(BundleName, Version), EditorTechniqueError]]
) extends TechniqueCompilationStatusSyncService {

/*
* Update the internal cache and build a Compilation status
*/
private[ncf] def updateStatus(results: List[EditorTechniqueCompilationResult]): UIO[CompilationStatus] = {
errorBase.updateAndGet { m =>
results.foldLeft(m) {
case (current, EditorTechniqueCompilationResult(id, version, name, CompilationResult.Error(error))) =>
current + ((id, version) -> EditorTechniqueError(id, version, name, error))
case (current, EditorTechniqueCompilationResult(id, version, _, CompilationResult.Success)) =>
current - ((id, version))
}
}.map(m => getStatus(m.values))
}

/*
* Given new editor technique compilation results, update current status and sync it with UI
*/
def syncOne(result: EditorTechniqueCompilationResult): IOResult[Unit] = {
for {
status <- updateStatus(List(result))
status <- updateOneStatus(result)
_ <- syncStatusWithUi(status)
} yield ()
}

/**
* Drop a value from the error base if it exists, sync the status to forget the specified one
*/
def unsyncOne(id: (BundleName, Version)): IOResult[Unit] = {
for {
base <-
errorBase.updateAndGet(_ - id)
status = getStatus(base.values)

_ <- syncStatusWithUi(status)
} yield ()
}

/*
* The whole process that lookup for compilation status and update everything
*/
def getUpdateAndSync(): IOResult[Unit] = {
def getUpdateAndSync(results: Option[List[EditorTechniqueCompilationResult]]): IOResult[Unit] = {
(for {
results <- reader.get()
results <- results.map(_.succeed).getOrElse(reader.get())
status <- updateStatus(results)
_ <- syncStatusWithUi(status)
} yield status).flatMap {
Expand All @@ -214,6 +217,37 @@ class TechniqueCompilationErrorsActorSync(
}
}

/*
* Update the internal cache and build a Compilation status
*/
private[ncf] def updateStatus(results: List[EditorTechniqueCompilationResult]): UIO[CompilationStatus] = {
errorBase.updateAndGet { m =>
results.collect {
case r @ EditorTechniqueCompilationResult(id, version, name, CompilationResult.Error(error)) =>
(getKey(r) -> EditorTechniqueError(id, version, name, error))
}.toMap
}.map(m => getStatus(m.values))
}

/**
* Only take a single result to update the cached technique if it is there, else do nothing
*/
private[ncf] def updateOneStatus(result: EditorTechniqueCompilationResult): UIO[CompilationStatus] = {
// only replace when current one is an error, when present or absent we should set the value
val replacement: Option[EditorTechniqueError] => Option[EditorTechniqueError] = result match {
case EditorTechniqueCompilationResult(id, version, name, CompilationResult.Error(error)) =>
_ => Some(EditorTechniqueError(id, version, name, error))
case _ =>
_ => None
}
errorBase
.updateAndGet(_.updatedWith(getKey(result))(replacement(_)))
.map(m => getStatus(m.values))
}

private def getKey(result: EditorTechniqueCompilationResult): (BundleName, Version) = {
result.id -> result.version
}
}

object TechniqueCompilationErrorsActorSync {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ trait TechniqueWriter {
modId: ModificationId,
committer: EventActor
): IOResult[EditorTechnique]

def writeTechniques(
techniques: List[EditorTechnique],
modId: ModificationId,
committer: EventActor
): IOResult[List[EditorTechnique]]
}

/**
Expand All @@ -106,16 +112,20 @@ class TechniqueWriterImpl(
deleteDirective: Boolean,
modId: ModificationId,
committer: QueryContext
): IOResult[Unit] = deleteService.deleteTechnique(techniqueName, techniqueVersion, deleteDirective, modId, committer)
): IOResult[Unit] = {
deleteService.deleteTechnique(techniqueName, techniqueVersion, deleteDirective, modId, committer)
}

def writeTechniqueAndUpdateLib(
technique: EditorTechnique,
modId: ModificationId,
committer: EventActor
): IOResult[EditorTechnique] = {
for {
updatedTechnique <- compileArchiveTechnique(technique, modId, committer)
libUpdate <-
updated <-
compileArchiveTechnique(technique, modId, committer, syncStatus = false) // sync is already0done in library update
(updatedTechnique, _) = updated
libUpdate <-
techLibUpdate
.update(modId, committer, Some(s"Update Technique library after creating files for ncf Technique ${technique.name}"))
.toIO
Expand All @@ -130,17 +140,32 @@ class TechniqueWriterImpl(
modId: ModificationId,
committer: EventActor
): IOResult[EditorTechnique] = {
compileArchiveTechnique(technique, modId, committer)
compileArchiveTechnique(technique, modId, committer).map { case (t, _) => t }
}

override def writeTechniques(
techniques: List[EditorTechnique],
modId: ModificationId,
committer: EventActor
): IOResult[List[EditorTechnique]] = {
for {
updated <- ZIO.foreach(techniques)(compileArchiveTechnique(_, modId, committer, syncStatus = false))
(updatedTechniques, results) = updated.unzip
_ <- compilationStatusService.getUpdateAndSync(Some(results))
} yield {
updatedTechniques
}
}

///// utility methods /////

// Write and commit all techniques files
private def compileArchiveTechnique(
technique: EditorTechnique,
modId: ModificationId,
committer: EventActor
): IOResult[EditorTechnique] = {
technique: EditorTechnique,
modId: ModificationId,
committer: EventActor,
syncStatus: Boolean = true // should update the compilation status ?
): IOResult[(EditorTechnique, EditorTechniqueCompilationResult)] = {
for {
time_0 <- currentTimeMillis
_ <- TechniqueWriterLoggerPure.debug(s"Writing technique '${technique.name}'")
Expand All @@ -150,33 +175,34 @@ class TechniqueWriterImpl(
}
techniqueWithResourceUpdated = technique.copy(resources = updateResources)

_ <- TechniqueWriterImpl.writeYaml(techniqueWithResourceUpdated)(baseConfigRepoPath)
time_1 <- currentTimeMillis
_ <-
_ <- TechniqueWriterImpl.writeYaml(techniqueWithResourceUpdated)(baseConfigRepoPath)
time_1 <- currentTimeMillis
_ <-
TimingDebugLoggerPure.trace(s"writeTechnique: writing yaml for technique '${technique.name}' took ${time_1 - time_0}ms")
compiled <- compiler.compileTechnique(techniqueWithResourceUpdated)
_ <- compilationStatusService.syncOne(EditorTechniqueCompilationResult.from(techniqueWithResourceUpdated, compiled))
time_3 <- currentTimeMillis
id <- TechniqueVersion.parse(technique.version.value).toIO.map(v => TechniqueId(TechniqueName(technique.id.value), v))
compiled <- compiler.compileTechnique(techniqueWithResourceUpdated)
compilationResult = EditorTechniqueCompilationResult.from(techniqueWithResourceUpdated, compiled)
_ <- compilationStatusService.syncOne(compilationResult)
time_3 <- currentTimeMillis
id <- TechniqueVersion.parse(technique.version.value).toIO.map(v => TechniqueId(TechniqueName(technique.id.value), v))
// resources files are missing the the "resources/" prefix
resources = technique.resources.map(r => ResourceFile("resources/" + r.path, r.state))
_ <- archiver.saveTechnique(
id,
technique.category.split('/').toIndexedSeq,
Chunk.fromIterable(resources),
modId,
committer,
s"Committing technique ${technique.name}"
)
time_4 <- currentTimeMillis
_ <- TimingDebugLoggerPure.trace(s"writeTechnique: committing technique '${technique.name}' took ${time_4 - time_3}ms")
_ <- TimingDebugLoggerPure.debug(s"writeTechnique: writing technique '${technique.name}' took ${time_4 - time_0}ms")
time_5 <- currentTimeMillis
_ <-
resources = technique.resources.map(r => ResourceFile("resources/" + r.path, r.state))
_ <- archiver.saveTechnique(
id,
technique.category.split('/').toIndexedSeq,
Chunk.fromIterable(resources),
modId,
committer,
s"Committing technique ${technique.name}"
)
time_4 <- currentTimeMillis
_ <- TimingDebugLoggerPure.trace(s"writeTechnique: committing technique '${technique.name}' took ${time_4 - time_3}ms")
_ <- TimingDebugLoggerPure.debug(s"writeTechnique: writing technique '${technique.name}' took ${time_4 - time_0}ms")
time_5 <- currentTimeMillis
_ <-
TimingDebugLoggerPure.trace(s"writeTechnique: writing technique '${technique.name}' in cache took ${time_5 - time_4}ms")

} yield {
techniqueWithResourceUpdated
(techniqueWithResourceUpdated, compilationResult)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import com.normation.eventlog.ModificationId
import com.normation.rudder.batch.AsyncDeploymentActor
import com.normation.rudder.batch.AutomaticStartDeployment
import com.normation.rudder.domain.eventlog.ReloadTechniqueLibrary
import com.normation.rudder.ncf.TechniqueCompilationStatusSyncService
import com.normation.rudder.repository.EventLogRepository
import net.liftweb.common.*

Expand Down Expand Up @@ -105,3 +106,20 @@ class LogEventOnTechniqueReloadCallback(
.toBox
}
}

class SyncCompilationStatusOnTechniqueCallback(
override val name: String,
override val order: Int,
techniqueCompilationStatusService: TechniqueCompilationStatusSyncService
) extends TechniquesLibraryUpdateNotification with Loggable {
override def updatedTechniques(
gitRev: String,
techniqueIds: Map[TechniqueName, TechniquesLibraryUpdateType],
updatedCategories: Set[TechniqueCategoryModType],
modId: ModificationId,
actor: EventActor,
reason: Option[String]
): Box[Unit] = {
techniqueCompilationStatusService.getUpdateAndSync().toBox
}
}
Loading

0 comments on commit e0616f1

Please sign in to comment.