aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libpod/container.go2
-rw-r--r--libpod/container_internal_linux.go11
-rw-r--r--libpod/container_log_linux.go14
-rw-r--r--libpod/network/cni/cni_conversion.go15
-rw-r--r--libpod/network/cni/cni_types.go15
-rw-r--r--libpod/network/cni/config_test.go13
-rw-r--r--libpod/network/cni/network.go7
-rw-r--r--libpod/networking_linux.go62
-rw-r--r--libpod/networking_machine.go121
-rw-r--r--libpod/networking_slirp4netns.go4
-rw-r--r--pkg/machine/qemu/machine.go5
-rw-r--r--pkg/specgen/generate/container_create.go1
-rw-r--r--pkg/specgen/specgen.go1
-rw-r--r--pkg/specgenutil/specgen.go5
-rw-r--r--test/e2e/run_test.go48
-rw-r--r--test/system/035-logs.bats21
16 files changed, 268 insertions, 77 deletions
diff --git a/libpod/container.go b/libpod/container.go
index 86989a02f..c38acb513 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -259,6 +259,8 @@ type ContainerSecret struct {
GID uint32
// Mode is the mode of the secret file
Mode uint32
+ // Secret target inside container
+ Target string
}
// ContainerNetworkDescriptions describes the relationship between the CNI
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index fbe8d8e7e..85b1e9139 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1876,8 +1876,17 @@ rootless=%d
return errors.Wrapf(err, "error creating secrets mount")
}
for _, secret := range c.Secrets() {
+ secretFileName := secret.Name
+ base := "/run/secrets"
+ if secret.Target != "" {
+ secretFileName = secret.Target
+ //If absolute path for target given remove base.
+ if filepath.IsAbs(secretFileName) {
+ base = ""
+ }
+ }
src := filepath.Join(c.config.SecretsPath, secret.Name)
- dest := filepath.Join("/run/secrets", secret.Name)
+ dest := filepath.Join(base, secretFileName)
c.state.BindMounts[dest] = src
}
}
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index 324aa3b98..d3d7c8397 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -37,9 +37,11 @@ func (c *Container) initializeJournal(ctx context.Context) error {
m := make(map[string]string)
m["SYSLOG_IDENTIFIER"] = "podman"
m["PODMAN_ID"] = c.ID()
- m["CONTAINER_ID_FULL"] = c.ID()
history := events.History
m["PODMAN_EVENT"] = history.String()
+ container := events.Container
+ m["PODMAN_TYPE"] = container.String()
+ m["PODMAN_TIME"] = time.Now().Format(time.RFC3339Nano)
return journal.Send("", journal.PriInfo, m)
}
@@ -95,6 +97,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
// exponential backoff.
var cursor string
var cursorError error
+ var containerCouldBeLogging bool
for i := 1; i <= 3; i++ {
cursor, cursorError = journal.GetCursor()
hundreds := 1
@@ -172,7 +175,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
doTailFunc()
}
// Unless we follow, quit.
- if !options.Follow {
+ if !options.Follow || !containerCouldBeLogging {
return
}
// Sleep until something's happening on the journal.
@@ -201,11 +204,14 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
logrus.Errorf("Failed to translate event: %v", err)
return
}
- if status == events.Exited {
+ switch status {
+ case events.History, events.Init, events.Start, events.Restart:
+ containerCouldBeLogging = true
+ case events.Exited:
+ containerCouldBeLogging = false
if doTail {
doTailFunc()
}
- return
}
continue
}
diff --git a/libpod/network/cni/cni_conversion.go b/libpod/network/cni/cni_conversion.go
index 70d259b60..788165b5e 100644
--- a/libpod/network/cni/cni_conversion.go
+++ b/libpod/network/cni/cni_conversion.go
@@ -295,10 +295,6 @@ func (n *cniNetwork) createCNIConfigListFromNetwork(network *types.Network, writ
// Note: in the future we might like to allow for dynamic domain names
plugins = append(plugins, newDNSNamePlugin(defaultPodmanDomainName))
}
- // Add the podman-machine CNI plugin if we are in a machine
- if n.isMachine {
- plugins = append(plugins, newPodmanMachinePlugin())
- }
case types.MacVLANNetworkDriver:
plugins = append(plugins, newVLANPlugin(types.MacVLANNetworkDriver, network.NetworkInterface, vlanPluginMode, mtu, ipamConf))
@@ -369,3 +365,14 @@ func convertSpecgenPortsToCNIPorts(ports []types.PortMapping) ([]cniPortMapEntry
}
return cniPorts, nil
}
+
+func removeMachinePlugin(conf *libcni.NetworkConfigList) *libcni.NetworkConfigList {
+ plugins := make([]*libcni.NetworkConfig, 0, len(conf.Plugins))
+ for _, net := range conf.Plugins {
+ if net.Network.Type != "podman-machine" {
+ plugins = append(plugins, net)
+ }
+ }
+ conf.Plugins = plugins
+ return conf
+}
diff --git a/libpod/network/cni/cni_types.go b/libpod/network/cni/cni_types.go
index c70cb92b6..e5eb777de 100644
--- a/libpod/network/cni/cni_types.go
+++ b/libpod/network/cni/cni_types.go
@@ -110,12 +110,6 @@ type dnsNameConfig struct {
Capabilities map[string]bool `json:"capabilities"`
}
-// podmanMachineConfig enables port handling on the host OS
-type podmanMachineConfig struct {
- PluginType string `json:"type"`
- Capabilities map[string]bool `json:"capabilities"`
-}
-
// ncList describes a generic map
type ncList map[string]interface{}
@@ -285,12 +279,3 @@ func newVLANPlugin(pluginType, device, mode string, mtu int, ipam ipamConfig) VL
}
return m
}
-
-func newPodmanMachinePlugin() podmanMachineConfig {
- caps := make(map[string]bool, 1)
- caps["portMappings"] = true
- return podmanMachineConfig{
- PluginType: "podman-machine",
- Capabilities: caps,
- }
-}
diff --git a/libpod/network/cni/config_test.go b/libpod/network/cni/config_test.go
index 0dfc6173c..c2e5fc985 100644
--- a/libpod/network/cni/config_test.go
+++ b/libpod/network/cni/config_test.go
@@ -965,19 +965,6 @@ var _ = Describe("Config", func() {
Expect(logString).To(ContainSubstring("dnsname and internal networks are incompatible"))
})
- It("create config with podman machine plugin", func() {
- libpodNet, err := getNetworkInterface(cniConfDir, true)
- Expect(err).To(BeNil())
-
- network := types.Network{}
- network1, err := libpodNet.NetworkCreate(network)
- Expect(err).To(BeNil())
- Expect(network1.Driver).To(Equal("bridge"))
- path := filepath.Join(cniConfDir, network1.Name+".conflist")
- Expect(path).To(BeARegularFile())
- grepInFile(path, `"type": "podman-machine",`)
- })
-
It("network inspect partial ID", func() {
network := types.Network{Name: "net4"}
network1, err := libpodNet.NetworkCreate(network)
diff --git a/libpod/network/cni/network.go b/libpod/network/cni/network.go
index 3e9cdaa47..41e3e414e 100644
--- a/libpod/network/cni/network.go
+++ b/libpod/network/cni/network.go
@@ -150,6 +150,13 @@ func (n *cniNetwork) loadNetworks() error {
continue
}
+ // podman < v4.0 used the podman-machine cni plugin for podman machine port forwarding
+ // since this is now build into podman we no longer use the plugin
+ // old configs may still contain it so we just remove it here
+ if n.isMachine {
+ conf = removeMachinePlugin(conf)
+ }
+
if _, err := n.cniConf.ValidateNetworkList(context.Background(), conf); err != nil {
logrus.Warnf("Error validating CNI config file %s: %v", file, err)
continue
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index fc91155fa..8ce435efd 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -87,12 +87,28 @@ func (c *Container) GetNetworkAliases(netName string) ([]string, error) {
return aliases, nil
}
+// convertPortMappings will remove the HostIP part from the ports when running inside podman machine.
+// This is need because a HostIP of 127.0.0.1 would now allow the gvproxy forwarder to reach to open ports.
+// For machine the HostIP must only be used by gvproxy and never in the VM.
+func (c *Container) convertPortMappings() []types.PortMapping {
+ if !c.runtime.config.Engine.MachineEnabled || len(c.config.PortMappings) == 0 {
+ return c.config.PortMappings
+ }
+ // if we run in a machine VM we have to ignore the host IP part
+ newPorts := make([]types.PortMapping, 0, len(c.config.PortMappings))
+ for _, port := range c.config.PortMappings {
+ port.HostIP = ""
+ newPorts = append(newPorts, port)
+ }
+ return newPorts
+}
+
func (c *Container) getNetworkOptions() (types.NetworkOptions, error) {
opts := types.NetworkOptions{
ContainerID: c.config.ID,
ContainerName: getCNIPodName(c),
}
- opts.PortMappings = c.config.PortMappings
+ opts.PortMappings = c.convertPortMappings()
networks, _, err := c.networks()
if err != nil {
return opts, err
@@ -591,32 +607,9 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
return rootlessNetNS, nil
}
-// setPrimaryMachineIP is used for podman-machine and it sets
-// and environment variable with the IP address of the podman-machine
-// host.
-func setPrimaryMachineIP() error {
- // no connection is actually made here
- conn, err := net.Dial("udp", "8.8.8.8:80")
- if err != nil {
- return err
- }
- defer func() {
- if err := conn.Close(); err != nil {
- logrus.Error(err)
- }
- }()
- addr := conn.LocalAddr().(*net.UDPAddr)
- return os.Setenv("PODMAN_MACHINE_HOST", addr.IP.String())
-}
-
// setUpNetwork will set up the the networks, on error it will also tear down the cni
// networks. If rootless it will join/create the rootless network namespace.
func (r *Runtime) setUpNetwork(ns string, opts types.NetworkOptions) (map[string]types.StatusBlock, error) {
- if r.config.MachineEnabled() {
- if err := setPrimaryMachineIP(); err != nil {
- return nil, err
- }
- }
rootlessNetNS, err := r.GetRootlessNetNs(true)
if err != nil {
return nil, err
@@ -650,7 +643,18 @@ func getCNIPodName(c *Container) string {
}
// Create and configure a new network namespace for a container
-func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (map[string]types.StatusBlock, error) {
+func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[string]types.StatusBlock, rerr error) {
+ if err := r.exposeMachinePorts(ctr.config.PortMappings); err != nil {
+ return nil, err
+ }
+ defer func() {
+ // make sure to unexpose the gvproxy ports when an error happens
+ if rerr != nil {
+ if err := r.unexposeMachinePorts(ctr.config.PortMappings); err != nil {
+ logrus.Errorf("failed to free gvproxy machine ports: %v", err)
+ }
+ }
+ }()
if ctr.config.NetMode.IsSlirp4netns() {
return nil, r.setupSlirp4netns(ctr, ctrNS)
}
@@ -836,6 +840,10 @@ func (r *Runtime) teardownCNI(ctr *Container) error {
// Tear down a network namespace, undoing all state associated with it.
func (r *Runtime) teardownNetNS(ctr *Container) error {
+ if err := r.unexposeMachinePorts(ctr.config.PortMappings); err != nil {
+ // do not return an error otherwise we would prevent network cleanup
+ logrus.Errorf("failed to free gvproxy machine ports: %v", err)
+ }
if err := r.teardownCNI(ctr); err != nil {
return err
}
@@ -1206,7 +1214,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
ContainerID: c.config.ID,
ContainerName: getCNIPodName(c),
}
- opts.PortMappings = c.config.PortMappings
+ opts.PortMappings = c.convertPortMappings()
eth, exists := c.state.NetInterfaceDescriptions.getInterfaceByName(netName)
if !exists {
return errors.Errorf("no network interface name for container %s on network %s", c.config.ID, netName)
@@ -1298,7 +1306,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
ContainerID: c.config.ID,
ContainerName: getCNIPodName(c),
}
- opts.PortMappings = c.config.PortMappings
+ opts.PortMappings = c.convertPortMappings()
eth, exists := c.state.NetInterfaceDescriptions.getInterfaceByName(netName)
if !exists {
return errors.Errorf("no network interface name for container %s on network %s", c.config.ID, netName)
diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go
new file mode 100644
index 000000000..7cb2a00f7
--- /dev/null
+++ b/libpod/networking_machine.go
@@ -0,0 +1,121 @@
+package libpod
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net"
+ "net/http"
+ "strconv"
+ "strings"
+
+ "github.com/containers/podman/v3/libpod/network/types"
+ "github.com/sirupsen/logrus"
+)
+
+const machineGvproxyEndpoint = "gateway.containers.internal"
+
+// machineExpose is the struct for the gvproxy port forwarding api send via json
+type machineExpose struct {
+ // Local is the local address on the vm host, format is ip:port
+ Local string `json:"local"`
+ // Remote is used to specify the vm ip:port
+ Remote string `json:"remote,omitempty"`
+ // Protocol to forward, tcp or udp
+ Protocol string `json:"protocol"`
+}
+
+func requestMachinePorts(expose bool, ports []types.PortMapping) error {
+ url := "http://" + machineGvproxyEndpoint + "/services/forwarder/"
+ if expose {
+ url = url + "expose"
+ } else {
+ url = url + "unexpose"
+ }
+ ctx := context.Background()
+ client := &http.Client{}
+ buf := new(bytes.Buffer)
+ for num, port := range ports {
+ protocols := strings.Split(port.Protocol, ",")
+ for _, protocol := range protocols {
+ for i := uint16(0); i < port.Range; i++ {
+ machinePort := machineExpose{
+ Local: net.JoinHostPort(port.HostIP, strconv.FormatInt(int64(port.HostPort+i), 10)),
+ Protocol: protocol,
+ }
+ if expose {
+ // only set the remote port the ip will be automatically be set by gvproxy
+ machinePort.Remote = ":" + strconv.FormatInt(int64(port.HostPort+i), 10)
+ }
+
+ // post request
+ if err := json.NewEncoder(buf).Encode(machinePort); err != nil {
+ if expose {
+ // in case of an error make sure to unexpose the other ports
+ if cerr := requestMachinePorts(false, ports[:num]); cerr != nil {
+ logrus.Errorf("failed to free gvproxy machine ports: %v", cerr)
+ }
+ }
+ return err
+ }
+ if err := makeMachineRequest(ctx, client, url, buf); err != nil {
+ if expose {
+ // in case of an error make sure to unexpose the other ports
+ if cerr := requestMachinePorts(false, ports[:num]); cerr != nil {
+ logrus.Errorf("failed to free gvproxy machine ports: %v", cerr)
+ }
+ }
+ return err
+ }
+ buf.Reset()
+ }
+ }
+ }
+ return nil
+}
+
+func makeMachineRequest(ctx context.Context, client *http.Client, url string, buf io.Reader) error {
+ //var buf io.ReadWriter
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, buf)
+ if err != nil {
+ return err
+ }
+ req.Header.Add("Accept", "application/json")
+ req.Header.Add("Content-Type", "application/json")
+ resp, err := client.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return annotateGvproxyResponseError(resp.Body)
+ }
+ return nil
+}
+
+func annotateGvproxyResponseError(r io.Reader) error {
+ b, err := ioutil.ReadAll(r)
+ if err == nil && len(b) > 0 {
+ return fmt.Errorf("something went wrong with the request: %q", string(b))
+ }
+ return errors.New("something went wrong with the request, could not read response")
+}
+
+// exposeMachinePorts exposes the ports for podman machine via gvproxy
+func (r *Runtime) exposeMachinePorts(ports []types.PortMapping) error {
+ if !r.config.Engine.MachineEnabled {
+ return nil
+ }
+ return requestMachinePorts(true, ports)
+}
+
+// unexposeMachinePorts closes the ports for podman machine via gvproxy
+func (r *Runtime) unexposeMachinePorts(ports []types.PortMapping) error {
+ if !r.config.Engine.MachineEnabled {
+ return nil
+ }
+ return requestMachinePorts(false, ports)
+}
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 674075e23..67ea31c1c 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -509,7 +509,7 @@ func (r *Runtime) setupRootlessPortMappingViaRLK(ctr *Container, netnsPath strin
childIP := getRootlessPortChildIP(ctr, netStatus)
cfg := rootlessport.Config{
- Mappings: ctr.config.PortMappings,
+ Mappings: ctr.convertPortMappings(),
NetNSPath: netnsPath,
ExitFD: 3,
ReadyFD: 4,
@@ -594,7 +594,7 @@ func (r *Runtime) setupRootlessPortMappingViaSlirp(ctr *Container, cmd *exec.Cmd
// for each port we want to add we need to open a connection to the slirp4netns control socket
// and send the add_hostfwd command.
- for _, i := range ctr.config.PortMappings {
+ for _, i := range ctr.convertPortMappings() {
conn, err := net.Dial("unix", apiSocket)
if err != nil {
return errors.Wrapf(err, "cannot open connection to %s", apiSocket)
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index a7174aac3..57c32bf74 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -664,9 +664,6 @@ func (v *MachineVM) startHostNetworking() error {
return err
}
- // Listen on all at port 7777 for setting up and tearing
- // down forwarding
- listenSocket := "tcp://0.0.0.0:7777"
qemuSocket, pidFile, err := v.getSocketandPid()
if err != nil {
return err
@@ -676,7 +673,7 @@ func (v *MachineVM) startHostNetworking() error {
files := []*os.File{os.Stdin, os.Stdout, os.Stderr}
attr.Files = files
cmd := []string{binary}
- cmd = append(cmd, []string{"-listen", listenSocket, "-listen-qemu", fmt.Sprintf("unix://%s", qemuSocket), "-pid-file", pidFile}...)
+ cmd = append(cmd, []string{"-listen-qemu", fmt.Sprintf("unix://%s", qemuSocket), "-pid-file", pidFile}...)
// Add the ssh port
cmd = append(cmd, []string{"-ssh-port", fmt.Sprintf("%d", v.Port)}...)
if logrus.GetLevel() == logrus.DebugLevel {
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index f3dc28b01..f90fef9e8 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -474,6 +474,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
UID: s.UID,
GID: s.GID,
Mode: s.Mode,
+ Target: s.Target,
})
}
options = append(options, libpod.WithSecrets(secrs))
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index cde456ad0..0e257ad4c 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -547,6 +547,7 @@ func (s *SpecGenerator) GetImage() (*libimage.Image, string) {
type Secret struct {
Source string
+ Target string
UID uint32
GID uint32
Mode uint32
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index aa59b0a8d..c110b9e97 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -876,6 +876,7 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
if len(split) == 1 {
mountSecret := specgen.Secret{
Source: val,
+ Target: target,
UID: uid,
GID: gid,
Mode: mode,
@@ -941,11 +942,9 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
return nil, nil, errors.Wrapf(secretParseError, "no source found %s", val)
}
if secretType == "mount" {
- if target != "" {
- return nil, nil, errors.Wrapf(secretParseError, "target option is invalid for mounted secrets")
- }
mountSecret := specgen.Secret{
Source: source,
+ Target: target,
UID: uid,
GID: gid,
Mode: mode,
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index ed2d8938d..d6d729d3a 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -1723,6 +1723,50 @@ WORKDIR /madethis`, BB)
})
+ It("podman run --secret source=mysecret,type=mount with target", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret_target", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target,type=mount,target=hello", "--name", "secr_target", ALPINE, "cat", "/run/secrets/hello"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(Equal(secretsString))
+
+ session = podmanTest.Podman([]string{"inspect", "secr_target", "--format", " {{(index .Config.Secrets 0).Name}}"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("mysecret_target"))
+
+ })
+
+ It("podman run --secret source=mysecret,type=mount with target at /tmp", func() {
+ secretsString := "somesecretdata"
+ secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
+ err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
+ Expect(err).To(BeNil())
+
+ session := podmanTest.Podman([]string{"secret", "create", "mysecret_target2", secretFilePath})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target2,type=mount,target=/tmp/hello", "--name", "secr_target2", ALPINE, "cat", "/tmp/hello"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(Equal(secretsString))
+
+ session = podmanTest.Podman([]string{"inspect", "secr_target2", "--format", " {{(index .Config.Secrets 0).Name}}"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("mysecret_target2"))
+
+ })
+
It("podman run --secret source=mysecret,type=env", func() {
secretsString := "somesecretdata"
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
@@ -1748,10 +1792,6 @@ WORKDIR /madethis`, BB)
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- // target with mount type should fail
- session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,target=anotherplace", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
- session.WaitWithDefaultTimeout()
- Expect(session).To(ExitWithError())
session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,target=anotherplace", "--name", "secr", ALPINE, "printenv", "anotherplace"})
session.WaitWithDefaultTimeout()
diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats
index 7fb3e62e4..44984eaad 100644
--- a/test/system/035-logs.bats
+++ b/test/system/035-logs.bats
@@ -89,6 +89,27 @@ ${cid[0]} d" "Sequential output from logs"
_log_test_multi journald
}
+function _log_test_restarted() {
+ run_podman run --log-driver=$1 --name logtest $IMAGE sh -c 'start=0; if test -s log; then start=`tail -n 1 log`; fi; seq `expr $start + 1` `expr $start + 10` | tee -a log'
+ run_podman start -a logtest
+ logfile=$(mktemp -p ${PODMAN_TMPDIR} logfileXXXXXXXX)
+ $PODMAN $_PODMAN_TEST_OPTS logs -f logtest > $logfile
+ expected=$(mktemp -p ${PODMAN_TMPDIR} expectedXXXXXXXX)
+ seq 1 20 > $expected
+ diff -u ${expected} ${logfile}
+}
+
+@test "podman logs restarted - k8s-file" {
+ _log_test_restarted k8s-file
+}
+
+@test "podman logs restarted journald" {
+ # We can't use journald on RHEL as rootless: rhbz#1895105
+ skip_if_journald_unavailable
+
+ _log_test_restarted journald
+}
+
@test "podman logs - journald log driver requires journald events backend" {
skip_if_remote "remote does not support --events-backend"
# We can't use journald on RHEL as rootless: rhbz#1895105